aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/edac_core.h12
-rw-r--r--drivers/edac/edac_device.c24
-rw-r--r--drivers/edac/edac_mc.c16
-rw-r--r--drivers/edac/edac_pci.c21
4 files changed, 18 insertions, 55 deletions
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index eefa3501916b..55b8278bb172 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -421,10 +421,6 @@ struct mem_ctl_info {
421 u32 ce_count; /* Total Correctable Errors for this MC */ 421 u32 ce_count; /* Total Correctable Errors for this MC */
422 unsigned long start_time; /* mci load start time (in jiffies) */ 422 unsigned long start_time; /* mci load start time (in jiffies) */
423 423
424 /* this stuff is for safe removal of mc devices from global list while
425 * NMI handlers may be traversing list
426 */
427 struct rcu_head rcu;
428 struct completion complete; 424 struct completion complete;
429 425
430 /* edac sysfs device control */ 426 /* edac sysfs device control */
@@ -620,10 +616,6 @@ struct edac_device_ctl_info {
620 616
621 unsigned long start_time; /* edac_device load start time (jiffies) */ 617 unsigned long start_time; /* edac_device load start time (jiffies) */
622 618
623 /* these are for safe removal of mc devices from global list while
624 * NMI handlers may be traversing list
625 */
626 struct rcu_head rcu;
627 struct completion removal_complete; 619 struct completion removal_complete;
628 620
629 /* sysfs top name under 'edac' directory 621 /* sysfs top name under 'edac' directory
@@ -722,10 +714,6 @@ struct edac_pci_ctl_info {
722 714
723 unsigned long start_time; /* edac_pci load start time (jiffies) */ 715 unsigned long start_time; /* edac_pci load start time (jiffies) */
724 716
725 /* these are for safe removal of devices from global list while
726 * NMI handlers may be traversing list
727 */
728 struct rcu_head rcu;
729 struct completion complete; 717 struct completion complete;
730 718
731 /* sysfs top name under 'edac' directory 719 /* sysfs top name under 'edac' directory
diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c
index a7408cf86f37..c3f67437afb6 100644
--- a/drivers/edac/edac_device.c
+++ b/drivers/edac/edac_device.c
@@ -346,30 +346,18 @@ fail1:
346} 346}
347 347
348/* 348/*
349 * complete_edac_device_list_del
350 *
351 * callback function when reference count is zero
352 */
353static void complete_edac_device_list_del(struct rcu_head *head)
354{
355 struct edac_device_ctl_info *edac_dev;
356
357 edac_dev = container_of(head, struct edac_device_ctl_info, rcu);
358 INIT_LIST_HEAD(&edac_dev->link);
359}
360
361/*
362 * del_edac_device_from_global_list 349 * del_edac_device_from_global_list
363 *
364 * remove the RCU, setup for a callback call,
365 * then wait for the callback to occur
366 */ 350 */
367static void del_edac_device_from_global_list(struct edac_device_ctl_info 351static void del_edac_device_from_global_list(struct edac_device_ctl_info
368 *edac_device) 352 *edac_device)
369{ 353{
370 list_del_rcu(&edac_device->link); 354 list_del_rcu(&edac_device->link);
371 call_rcu(&edac_device->rcu, complete_edac_device_list_del); 355
372 rcu_barrier(); 356 /* these are for safe removal of devices from global list while
357 * NMI handlers may be traversing list
358 */
359 synchronize_rcu();
360 INIT_LIST_HEAD(&edac_device->link);
373} 361}
374 362
375/* 363/*
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 1d8056049072..d69144a09043 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -447,20 +447,16 @@ fail1:
447 return 1; 447 return 1;
448} 448}
449 449
450static void complete_mc_list_del(struct rcu_head *head)
451{
452 struct mem_ctl_info *mci;
453
454 mci = container_of(head, struct mem_ctl_info, rcu);
455 INIT_LIST_HEAD(&mci->link);
456}
457
458static void del_mc_from_global_list(struct mem_ctl_info *mci) 450static void del_mc_from_global_list(struct mem_ctl_info *mci)
459{ 451{
460 atomic_dec(&edac_handlers); 452 atomic_dec(&edac_handlers);
461 list_del_rcu(&mci->link); 453 list_del_rcu(&mci->link);
462 call_rcu(&mci->rcu, complete_mc_list_del); 454
463 rcu_barrier(); 455 /* these are for safe removal of devices from global list while
456 * NMI handlers may be traversing list
457 */
458 synchronize_rcu();
459 INIT_LIST_HEAD(&mci->link);
464} 460}
465 461
466/** 462/**
diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c
index efb5d5650783..2b378207d571 100644
--- a/drivers/edac/edac_pci.c
+++ b/drivers/edac/edac_pci.c
@@ -164,19 +164,6 @@ fail1:
164} 164}
165 165
166/* 166/*
167 * complete_edac_pci_list_del
168 *
169 * RCU completion callback to indicate item is deleted
170 */
171static void complete_edac_pci_list_del(struct rcu_head *head)
172{
173 struct edac_pci_ctl_info *pci;
174
175 pci = container_of(head, struct edac_pci_ctl_info, rcu);
176 INIT_LIST_HEAD(&pci->link);
177}
178
179/*
180 * del_edac_pci_from_global_list 167 * del_edac_pci_from_global_list
181 * 168 *
182 * remove the PCI control struct from the global list 169 * remove the PCI control struct from the global list
@@ -184,8 +171,12 @@ static void complete_edac_pci_list_del(struct rcu_head *head)
184static void del_edac_pci_from_global_list(struct edac_pci_ctl_info *pci) 171static void del_edac_pci_from_global_list(struct edac_pci_ctl_info *pci)
185{ 172{
186 list_del_rcu(&pci->link); 173 list_del_rcu(&pci->link);
187 call_rcu(&pci->rcu, complete_edac_pci_list_del); 174
188 rcu_barrier(); 175 /* these are for safe removal of devices from global list while
176 * NMI handlers may be traversing list
177 */
178 synchronize_rcu();
179 INIT_LIST_HEAD(&pci->link);
189} 180}
190 181
191#if 0 182#if 0