On 7/6/20 8:45 AM, Pavel Begunkov wrote: > > > On 06/07/2020 17:42, Pavel Begunkov wrote: >> On 06/07/2020 17:31, Jens Axboe wrote: >>> On 7/6/20 8:14 AM, Pavel Begunkov wrote: >>>> It's not nice to hold @uring_lock for too long io_iopoll_reap_events(). >>>> For instance, the lock is needed to publish requests to @poll_list, and >>>> that locks out tasks doing that for no good reason. Loose it >>>> occasionally. >>>> >>>> Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx> >>>> --- >>>> fs/io_uring.c | 3 +++ >>>> 1 file changed, 3 insertions(+) >>>> >>>> diff --git a/fs/io_uring.c b/fs/io_uring.c >>>> index 020944a193d0..568e25bcadd6 100644 >>>> --- a/fs/io_uring.c >>>> +++ b/fs/io_uring.c >>>> @@ -2059,11 +2059,14 @@ static void io_iopoll_reap_events(struct io_ring_ctx *ctx) >>>> >>>> io_iopoll_getevents(ctx, &nr_events, 1); >>>> >>>> + /* task_work takes the lock to publish a req to @poll_list */ >>>> + mutex_unlock(&ctx->uring_lock); >>>> /* >>>> * Ensure we allow local-to-the-cpu processing to take place, >>>> * in this case we need to ensure that we reap all events. >>>> */ >>>> cond_resched(); >>>> + mutex_lock(&ctx->uring_lock); >>>> } >>>> mutex_unlock(&ctx->uring_lock); >>>> } >>> >>> This would be much better written as: >>> >>> if (need_resched()) { >>> mutex_unlock(&ctx->uring_lock); >>> cond_resched(); >>> mutex_lock(&ctx->uring_lock); >>> } >>> >>> to avoid shuffling the lock when not needed to. Every cycle counts for >>> polled IO. >> >> It happens only when io_uring is being killed, can't imagine any sane app >> trying to catch CQEs after doing that. I'll resend > > Also, io_iopoll_getevents() already does need_resched(). Hmm, do you wan't > me to resend? I missed this was the "reap on dead" path. But yes, please resend. -- Jens Axboe