RE: [PATCH] task_work: return -EBUSY when adding same work

From: David Laight
Date: Tue Jul 13 2021 - 06:41:34 EST


From: Jens Axboe
> Sent: 09 July 2021 15:18
...
> > */
> > int task_work_add(struct task_struct *task, struct callback_head *work,
> > enum task_work_notify_mode notify)
> > @@ -41,6 +41,8 @@ int task_work_add(struct task_struct *task, struct callback_head *work,
> > head = READ_ONCE(task->task_works);
> > if (unlikely(head == &work_exited))
> > return -ESRCH;
> > + if (unlikely(head == work))
> > + return -EBUSY;
> > work->next = head;
> > } while (cmpxchg(&task->task_works, head, work) != head);
>
> I don't think there's anything conceptually wrong with this patch, but
> it makes me think that you hit this condition. It's really a bug in the
> caller, of course, is a WARN_ON_ONCE() warranted here? And who was the
> caller?

How can the caller know that the task is on the queue?

There will be a race condition just before the work function
is called and/or just after it returns that the caller
can't detect.
The check needs to be done atomically with the code that
removes the work item from the list.

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)