On 9/15/20 7:25 AM, Jens Axboe wrote: > On 9/15/20 7:02 AM, Yinyin Zhu wrote: >> when parent process setup a io_uring_instance, the ctx->sqo_mm was >> assigned of parent process'mm. Then it fork a child >> process. So the child process inherits the io_uring_instance fd from >> parent process. Then the child process submit a io task to the io_uring >> instance. The kworker will do the io task actually, and use >> the ctx->sqo_mm as its mm, but this ctx->sqo_mm is parent process's mm, >> not the child process's mm. so child do the io task unsuccessfully. To >> fix this bug, when a process submit a io task to the kworker, assign the >> ctx->sqo_mm with this process's mm. > > Hmm, what's the test case for this? There's a 5.9 regression where we > don't always grab the right context for certain linked cases, below > is the fix. Does that fix your case? Ah hang on, you're on the 5.4 code base... I think this is a better approach. Any chance you can test it? The problem with yours is that you can have multiple pending async ones, and you can't just re-assign ctx->sqo_mm. That one should only be used by the SQPOLL thread. diff --git a/fs/io_uring.c b/fs/io_uring.c index 2a539b794f3b..e8a4b4ae7006 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -514,7 +514,7 @@ static inline void io_queue_async_work(struct io_ring_ctx *ctx, } } - req->task = current; + req->task = get_task_struct(current); spin_lock_irqsave(&ctx->task_lock, flags); list_add(&req->task_list, &ctx->task_list); @@ -1832,6 +1832,7 @@ static void io_poll_complete_work(struct work_struct *work) spin_unlock_irq(&ctx->completion_lock); io_cqring_ev_posted(ctx); + put_task_struct(req->task); io_put_req(req); out: revert_creds(old_cred); @@ -2234,11 +2235,11 @@ static void io_sq_wq_submit_work(struct work_struct *work) ret = 0; if (io_req_needs_user(req) && !cur_mm) { - if (!mmget_not_zero(ctx->sqo_mm)) { + if (!mmget_not_zero(req->task->mm)) { ret = -EFAULT; goto end_req; } else { - cur_mm = ctx->sqo_mm; + cur_mm = req->task->mm; use_mm(cur_mm); old_fs = get_fs(); set_fs(USER_DS); @@ -2275,6 +2276,7 @@ static void io_sq_wq_submit_work(struct work_struct *work) } /* drop submission reference */ + put_task_struct(req->task); io_put_req(req); if (ret) { -- Jens Axboe