lkml.org 
[lkml]   [2007]   [May]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] make-cancel_rearming_delayed_work-reliable-fix
on top of
make-cancel_rearming_delayed_work-reliable-spelling.patch

Add cpu-relax() into spinloops, and a comments update.

Small note. The new implementation has another downside. Suppose that rearming
work->func() gets a preemtion after setting WORK_STRUCT_PENDING but before
add_timer/__queue_work. In that case cancel_rearming_delayed_work() will burn
CPU in a busy-wait loop. Fortunately this can happen only with CONFIG_PREEMPT
and we spin with preemption enabled.

We can avoid this,

void cancel_rearming_delayed_work(struct delayed_work *dwork)
{
int retry;

do {
retry = !del_timer(&dwork->timer) &&
!try_to_grab_pending(&dwork->work);
wait_on_work(&dwork->work);
} while (retry);

work_clear_pending(&dwork->work);
}

but I don't think this is worth fixing.

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>

--- OLD/kernel/workqueue.c~2_RELAX 2007-05-05 23:17:48.000000000 +0400
+++ OLD/kernel/workqueue.c 2007-05-05 23:59:59.000000000 +0400
@@ -475,13 +475,16 @@ static void wait_on_work(struct work_str
* case it only guarantees that work->func() has completed on the last queued
* workqueue.
*
+ * cancel_work_sync(&delayed_work->work) should be used only if ->timer is not
+ * pending, otherwise it goes into a busy-wait loop until the timer expires.
+ *
* The caller must ensure that workqueue_struct on which this work was last
* queued can't be destroyed before this function returns.
*/
void cancel_work_sync(struct work_struct *work)
{
while (!try_to_grab_pending(work))
- ;
+ cpu_relax();
wait_on_work(work);
work_clear_pending(work);
}
@@ -498,7 +501,7 @@ void cancel_rearming_delayed_work(struct
{
while (!del_timer(&dwork->timer) &&
!try_to_grab_pending(&dwork->work))
- ;
+ cpu_relax();
wait_on_work(&dwork->work);
work_clear_pending(&dwork->work);
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2007-05-05 23:35    [W:0.161 / U:0.408 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site