[PATCH] EDAC: mc numbers refactor 1-of-2
Doug Thompson [Fri, 30 Jun 2006 08:56:08 +0000 (01:56 -0700)]
Remove add_mc_to_global_list().  In next patch, this function will be
reimplemented with different semantics.

1 Reimplement add_mc_to_global_list() with semantics that allow the caller to
  determine the ID number for a mem_ctl_info structure.  Then modify
  edac_mc_add_mc() so that the caller specifies the ID number for the new
  mem_ctl_info structure.  Platform-specific code should be able to assign the
  ID numbers in a platform-specific manner.  For instance, on Opteron it makes
  sense to have the ID of the mem_ctl_info structure match the ID of the node
  that the memory controller belongs to.

2 Modify callers of edac_mc_add_mc() so they use the new semantics.

Signed-off-by: Doug Thompson <norsk5@xmission.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

drivers/edac/amd76x_edac.c
drivers/edac/e752x_edac.c
drivers/edac/e7xxx_edac.c
drivers/edac/edac_mc.c
drivers/edac/edac_mc.h
drivers/edac/i82860_edac.c
drivers/edac/i82875p_edac.c
drivers/edac/r82600_edac.c

index 7fd6283..303cb50 100644 (file)
@@ -257,7 +257,10 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx)
 
        amd76x_get_error_info(mci, &discard);  /* clear counters */
 
-       if (edac_mc_add_mc(mci)) {
+       /* Here we assume that we will never see multiple instances of this
+        * type of memory controller.  The ID is therefore hardcoded to 0.
+        */
+       if (edac_mc_add_mc(mci,0)) {
                debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
                goto fail;
        }
index de9f332..5e773e3 100644 (file)
@@ -953,7 +953,10 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
                "tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm,
                pvt->remapbase, pvt->remaplimit);
 
-       if (edac_mc_add_mc(mci)) {
+       /* Here we assume that we will never see multiple instances of this
+        * type of memory controller.  The ID is therefore hardcoded to 0.
+        */
+       if (edac_mc_add_mc(mci,0)) {
                debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
                goto fail;
        }
index d601d53..1e282c8 100644 (file)
@@ -463,7 +463,10 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx)
        /* clear any pending errors, or initial state bits */
        e7xxx_get_error_info(mci, &discard);
 
-       if (edac_mc_add_mc(mci) != 0) {
+       /* Here we assume that we will never see multiple instances of this
+        * type of memory controller.  The ID is therefore hardcoded to 0.
+        */
+       if (edac_mc_add_mc(mci,0)) {
                debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
                goto fail;
        }
index 603de8b..357c95f 100644 (file)
@@ -1632,47 +1632,46 @@ static struct mem_ctl_info *find_mci_by_dev(struct device *dev)
        return NULL;
 }
 
