Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

edac: core: remove completion-wait for complete with rcu_barrier

Module edac_core.ko uses call_rcu() callbacks in edac_device.c, edac_mc.c
and edac_pci.c.

They all use a wait_for_completion() scheme, but this scheme it not 100%
safe on multiple CPUs. See the _rcu_barrier() implementation which
explains why extra precausion is needed.

The patch adds a comment about rcu_barrier() and as a precausion calls
rcu_barrier(). A maintainer needs to look at removing the
wait_for_completion code.

[dougthompson@xmission.com: remove the wait_for_completion code]
Signed-off-by Jesper Dangaard Brouer <hawk@comx.dk>
Signed-off-by: Doug Thompson <dougthompson@xmission.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Jesper Dangaard Brouer and committed by
Linus Torvalds
458e5ff1 dd8ef1db

+3 -10
+1 -4
drivers/edac/edac_device.c
··· 356 356 357 357 edac_dev = container_of(head, struct edac_device_ctl_info, rcu); 358 358 INIT_LIST_HEAD(&edac_dev->link); 359 - complete(&edac_dev->removal_complete); 360 359 } 361 360 362 361 /* ··· 368 369 *edac_device) 369 370 { 370 371 list_del_rcu(&edac_device->link); 371 - 372 - init_completion(&edac_device->removal_complete); 373 372 call_rcu(&edac_device->rcu, complete_edac_device_list_del); 374 - wait_for_completion(&edac_device->removal_complete); 373 + rcu_barrier(); 375 374 } 376 375 377 376 /*
+1 -3
drivers/edac/edac_mc.c
··· 418 418 419 419 mci = container_of(head, struct mem_ctl_info, rcu); 420 420 INIT_LIST_HEAD(&mci->link); 421 - complete(&mci->complete); 422 421 } 423 422 424 423 static void del_mc_from_global_list(struct mem_ctl_info *mci) 425 424 { 426 425 atomic_dec(&edac_handlers); 427 426 list_del_rcu(&mci->link); 428 - init_completion(&mci->complete); 429 427 call_rcu(&mci->rcu, complete_mc_list_del); 430 - wait_for_completion(&mci->complete); 428 + rcu_barrier(); 431 429 } 432 430 433 431 /**
+1 -3
drivers/edac/edac_pci.c
··· 174 174 175 175 pci = container_of(head, struct edac_pci_ctl_info, rcu); 176 176 INIT_LIST_HEAD(&pci->link); 177 - complete(&pci->complete); 178 177 } 179 178 180 179 /* ··· 184 185 static void del_edac_pci_from_global_list(struct edac_pci_ctl_info *pci) 185 186 { 186 187 list_del_rcu(&pci->link); 187 - init_completion(&pci->complete); 188 188 call_rcu(&pci->rcu, complete_edac_pci_list_del); 189 - wait_for_completion(&pci->complete); 189 + rcu_barrier(); 190 190 } 191 191 192 192 #if 0