Hello,
On Wed, Nov 18, 2015 at 02:25:14PM +0100, Petr Mladek wrote:
quoted hunk ↗ jump to hunk
+static int
+try_to_cancel_kthread_work(struct kthread_work *work,
+ spinlock_t *lock,
+ unsigned long *flags)
+{
+ int ret = 0;
+
+ if (work->timer) {
+ /* Try to cancel the timer if pending. */
+ if (del_timer(work->timer)) {
+ ret = 1;
+ goto out;
+ }
+
+ /* Are we racing with the timer callback? */
+ if (timer_active(work->timer)) {
+ /* Bad luck, need to avoid a deadlock. */
+ spin_unlock_irqrestore(lock, *flags);
+ del_timer_sync(work->timer);
+ ret = -EAGAIN;
+ goto out;
+ }
As the timer side is already kinda trylocking anyway, can't the cancel
path be made simpler? Sth like
lock(worker);
work->canceling = true;
del_timer_sync(work->timer);
unlock(worker);
And the timer can do (ignoring the multiple worker support, do we even
need that?)
while (!trylock(worker)) {
if (work->canceling)
return;
cpu_relax();
}
queue;
unlock(worker);
Thanks.
--
tejun