Re: [ISSUE] The time cost of IOSQE_IO_LINK

Oleg Nesterov
2020-02-18T15:07:59Z

On 02/18, Oleg Nesterov wrote:
>
> otherwise I think this is correct, but how about the patch below?
> Then this code can be changed to use try_cmpxchg().

You have already sent the patch which adds the generic try_cmpxchg,
so the patch below can be trivially adapted.

But I'd prefer another change, I think both task_work_add() and
task_work_cancel() can use try_cmpxchg() too.

>
> Oleg.
>
> --- a/kernel/task_work.c
> +++ b/kernel/task_work.c
> @@ -97,17 +97,24 @@ void task_work_run(void)
> * work->func() can do task_work_add(), do not set
> * work_exited unless the list is empty.
> */
> - raw_spin_lock_irq(&task->pi_lock);
> do {
> + head = NULL;
> work = READ_ONCE(task->task_works);
> - head = !work && (task->flags & PF_EXITING) ?
> - &work_exited : NULL;
> + if (!work) {
> + if (task->flags & PF_EXITING)
> + head = &work_exited;
> + else
> + break;
> + }
> } while (cmpxchg(&task->task_works, work, head) != work);
> - raw_spin_unlock_irq(&task->pi_lock);
>
> if (!work)
> break;
>
> + // Synchronize with task_work_cancel()
> + raw_spin_lock_irq(&task->pi_lock);
> + raw_spin_unlock_irq(&task->pi_lock);
> +
> do {
> next = work->next;
> work->func(work);