Re: Memory coherency issue with IO thread offloading?
From: Jens Axboe <axboe@kernel.dk>
Date: 2023-03-25 01:21:08
Subsystem:
io_uring, the rest · Maintainers:
Jens Axboe, Linus Torvalds
On 3/24/23 7:15?PM, Jens Axboe wrote:
quoted
Are there any CONFIG options I'd need to trip this?I don't think you need any special CONFIG options. I'll attach my config here, and I know the default distro one hits it too. But perhaps the mariadb version is not new enough? I think you need 10.6 or above, as will use io_uring by default. What version are you running?
And here's the .config and the patch for using queue_work().
diff --git a/io_uring/rw.c b/io_uring/rw.c
index 4c233910e200..14ce460aa036 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c@@ -850,6 +865,8 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags) return kiocb_done(req, ret, issue_flags); } +static int io_rewrite_queue(struct io_kiocb *req); + int io_write(struct io_kiocb *req, unsigned int issue_flags) { struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
@@ -974,7 +991,9 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags) if (!ret) { if (kiocb->ki_flags & IOCB_WRITE) kiocb_end_write(req); - return -EAGAIN; + if (io_rewrite_queue(req)) + return -EAGAIN; + return IOU_ISSUE_SKIP_COMPLETE; } return ret; }
@@ -984,6 +1003,45 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags) return ret; } +struct koffload { + struct work_struct work; + struct io_kiocb *req; + struct mm_struct *mm; +}; + +static void io_rewrite(struct work_struct *work) +{ + struct koffload *k = container_of(work, struct koffload, work); + unsigned issue_flags = IO_URING_F_UNLOCKED; + int ret; + + kthread_use_mm(k->mm); + ret = io_write(k->req, issue_flags); + kthread_unuse_mm(k->mm); + mmput(k->mm); + + if (ret != IOU_ISSUE_SKIP_COMPLETE) + io_req_complete_post(k->req, issue_flags); + kfree(k); +} + +static int io_rewrite_queue(struct io_kiocb *req) +{ + struct koffload *k; + + k = kmalloc(sizeof(*k), GFP_NOIO); + if (!k) + return 1; + + INIT_WORK(&k->work, io_rewrite); + k->req = req; + mmget(current->mm); + k->mm = current->mm; + queue_work(system_wq, &k->work); + return 0; +} + + static void io_cqring_ev_posted_iopoll(struct io_ring_ctx *ctx) { io_commit_cqring_flush(ctx);
--
Jens AxboeAttachments
- ppc-config [text/plain] 128641 bytes · preview