-static int add_mc_to_global_list(struct mem_ctl_info *mci)
+/* Return 0 on success, 1 on failure.
+ * Before calling this function, caller must
+ * assign a unique value to mci->mc_idx.
+ */
+static int add_mc_to_global_list (struct mem_ctl_info *mci)
 {
        struct list_head *item, *insert_before;
        struct mem_ctl_info *p;
-       int i;
 
-       if (list_empty(&mc_devices)) {
-               mci->mc_idx = 0;
-               insert_before = &mc_devices;
-       } else {
-               if (find_mci_by_dev(mci->dev)) {
-                       edac_printk(KERN_WARNING, EDAC_MC,
-                               "%s (%s) %s %s already assigned %d\n",
-                               mci->dev->bus_id, dev_name(mci->dev),
-                               mci->mod_name, mci->ctl_name,
-                               mci->mc_idx);
-                       return 1;
-               }
+       insert_before = &mc_devices;
 
-               insert_before = NULL;
-               i = 0;
+       if (unlikely((p = find_mci_by_dev(mci->dev)) != NULL))
+               goto fail0;
 
-               list_for_each(item, &mc_devices) {
-                       p = list_entry(item, struct mem_ctl_info, link);
+       list_for_each(item, &mc_devices) {
+               p = list_entry(item, struct mem_ctl_info, link);
 
-                       if (p->mc_idx != i) {
-                               insert_before = item;
-                               break;
-                       }
+               if (p->mc_idx >= mci->mc_idx) {
+                       if (unlikely(p->mc_idx == mci->mc_idx))
+                               goto fail1;
 
-                       i++;
+                       insert_before = item;
+                       break;
                }
-
-               mci->mc_idx = i;
-
-               if (insert_before == NULL)
-                       insert_before = &mc_devices;
        }
 
        list_add_tail_rcu(&mci->link, insert_before);
        return 0;
+
+fail0:
+       edac_printk(KERN_WARNING, EDAC_MC,
+                   "%s (%s) %s %s already assigned %d\n", p->dev->bus_id,
+                   dev_name(p->dev), p->mod_name, p->ctl_name, p->mc_idx);
+       return 1;
+
+fail1:
+       edac_printk(KERN_WARNING, EDAC_MC,
+                   "bug in low-level driver: attempt to assign\n"
+                   "    duplicate mc_idx %d in %s()\n", p->mc_idx, __func__);
+       return 1;
 }
 
 static void complete_mc_list_del(struct rcu_head *head)
@@ -1696,6 +1695,7 @@ static void del_mc_from_global_list(struct mem_ctl_info *mci)
  * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and
  *                 create sysfs entries associated with mci structure
  * @mci: pointer to the mci structure to be added to the list
+ * @mc_idx: A unique numeric identifier to be assigned to the 'mci' structure.
  *
  * Return:
  *     0       Success
@@ -1703,9 +1703,10 @@ static void del_mc_from_global_list(struct mem_ctl_info *mci)
  */
 
 /* FIXME - should a warning be printed if no error detection? correction? */
-int edac_mc_add_mc(struct mem_ctl_info *mci)
+int edac_mc_add_mc(struct mem_ctl_info *mci, int mc_idx)
 {
        debugf0("%s()\n", __func__);
+       mci->mc_idx = mc_idx;
 #ifdef CONFIG_EDAC_DEBUG
        if (edac_debug_level >= 3)
                edac_mc_dump_mci(mci);
index a2c3a46..3429796 100644 (file)
@@ -417,7 +417,7 @@ void edac_mc_dump_mci(struct mem_ctl_info *mci);
 void edac_mc_dump_csrow(struct csrow_info *csrow);
 #endif  /* CONFIG_EDAC_DEBUG */
 
-extern int edac_mc_add_mc(struct mem_ctl_info *mci);
+extern int edac_mc_add_mc(struct mem_ctl_info *mci,int mc_idx);
 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,
                                        unsigned long page);
index baa021b..e2c3b8b 100644 (file)
@@ -208,7 +208,10 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx)
 
        i82860_get_error_info(mci, &discard);  /* clear counters */
 
-       if (edac_mc_add_mc(mci)) {
+       /* Here we assume that we will never see multiple instances of this
+        * type of memory controller.  The ID is therefore hardcoded to 0.
+        */
+       if (edac_mc_add_mc(mci,0)) {
                debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
                edac_mc_free(mci);
        } else {
index 3f509a7..2be18ca 100644 (file)
@@ -390,7 +390,10 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
 
        i82875p_get_error_info(mci, &discard);  /* clear counters */
 
-       if (edac_mc_add_mc(mci)) {
+       /* Here we assume that we will never see multiple instances of this
+        * type of memory controller.  The ID is therefore hardcoded to 0.
+        */
+       if (edac_mc_add_mc(mci,0)) {
                debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
                goto fail3;
        }
index d04769a..eb3aa61 100644 (file)
@@ -304,7 +304,10 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
 
        r82600_get_error_info(mci, &discard);  /* clear counters */
 
-       if (edac_mc_add_mc(mci)) {
+       /* Here we assume that we will never see multiple instances of this
+        * type of memory controller.  The ID is therefore hardcoded to 0.
+        */
+       if (edac_mc_add_mc(mci,0)) {
                debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
                goto fail;
        }