workqueue: make cancel_rearming_delayed_workqueue() work on idle dwork
cancel_rearming_delayed_workqueue(dwork) will hang forever if dwork was not scheduled, because in that case cancel_delayed_work()->del_timer_sync() never returns true. I don't know if there are any callers which may have problems, but this is not so convenient, and the fix is very simple. Q: looks like we don't need "struct workqueue_struct *wq" parameter. If the timer was aborted successfully, get_wq_data() == wq. Is it worth to add the new function? Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
f293ea9200
Коммит
dfb4b82e1c
|
@ -569,6 +569,10 @@ EXPORT_SYMBOL(flush_work_keventd);
|
||||||
void cancel_rearming_delayed_workqueue(struct workqueue_struct *wq,
|
void cancel_rearming_delayed_workqueue(struct workqueue_struct *wq,
|
||||||
struct delayed_work *dwork)
|
struct delayed_work *dwork)
|
||||||
{
|
{
|
||||||
|
/* Was it ever queued ? */
|
||||||
|
if (!get_wq_data(&dwork->work))
|
||||||
|
return;
|
||||||
|
|
||||||
while (!cancel_delayed_work(dwork))
|
while (!cancel_delayed_work(dwork))
|
||||||
flush_workqueue(wq);
|
flush_workqueue(wq);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче