mirror of https://gitee.com/openkylin/linux.git
EDAC, mc: Fix locking around mc_devices list
When accessing the mc_devices list of memory controller descriptors, we need to hold mem_ctls_mutex. This was not always the case, fix that. Make all external callers call a version which grabs the mutex since the last is local to edac_mc.c. Reported-by: Yazen Ghannam <yazen.ghannam@amd.com> Signed-off-by: Borislav Petkov <bp@suse.de>
This commit is contained in:
parent
90e493d7d5
commit
c73e8833be
|
@ -482,15 +482,8 @@ void edac_mc_free(struct mem_ctl_info *mci)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(edac_mc_free);
|
EXPORT_SYMBOL_GPL(edac_mc_free);
|
||||||
|
|
||||||
|
/* Caller must hold mem_ctls_mutex */
|
||||||
/**
|
static struct mem_ctl_info *__find_mci_by_dev(struct device *dev)
|
||||||
* find_mci_by_dev
|
|
||||||
*
|
|
||||||
* scan list of controllers looking for the one that manages
|
|
||||||
* the 'dev' device
|
|
||||||
* @dev: pointer to a struct device related with the MCI
|
|
||||||
*/
|
|
||||||
struct mem_ctl_info *find_mci_by_dev(struct device *dev)
|
|
||||||
{
|
{
|
||||||
struct mem_ctl_info *mci;
|
struct mem_ctl_info *mci;
|
||||||
struct list_head *item;
|
struct list_head *item;
|
||||||
|
@ -506,6 +499,24 @@ struct mem_ctl_info *find_mci_by_dev(struct device *dev)
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find_mci_by_dev
|
||||||
|
*
|
||||||
|
* scan list of controllers looking for the one that manages
|
||||||
|
* the 'dev' device
|
||||||
|
* @dev: pointer to a struct device related with the MCI
|
||||||
|
*/
|
||||||
|
struct mem_ctl_info *find_mci_by_dev(struct device *dev)
|
||||||
|
{
|
||||||
|
struct mem_ctl_info *ret;
|
||||||
|
|
||||||
|
mutex_lock(&mem_ctls_mutex);
|
||||||
|
ret = __find_mci_by_dev(dev);
|
||||||
|
mutex_unlock(&mem_ctls_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
EXPORT_SYMBOL_GPL(find_mci_by_dev);
|
EXPORT_SYMBOL_GPL(find_mci_by_dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -588,7 +599,7 @@ static int add_mc_to_global_list(struct mem_ctl_info *mci)
|
||||||
|
|
||||||
insert_before = &mc_devices;
|
insert_before = &mc_devices;
|
||||||
|
|
||||||
p = find_mci_by_dev(mci->pdev);
|
p = __find_mci_by_dev(mci->pdev);
|
||||||
if (unlikely(p != NULL))
|
if (unlikely(p != NULL))
|
||||||
goto fail0;
|
goto fail0;
|
||||||
|
|
||||||
|
@ -640,26 +651,28 @@ static int del_mc_from_global_list(struct mem_ctl_info *mci)
|
||||||
*
|
*
|
||||||
* If found, return a pointer to the structure.
|
* If found, return a pointer to the structure.
|
||||||
* Else return NULL.
|
* Else return NULL.
|
||||||
*
|
|
||||||
* Caller must hold mem_ctls_mutex.
|
|
||||||
*/
|
*/
|
||||||
struct mem_ctl_info *edac_mc_find(int idx)
|
struct mem_ctl_info *edac_mc_find(int idx)
|
||||||
{
|
{
|
||||||
|
struct mem_ctl_info *mci = NULL;
|
||||||
struct list_head *item;
|
struct list_head *item;
|
||||||
struct mem_ctl_info *mci;
|
|
||||||
|
mutex_lock(&mem_ctls_mutex);
|
||||||
|
|
||||||
list_for_each(item, &mc_devices) {
|
list_for_each(item, &mc_devices) {
|
||||||
mci = list_entry(item, struct mem_ctl_info, link);
|
mci = list_entry(item, struct mem_ctl_info, link);
|
||||||
|
|
||||||
if (mci->mc_idx >= idx) {
|
if (mci->mc_idx >= idx) {
|
||||||
if (mci->mc_idx == idx)
|
if (mci->mc_idx == idx) {
|
||||||
return mci;
|
goto unlock;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
unlock:
|
||||||
|
mutex_unlock(&mem_ctls_mutex);
|
||||||
|
return mci;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(edac_mc_find);
|
EXPORT_SYMBOL(edac_mc_find);
|
||||||
|
|
||||||
|
@ -779,7 +792,7 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev)
|
||||||
mutex_lock(&mem_ctls_mutex);
|
mutex_lock(&mem_ctls_mutex);
|
||||||
|
|
||||||
/* find the requested mci struct in the global list */
|
/* find the requested mci struct in the global list */
|
||||||
mci = find_mci_by_dev(dev);
|
mci = __find_mci_by_dev(dev);
|
||||||
if (mci == NULL) {
|
if (mci == NULL) {
|
||||||
mutex_unlock(&mem_ctls_mutex);
|
mutex_unlock(&mem_ctls_mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in New Issue