Re: [PATCH v4 1/2] io_uring: avoid whole io_wq_work copy for requests completed inline

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



hi,

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 12296ce3e8b9..2a3a02838f7b 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -907,9 +907,10 @@ static void io_file_put_work(struct work_struct *work);
   static inline void io_req_init_async(struct io_kiocb *req,
                          void (*func)(struct io_wq_work **))
   {
-       if (req->flags & REQ_F_WORK_INITIALIZED)
-               req->work.func = func;
-       else {
+       if (req->flags & REQ_F_WORK_INITIALIZED) {
+               if (!req->work.func)
+                       req->work.func = func;
+       } else {
                  req->work = (struct io_wq_work){ .func = func };
                  req->flags |= REQ_F_WORK_INITIALIZED;
          }
@@ -2920,6 +2921,8 @@ static int __io_splice_prep(struct io_kiocb *req,
                  return ret;
          req->flags |= REQ_F_NEED_CLEANUP;

+       /* Splice will be punted aync, so initialize io_wq_work firstly_*/
+       io_req_init_async(req, io_wq_submit_work);
          if (!S_ISREG(file_inode(sp->file_in)->i_mode))
                  req->work.flags |= IO_WQ_WORK_UNBOUND;

@@ -3592,6 +3595,9 @@ static int io_statx(struct io_kiocb *req, bool force_nonblock)

   static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
   {
+        /* Close may be punted aync, so initialize io_wq_work firstly */
+       io_req_init_async(req, io_wq_submit_work);
+
For splice and close requests, these two about io_req_init_async() calls should be
io_req_init_async(req, NULL), because they change req->work.flags firstly.

Please no. Such assumptions/dependencies are prone to break.
It'll get us subtle bugs in no time.

BTW, why not io_wq_submit_work in place of NULL?
In the begin of __io_splice_prep or io_close_prep, current io_uring mainline codes will
modify req->work.flags firstly, so we need to call io_req_init_async to initialize
io_wq_work before the work.flags modification.
For below codes:
static inline void io_req_init_async(struct io_kiocb *req,
                        void (*func)(struct io_wq_work **))
{
        if (req->flags & REQ_F_WORK_INITIALIZED) {
                if (!req->work.func)
                        req->work.func = func;
        } else {
                req->work = (struct io_wq_work){ .func = func };
                req->flags |= REQ_F_WORK_INITIALIZED;
        }
}

if we not pass NULL to parameter 'func', e.g. pass io_wq_submit_work, then
we can not use io_req_init_async() to pass io_close_finish again.

Now I'm confused how to write better codes based on current io_uring mainline codes :)
If you have some free time, please have a deeper look, thanks.

Regards,
Xiaoguang Wang






[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux