Commit 2b73b07ab8a44ce171e07a328439f311481a7ea7
Committed by
Herbert Xu
1 parent
d46a5ac7a7
Exists in
master
and in
4 other branches
padata: Flush the padata queues actively
yield was used to wait until all references of the internal control structure in use are dropped before it is freed. This patch implements padata_flush_queues which actively flushes the padata percpu queues in this case. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Showing 1 changed file with 25 additions and 8 deletions Side-by-side Diff
kernel/padata.c
... | ... | @@ -417,6 +417,29 @@ |
417 | 417 | kfree(pd); |
418 | 418 | } |
419 | 419 | |
420 | +static void padata_flush_queues(struct parallel_data *pd) | |
421 | +{ | |
422 | + int cpu; | |
423 | + struct padata_queue *queue; | |
424 | + | |
425 | + for_each_cpu(cpu, pd->cpumask) { | |
426 | + queue = per_cpu_ptr(pd->queue, cpu); | |
427 | + flush_work(&queue->pwork); | |
428 | + } | |
429 | + | |
430 | + del_timer_sync(&pd->timer); | |
431 | + | |
432 | + if (atomic_read(&pd->reorder_objects)) | |
433 | + padata_reorder(pd); | |
434 | + | |
435 | + for_each_cpu(cpu, pd->cpumask) { | |
436 | + queue = per_cpu_ptr(pd->queue, cpu); | |
437 | + flush_work(&queue->swork); | |
438 | + } | |
439 | + | |
440 | + BUG_ON(atomic_read(&pd->refcnt) != 0); | |
441 | +} | |
442 | + | |
420 | 443 | static void padata_replace(struct padata_instance *pinst, |
421 | 444 | struct parallel_data *pd_new) |
422 | 445 | { |
... | ... | @@ -428,11 +451,7 @@ |
428 | 451 | |
429 | 452 | synchronize_rcu(); |
430 | 453 | |
431 | - while (atomic_read(&pd_old->refcnt) != 0) | |
432 | - yield(); | |
433 | - | |
434 | - flush_workqueue(pinst->wq); | |
435 | - | |
454 | + padata_flush_queues(pd_old); | |
436 | 455 | padata_free_pd(pd_old); |
437 | 456 | |
438 | 457 | pinst->flags &= ~PADATA_RESET; |
439 | 458 | |
... | ... | @@ -695,12 +714,10 @@ |
695 | 714 | |
696 | 715 | synchronize_rcu(); |
697 | 716 | |
698 | - while (atomic_read(&pinst->pd->refcnt) != 0) | |
699 | - yield(); | |
700 | - | |
701 | 717 | #ifdef CONFIG_HOTPLUG_CPU |
702 | 718 | unregister_hotcpu_notifier(&pinst->cpu_notifier); |
703 | 719 | #endif |
720 | + padata_flush_queues(pinst->pd); | |
704 | 721 | padata_free_pd(pinst->pd); |
705 | 722 | free_cpumask_var(pinst->cpumask); |
706 | 723 | kfree(pinst); |