提交 939747bd 编写于 作者: M Mauro Carvalho Chehab

i7core_edac: Be sure that the edac pci handler will be properly released

With multi-sockets, more than one edac pci handler is enabled. Be sure to
un-register all instances.
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 f6f94e2a
...@@ -810,6 +810,7 @@ extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, ...@@ -810,6 +810,7 @@ extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
extern int edac_mc_add_mc(struct mem_ctl_info *mci); extern int edac_mc_add_mc(struct mem_ctl_info *mci);
extern void edac_mc_free(struct mem_ctl_info *mci); extern void edac_mc_free(struct mem_ctl_info *mci);
extern struct mem_ctl_info *edac_mc_find(int idx); extern struct mem_ctl_info *edac_mc_find(int idx);
extern struct mem_ctl_info *find_mci_by_dev(struct device *dev);
extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev); extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev);
extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
unsigned long page); unsigned long page);
......
...@@ -239,13 +239,14 @@ void edac_mc_free(struct mem_ctl_info *mci) ...@@ -239,13 +239,14 @@ void edac_mc_free(struct mem_ctl_info *mci)
EXPORT_SYMBOL_GPL(edac_mc_free); EXPORT_SYMBOL_GPL(edac_mc_free);
/* /**
* find_mci_by_dev * find_mci_by_dev
* *
* scan list of controllers looking for the one that manages * scan list of controllers looking for the one that manages
* the 'dev' device * the 'dev' device
* @dev: pointer to a struct device related with the MCI
*/ */
static struct mem_ctl_info *find_mci_by_dev(struct device *dev) 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;
...@@ -261,6 +262,7 @@ static struct mem_ctl_info *find_mci_by_dev(struct device *dev) ...@@ -261,6 +262,7 @@ static struct mem_ctl_info *find_mci_by_dev(struct device *dev)
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(find_mci_by_dev);
/* /*
* handler for EDAC to check if NMI type handler has asserted interrupt * handler for EDAC to check if NMI type handler has asserted interrupt
......
...@@ -261,6 +261,9 @@ struct i7core_pvt { ...@@ -261,6 +261,9 @@ struct i7core_pvt {
/* Count indicator to show errors not got */ /* Count indicator to show errors not got */
unsigned mce_overrun; unsigned mce_overrun;
/* Struct to control EDAC polling */
struct edac_pci_ctl_info *i7core_pci;
}; };
/* Static vars */ /* Static vars */
...@@ -378,8 +381,6 @@ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { ...@@ -378,8 +381,6 @@ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = {
{0,} /* 0 terminated list. */ {0,} /* 0 terminated list. */
}; };
static struct edac_pci_ctl_info *i7core_pci;
/**************************************************************************** /****************************************************************************
Anciliary status routines Anciliary status routines
****************************************************************************/ ****************************************************************************/
...@@ -1906,9 +1907,9 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev, ...@@ -1906,9 +1907,9 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev,
} }
/* allocating generic PCI control info */ /* allocating generic PCI control info */
i7core_pci = edac_pci_create_generic_ctl(&i7core_dev->pdev[0]->dev, pvt->i7core_pci = edac_pci_create_generic_ctl(&i7core_dev->pdev[0]->dev,
EDAC_MOD_STR); EDAC_MOD_STR);
if (unlikely(!i7core_pci)) { if (unlikely(!pvt->i7core_pci)) {
printk(KERN_WARNING printk(KERN_WARNING
"%s(): Unable to create PCI control\n", "%s(): Unable to create PCI control\n",
__func__); __func__);
...@@ -2008,12 +2009,10 @@ static void __devexit i7core_remove(struct pci_dev *pdev) ...@@ -2008,12 +2009,10 @@ static void __devexit i7core_remove(struct pci_dev *pdev)
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
struct i7core_dev *i7core_dev, *tmp; struct i7core_dev *i7core_dev, *tmp;
struct i7core_pvt *pvt;
debugf0(__FILE__ ": %s()\n", __func__); debugf0(__FILE__ ": %s()\n", __func__);
if (i7core_pci)
edac_pci_release_generic_ctl(i7core_pci);
/* /*
* we have a trouble here: pdev value for removal will be wrong, since * we have a trouble here: pdev value for removal will be wrong, since
* it will point to the X58 register used to detect that the machine * it will point to the X58 register used to detect that the machine
...@@ -2024,19 +2023,28 @@ static void __devexit i7core_remove(struct pci_dev *pdev) ...@@ -2024,19 +2023,28 @@ static void __devexit i7core_remove(struct pci_dev *pdev)
mutex_lock(&i7core_edac_lock); mutex_lock(&i7core_edac_lock);
list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) { list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) {
mci = edac_mc_del_mc(&i7core_dev->pdev[0]->dev); mci = find_mci_by_dev(&i7core_dev->pdev[0]->dev);
if (mci) { if (unlikely(!mci || !mci->pvt_info)) {
struct i7core_pvt *pvt = mci->pvt_info; i7core_printk(KERN_ERR,
"Couldn't find mci hanler\n");
} else {
pvt = mci->pvt_info;
i7core_dev = pvt->i7core_dev; i7core_dev = pvt->i7core_dev;
if (likely(pvt->i7core_pci))
edac_pci_release_generic_ctl(pvt->i7core_pci);
else
i7core_printk(KERN_ERR,
"Couldn't find mem_ctl_info for socket %d\n",
i7core_dev->socket);
pvt->i7core_pci = NULL;
edac_mc_del_mc(&i7core_dev->pdev[0]->dev);
edac_mce_unregister(&pvt->edac_mce); edac_mce_unregister(&pvt->edac_mce);
kfree(mci->ctl_name); kfree(mci->ctl_name);
edac_mc_free(mci); edac_mc_free(mci);
i7core_put_devices(i7core_dev); i7core_put_devices(i7core_dev);
} else {
i7core_printk(KERN_ERR,
"Couldn't find mci for socket %d\n",
i7core_dev->socket);
} }
} }
probed--; probed--;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册