fs: kill unused ret2 argument from iocb->ki_complete()
Subsystems (13)
Jens Axboe
maintainerPATCH 1/1 fs: kill unused ret2 argument from iocb->ki_complete()
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all ki_complete users in the kernel to drop that last argument.
The exception is the USB gadget code, which passes in non-zero. But since nobody every looks at ret2, it's still pointless.
---
block/fops.c +2 -2
@@ -164,7 +164,7 @@ static void blkdev_bio_end_io(struct bio *bio) ret =blk_status_to_errno (dio->bio.bi_status); } - iocb->ki_complete (iocb, ret,0 ); + iocb->ki_complete (iocb, ret);if (flags &DIO_MULTI_BIO )bio_put (&dio->bio); }else {
@@ -318,7 +318,7 @@ static void blkdev_bio_end_io_async(struct bio *bio) ret =blk_status_to_errno (bio->bi_status); } - iocb->ki_complete (iocb, ret,0 ); + iocb->ki_complete (iocb, ret);if (dio->flags &DIO_SHOULD_DIRTY ) {bio_check_pages_dirty (bio);
crypto/af_alg.c +1 -1
@@ -1076,7 +1076,7 @@ void af_alg_async_cb(struct crypto_async_request *_req, int err)af_alg_free_resources (areq);sock_put (sk); - iocb->ki_complete (iocb, err ? err : (int )resultlen,0 ); + iocb->ki_complete (iocb, err ? err : (int )resultlen); }EXPORT_SYMBOL_GPL (af_alg_async_cb);
drivers/block/loop.c +2 -2
@@ -550,7 +550,7 @@ static void lo_rw_aio_do_completion(struct loop_cmd *cmd)blk_mq_complete_request (rq); } -static void lo_rw_aio_complete (struct kiocb *iocb,long ret,long ret2) +static void lo_rw_aio_complete (struct kiocb *iocb,long ret) { struct loop_cmd *cmd = container_of(iocb, struct loop_cmd, iocb);
@@ -623,7 +623,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,lo_rw_aio_do_completion (cmd);if (ret != -EIOCBQUEUED ) - cmd->iocb.ki_complete (&cmd->iocb, ret,0 ); +lo_rw_aio_complete (&cmd->iocb, ret);return 0 ; }
drivers/nvme/target/io-cmd-file.c +2 -2
@@ -123,7 +123,7 @@ static ssize_t nvmet_file_submit_bvec(struct nvmet_req *req, loff_t pos,return call_iter (iocb, &iter); } -static void nvmet_file_io_done (struct kiocb *iocb,long ret,long ret2) +static void nvmet_file_io_done (struct kiocb *iocb,long ret) { struct nvmet_req *req = container_of(iocb, struct nvmet_req, f.iocb);u16 status =NVME_SC_SUCCESS ;
@@ -220,7 +220,7 @@ static bool nvmet_file_execute_io(struct nvmet_req *req, int ki_flags) } complete: -nvmet_file_io_done (&req->f.iocb, ret,0 ); +nvmet_file_io_done (&req->f.iocb, ret);return true; }
drivers/target/target_core_file.c +2 -2
@@ -245,7 +245,7 @@ struct target_core_file_cmd {struct bio_vec bvecs[]; }; -static void cmd_rw_aio_complete (struct kiocb *iocb,long ret,long ret2) +static void cmd_rw_aio_complete (struct kiocb *iocb,long ret) {struct target_core_file_cmd *cmd;
@@ -301,7 +301,7 @@ fd_execute_rw_aio(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, ret =call_read_iter (file, &aio_cmd->iocb, &iter);if (ret != -EIOCBQUEUED ) -cmd_rw_aio_complete (&aio_cmd->iocb, ret,0 ); +cmd_rw_aio_complete (&aio_cmd->iocb, ret);return 0 ; }
drivers/usb/gadget/function/f_fs.c +1 -1
@@ -831,7 +831,7 @@ static void ffs_user_copy_worker(struct work_struct *work)kthread_unuse_mm (io_data->mm); } - io_data->kiocb->ki_complete (io_data->kiocb, ret, ret); + io_data->kiocb->ki_complete (io_data->kiocb, ret);if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd)eventfd_signal (io_data->ffs->ffs_eventfd,1 );
drivers/usb/gadget/legacy/inode.c +2 -3
@@ -469,7 +469,7 @@ static void ep_user_copy_worker(struct work_struct *work) ret = -EFAULT ;/* completing the iocb can drop the ctx and mm, don't touch mm after */ - iocb->ki_complete (iocb, ret, ret); + iocb->ki_complete (iocb, ret);kfree (priv->buf);kfree (priv->to_free);
@@ -499,8 +499,7 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)/* aio_complete() reports bytes-transferred _and_ faults */ iocb->ki_complete (iocb, - req->actual ? req->actual : (long )req->status, - req->status); + req->actual ? req->actual : (long )req->status); }else {/* ep_copy_to_user() won't report both; we hide some faults */ if (unlikely (0 != req->status))
fs/aio.c +3 -3
@@ -1417,7 +1417,7 @@ static void aio_remove_iocb(struct aio_kiocb *iocb)spin_unlock_irqrestore (&ctx->ctx_lock, flags); } -static void aio_complete_rw (struct kiocb *kiocb,long res,long res2) +static void aio_complete_rw (struct kiocb *kiocb,long res) { struct aio_kiocb *iocb = container_of(kiocb, struct aio_kiocb, rw);
@@ -1437,7 +1437,7 @@ static void aio_complete_rw(struct kiocb *kiocb, long res, long res2) } iocb->ki_res.res = res; - iocb->ki_res.res2 = res2; + iocb->ki_res.res2 =0 ;iocb_put (iocb); }
@@ -1508,7 +1508,7 @@ static inline void aio_rw_done(struct kiocb *req, ssize_t ret) ret = -EINTR ; fallthrough;default : - req->ki_complete (req, ret,0 ); + req->ki_complete (req, ret); } }
fs/cachefiles/io.c +6 -6
@@ -37,11 +37,11 @@ static inline void cachefiles_put_kiocb(struct cachefiles_kiocb *ki)/* * Handle completion of a read from the cache. */ -static void cachefiles_read_complete (struct kiocb *iocb,long ret,long ret2) +static void cachefiles_read_complete (struct kiocb *iocb,long ret) { struct cachefiles_kiocb *ki = container_of(iocb, struct cachefiles_kiocb, iocb); -_enter ("%ld,%ld" , ret, ret2); +_enter ("%ld" , ret);if (ki->term_func) {if (ret >=0 )
@@ -139,7 +139,7 @@ static int cachefiles_read(struct netfs_cache_resources *cres, fallthrough;default : ki->was_async = false; -cachefiles_read_complete (&ki->iocb, ret,0 ); +cachefiles_read_complete (&ki->iocb, ret);if (ret >0 ) ret =0 ;break ;
@@ -159,12 +159,12 @@ static int cachefiles_read(struct netfs_cache_resources *cres,/* * Handle completion of a write to the cache. */ -static void cachefiles_write_complete (struct kiocb *iocb,long ret,long ret2) +static void cachefiles_write_complete (struct kiocb *iocb,long ret) { struct cachefiles_kiocb *ki = container_of(iocb, struct cachefiles_kiocb, iocb);struct inode *inode =file_inode (ki->iocb.ki_filp); -_enter ("%ld,%ld" , ret, ret2); +_enter ("%ld" , ret);/* Tell lockdep we inherited freeze protection from submission thread */ __sb_writers_acquired (inode->i_sb,SB_FREEZE_WRITE );
@@ -244,7 +244,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres, fallthrough;default : ki->was_async = false; -cachefiles_write_complete (&ki->iocb, ret,0 ); +cachefiles_write_complete (&ki->iocb, ret);if (ret >0 ) ret =0 ;break ;
fs/ceph/file.c +1 -1
@@ -1022,7 +1022,7 @@ static void ceph_aio_complete(struct inode *inode,ceph_put_cap_refs (ci, (aio_req->write ?CEPH_CAP_FILE_WR :CEPH_CAP_FILE_RD )); - aio_req->iocb->ki_complete (aio_req->iocb, ret,0 ); + aio_req->iocb->ki_complete (aio_req->iocb, ret);ceph_free_cap_flush (aio_req->prealloc_cf);kfree (aio_req);
fs/cifs/file.c +2 -2
@@ -3184,7 +3184,7 @@ static void collect_uncached_write_data(struct cifs_aio_ctx *ctx)mutex_unlock (&ctx->aio_mutex);if (ctx->iocb && ctx->iocb->ki_complete) - ctx->iocb->ki_complete (ctx->iocb, ctx->rc,0 ); + ctx->iocb->ki_complete (ctx->iocb, ctx->rc);else complete (&ctx->done); }
@@ -3917,7 +3917,7 @@ collect_uncached_read_data(struct cifs_aio_ctx *ctx)mutex_unlock (&ctx->aio_mutex);if (ctx->iocb && ctx->iocb->ki_complete) - ctx->iocb->ki_complete (ctx->iocb, ctx->rc,0 ); + ctx->iocb->ki_complete (ctx->iocb, ctx->rc);else complete (&ctx->done); }
fs/direct-io.c +1 -1
@@ -307,7 +307,7 @@ static ssize_t dio_complete(struct dio *dio, ssize_t ret, unsigned int flags)if (ret >0 && dio->op ==REQ_OP_WRITE ) ret =generic_write_sync (dio->iocb, ret); - dio->iocb->ki_complete (dio->iocb, ret,0 ); + dio->iocb->ki_complete (dio->iocb, ret); }kmem_cache_free (dio_cache, dio);
fs/fuse/file.c +1 -1
@@ -687,7 +687,7 @@ static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos)spin_unlock (&fi->lock); } - io->iocb->ki_complete (io->iocb, res,0 ); + io->iocb->ki_complete (io->iocb, res); }kref_put (&io->refcnt, fuse_io_release);
fs/io_uring.c +3 -3
@@ -2672,7 +2672,7 @@ static void __io_complete_rw(struct io_kiocb *req, long res, long res2,__io_req_complete (req, issue_flags, req->result,io_put_rw_kbuf (req)); } -static void io_complete_rw (struct kiocb *kiocb,long res,long res2) +static void io_complete_rw (struct kiocb *kiocb,long res) { struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
@@ -2683,7 +2683,7 @@ static void io_complete_rw(struct kiocb *kiocb, long res, long res2)io_req_task_work_add (req); } -static void io_complete_rw_iopoll (struct kiocb *kiocb,long res,long res2) +static void io_complete_rw_iopoll (struct kiocb *kiocb,long res) { struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
@@ -2891,7 +2891,7 @@ static inline void io_rw_done(struct kiocb *kiocb, ssize_t ret) ret = -EINTR ; fallthrough;default : - kiocb->ki_complete (kiocb, ret,0 ); + kiocb->ki_complete (kiocb, ret); } }
fs/iomap/direct-io.c +1 -1
@@ -125,7 +125,7 @@ static void iomap_dio_complete_work(struct work_struct *work) struct iomap_dio *dio = container_of(work, struct iomap_dio, aio.work);struct kiocb *iocb = dio->iocb; - iocb->ki_complete (iocb,iomap_dio_complete (dio),0 ); + iocb->ki_complete (iocb,iomap_dio_complete (dio)); }/*
fs/nfs/direct.c +1 -1
@@ -275,7 +275,7 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq) res = (long ) dreq->count;WARN_ON_ONCE (dreq->count <0 ); } - dreq->iocb->ki_complete (dreq->iocb, res,0 ); + dreq->iocb->ki_complete (dreq->iocb, res); }complete (&dreq->completion);
fs/overlayfs/file.c +2 -2
@@ -272,14 +272,14 @@ static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req)kmem_cache_free (ovl_aio_request_cachep, aio_req); } -static void ovl_aio_rw_complete (struct kiocb *iocb,long res,long res2) +static void ovl_aio_rw_complete (struct kiocb *iocb,long res) {struct ovl_aio_req *aio_req =container_of (iocb, struct ovl_aio_req, iocb);struct kiocb *orig_iocb = aio_req->orig_iocb;ovl_aio_cleanup_handler (aio_req); - orig_iocb->ki_complete (orig_iocb, res, res2); + orig_iocb->ki_complete (orig_iocb, res); }static ssize_t ovl_read_iter (struct kiocb *iocb,struct iov_iter *iter)
include/linux/fs.h +1 -1
@@ -330,7 +330,7 @@ struct kiocb {randomized_struct_fields_start loff_t ki_pos; -void (*ki_complete)(struct kiocb *iocb,long ret,long ret2); +void (*ki_complete)(struct kiocb *iocb,long ret);void *private;int ki_flags;u16 ki_hint;
Signature · 1 line
Jens Axboe
Quoted 6 lines · Jens Axboe
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.The exception is the USB gadget code, which passes in non-zero. But since nobody every looks at ret2, it's still pointless.
Yes, the USB gadget passes non-zero, and aio passes that on to userspace. So this is an ABI change. Does it actually matter? I don't know, but you could CC the relevant maintainers and list to try to figure that out.
Jens Axboe
maintainerQuoted 5 lines · Christoph Hellwig
Quoted 4 lines · Jens Axboe
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.
Quoted 7 lines
Quoted 2 lines
The exception is the USB gadget code, which passes in non-zero. But since nobody every looks at ret2, it's still pointless.
Yes, the USB gadget passes non-zero, and aio passes that on to userspace. So this is an ABI change. Does it actually matter? I don't know, but you could CC the relevant maintainers and list to try to figure that out.
True, guess it does go out to userspace. Greg, is anyone using it on the userspace side?
Signature · 1 line
Jens Axboe
Greg Kroah-Hartman
maintainerQuoted 9 lines · Jens Axboe
Quoted 8 lines · Christoph Hellwig
Quoted 6 lines · Jens Axboe
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.The exception is the USB gadget code, which passes in non-zero. But since nobody every looks at ret2, it's still pointless.
Quoted 7 lines
Quoted 4 lines
Yes, the USB gadget passes non-zero, and aio passes that on to userspace. So this is an ABI change. Does it actually matter? I don't know, but you could CC the relevant maintainers and list to try to figure that out.
True, guess it does go out to userspace. Greg, is anyone using it on the userspace side?
I really do not know (adding linux-usb@vger) My interactions with the gadget code have not been through the aio api, thankfully :)
Odds are it's fine, I think that something had to be passed in there so that was chosen? If the aio code didn't do anything with it, I can't see where the gadget code gets it back at anywhere, but I might be looking in the wrong place.
Anyone else here know?
thanks,
greg k-h
Quoted 21 lines · On Wed, 20 Oct 2021 19:49:07 +0200 Greg Kroah-Hartman…
Quoted 9 lines · Jens Axboe
Quoted 8 lines · Christoph Hellwig
Quoted 6 lines · Jens Axboe
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.The exception is the USB gadget code, which passes in non-zero. But since nobody every looks at ret2, it's still pointless.
Quoted 7 lines
Quoted 4 lines
Yes, the USB gadget passes non-zero, and aio passes that on to userspace. So this is an ABI change. Does it actually matter? I don't know, but you could CC the relevant maintainers and list to try to figure that out.
True, guess it does go out to userspace. Greg, is anyone using it on the userspace side?
I really do not know (adding linux-usb@vger) My interactions with the gadget code have not been through the aio api, thankfully :)
Quoted 6 lines
Odds are it's fine, I think that something had to be passed in there so that was chosen? If the aio code didn't do anything with it, I can't see where the gadget code gets it back at anywhere, but I might be looking in the wrong place.
Anyone else here know?
I really doubt anyone uses io_event::res2 with FunctionFS gadgets. The examples in tools/usb/ffs-aio-example/ either check just "res" or ignore the status completely.
The only other program I can find using aio FunctionFS is adbd which also checks res and ignores res2 [1]. Other examples I know of just use synchronous I/O.
Jens Axboe
maintainerQuoted 31 lines · John Keeping
Quoted 21 lines · On Wed, 20 Oct 2021 19:49:07 +0200 Greg Kroah-Hartman…
Quoted 9 lines · Jens Axboe
Quoted 8 lines · Christoph Hellwig
Quoted 6 lines · Jens Axboe
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.The exception is the USB gadget code, which passes in non-zero. But since nobody every looks at ret2, it's still pointless.
Quoted 7 lines
Quoted 4 lines
Yes, the USB gadget passes non-zero, and aio passes that on to userspace. So this is an ABI change. Does it actually matter? I don't know, but you could CC the relevant maintainers and list to try to figure that out.
True, guess it does go out to userspace. Greg, is anyone using it on the userspace side?
I really do not know (adding linux-usb@vger) My interactions with the gadget code have not been through the aio api, thankfully :)
Quoted 6 lines
Odds are it's fine, I think that something had to be passed in there so that was chosen? If the aio code didn't do anything with it, I can't see where the gadget code gets it back at anywhere, but I might be looking in the wrong place.
Anyone else here know?
Quoted 7 lines
I really doubt anyone uses
io_event::res2with FunctionFS gadgets. The examples intools/usb/ffs-aio-example/either check just "res" or ignore the status completely.The only other program I can find using aio FunctionFS is adbd which also checks res and ignores res2 [1]. Other examples I know of just use synchronous I/O.
We might consider doing a separate change to just skip status reporting, and then once a few releases have passed and if nobody has complained, then we can drop it entirely. If we do it separately, it'd be an easy revert of just that part if we do run into trouble.
At least for now we'll just have the one argument bundling the two parts for aio, so there's not a great need to eliminate the status thing on the USB gadget side. But if it is unused, then it should get removed regardless.
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerQuoted 31 lines · John Keeping
Quoted 21 lines · On Wed, 20 Oct 2021 19:49:07 +0200 Greg Kroah-Hartman…
Quoted 9 lines · Jens Axboe
Quoted 8 lines · Christoph Hellwig
Quoted 6 lines · Jens Axboe
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.The exception is the USB gadget code, which passes in non-zero. But since nobody every looks at ret2, it's still pointless.
Quoted 7 lines
Quoted 4 lines
Yes, the USB gadget passes non-zero, and aio passes that on to userspace. So this is an ABI change. Does it actually matter? I don't know, but you could CC the relevant maintainers and list to try to figure that out.
True, guess it does go out to userspace. Greg, is anyone using it on the userspace side?
I really do not know (adding linux-usb@vger) My interactions with the gadget code have not been through the aio api, thankfully :)
Quoted 6 lines
Odds are it's fine, I think that something had to be passed in there so that was chosen? If the aio code didn't do anything with it, I can't see where the gadget code gets it back at anywhere, but I might be looking in the wrong place.
Anyone else here know?
Quoted 7 lines
I really doubt anyone uses
io_event::res2with FunctionFS gadgets. The examples intools/usb/ffs-aio-example/either check just "res" or ignore the status completely.The only other program I can find using aio FunctionFS is adbd which also checks res and ignores res2 [1]. Other examples I know of just use synchronous I/O.
So is there consensus on the USB side that we can just fill res2 with zero? The single cases that does just do res == res2 puts the error in res anyway, which is what you'd expect.
If so, then I do think that'd be cleaner than packing two values into a u64.
Signature · 1 line
Jens Axboe
Greg Kroah-Hartman
maintainerQuoted 40 lines · Jens Axboe
Quoted 31 lines · John Keeping
Quoted 21 lines · On Wed, 20 Oct 2021 19:49:07 +0200 Greg Kroah-Hartman…
Quoted 9 lines · Jens Axboe
Quoted 8 lines · Christoph Hellwig
Quoted 6 lines · Jens Axboe
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.The exception is the USB gadget code, which passes in non-zero. But since nobody every looks at ret2, it's still pointless.
Quoted 7 lines
Quoted 4 lines
Yes, the USB gadget passes non-zero, and aio passes that on to userspace. So this is an ABI change. Does it actually matter? I don't know, but you could CC the relevant maintainers and list to try to figure that out.
True, guess it does go out to userspace. Greg, is anyone using it on the userspace side?
I really do not know (adding linux-usb@vger) My interactions with the gadget code have not been through the aio api, thankfully :)
Quoted 6 lines
Odds are it's fine, I think that something had to be passed in there so that was chosen? If the aio code didn't do anything with it, I can't see where the gadget code gets it back at anywhere, but I might be looking in the wrong place.
Anyone else here know?
Quoted 7 lines
I really doubt anyone uses
io_event::res2with FunctionFS gadgets. The examples intools/usb/ffs-aio-example/either check just "res" or ignore the status completely.The only other program I can find using aio FunctionFS is adbd which also checks res and ignores res2 [1]. Other examples I know of just use synchronous I/O.
Quoted 6 lines
So is there consensus on the USB side that we can just fill res2 with zero? The single cases that does just do res == res2 puts the error in res anyway, which is what you'd expect.
If so, then I do think that'd be cleaner than packing two values into a u64.
I think yes, we should try that, and if something breaks, be ready to provide a fix for it.
thanks,
greg k-h
Jens Axboe
maintainerQuoted 45 lines · Greg Kroah-Hartman
Quoted 44 lines · Jens Axboe
Quoted 31 lines · John Keeping
Quoted 21 lines · On Wed, 20 Oct 2021 19:49:07 +0200 Greg Kroah-Hartman…
Quoted 9 lines · Jens Axboe
Quoted 8 lines · Christoph Hellwig
Quoted 6 lines · Jens Axboe
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.The exception is the USB gadget code, which passes in non-zero. But since nobody every looks at ret2, it's still pointless.
Quoted 7 lines
Quoted 4 lines
Yes, the USB gadget passes non-zero, and aio passes that on to userspace. So this is an ABI change. Does it actually matter? I don't know, but you could CC the relevant maintainers and list to try to figure that out.
True, guess it does go out to userspace. Greg, is anyone using it on the userspace side?
I really do not know (adding linux-usb@vger) My interactions with the gadget code have not been through the aio api, thankfully :)
Quoted 6 lines
Odds are it's fine, I think that something had to be passed in there so that was chosen? If the aio code didn't do anything with it, I can't see where the gadget code gets it back at anywhere, but I might be looking in the wrong place.
Anyone else here know?
Quoted 7 lines
I really doubt anyone uses
io_event::res2with FunctionFS gadgets. The examples intools/usb/ffs-aio-example/either check just "res" or ignore the status completely.The only other program I can find using aio FunctionFS is adbd which also checks res and ignores res2 [1]. Other examples I know of just use synchronous I/O.
So is there consensus on the USB side that we can just fill res2 with zero? The single cases that does just do res == res2 puts the error in res anyway, which is what you'd expect.
Quoted 5 lines
Quoted 2 lines
If so, then I do think that'd be cleaner than packing two values into a u64.
I think yes, we should try that, and if something breaks, be ready to provide a fix for it.
I've split the change in two, one that gets rid of the special arguments on the USB side, and one that then drops it for the whole kernel since everybody passes 0 at that point. Should make it easy to pinpoint, if need be.
Signature · 1 line
Jens Axboe
Hi, Jens,
Quoted 3 lines · Jens Axboe
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.
What does "wasting time passing in zeroes" mean?
Quoted 2 lines
The exception is the USB gadget code, which passes in non-zero. But since nobody every looks at ret2, it's still pointless.
As Christoph mentioned, it is passed along to userspace as part of the io_event.
drivers/usb/gadget/legacy/inode.c static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) · line 499
Quoted 2 lines
drivers/usb/gadget/legacy/inode.c +0
-0@@ -499,8 +499,7 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)/* aio_complete() reports bytes-transferred _and_ faults */
Note this comment ^^^
drivers/usb/gadget/legacy/inode.c static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) · line 502
Quoted 5 lines
drivers/usb/gadget/legacy/inode.c +1
-2iocb->ki_complete (iocb, - req->actual ? req->actual : (long )req->status, - req->status); + req->actual ? req->actual : (long )req->status);
We can't know whether some userspace implementation relies on this behavior, so I don't think you can change it.
Cheers,
Jeff
p.s. Please CC linux-aio on future changes to the aio code.
Jens Axboe
maintainerQuoted 9 lines · Jeff Moyer
Hi, Jens,
Quoted 3 lines · Jens Axboe
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.What does "wasting time passing in zeroes" mean?
That everybody but the funky usb gadget code passes in zero, hence it's a waste of time to pass it in as an argument.
Quoted 5 lines
Quoted 2 lines
The exception is the USB gadget code, which passes in non-zero. But since nobody every looks at ret2, it's still pointless.
As Christoph mentioned, it is passed along to userspace as part of the
io_event.
Right
Quoted 6 lines
drivers/usb/gadget/legacy/inode.c static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) · line 499
Quoted 2 lines
drivers/usb/gadget/legacy/inode.c +0
-0@@ -499,8 +499,7 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)/* aio_complete() reports bytes-transferred _and_ faults */ Note this comment ^^^
Quoted 1 line
Quoted 7 lines
drivers/usb/gadget/legacy/inode.c static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) · line 502
Quoted 4 lines
drivers/usb/gadget/legacy/inode.c +1
-2iocb->ki_complete (iocb, - req->actual ? req->actual : (long )req->status, - req->status); + req->actual ? req->actual : (long )req->status);We can't know whether some userspace implementation relies on this behavior, so I don't think you can change it.
Well, I think we should find out, particularly as it's the sole user of that extra argument. No generic aio code would look at res2, exactly because it is always zero for anything but some weird usb gadget code.
Signature · 1 line
Jens Axboe
Quoted 5 lines · Jens Axboe
Quoted 4 lines · Jeff Moyer
Hi, Jens,
Jens Axboe <[email protected]> writes:
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.What does "wasting time passing in zeroes" mean?
That everybody but the funky usb gadget code passes in zero, hence it's a waste of time to pass it in as an argument.
OK. Just making sure you hadn't found some performance gain from this. :)
Quoted 5 lines
Quoted 2 lines
We can't know whether some userspace implementation relies on this behavior, so I don't think you can change it.
Well, I think we should find out, particularly as it's the sole user of that extra argument.
How can we find out? Anyone can write userspace usb gadget code. Some of those users may be proprietary. Is that likely? I don't know. I'd rather err on the side of not (potentially) breaking existing applications, though.
Quoted 2 lines
No generic aio code would look at res2, exactly because it is always zero for anything but some weird usb gadget code.
I think that no generic code looks at it because it isn't meant to be interpreted by generic code. :)
-Jeff
Jens Axboe
maintainerQuoted 11 lines · Jeff Moyer
Quoted 9 lines · Jens Axboe
Quoted 8 lines · Jeff Moyer
Hi, Jens,
Quoted 3 lines · Jens Axboe
It's not used for anything, and we're wasting time passing in zeroes where we could just ignore it instead. Update all
ki_completeusers in the kernel to drop that last argument.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
What does "wasting time passing in zeroes" mean?
That everybody but the funky usb gadget code passes in zero, hence it's a waste of time to pass it in as an argument.
OK. Just making sure you hadn't found some performance gain from this. :)
Oh there certainly is, not uncommon to see an extra register cleared and used just for passing in this 0.
Quoted 10 lines
Quoted 5 lines
Quoted 2 lines
We can't know whether some userspace implementation relies on this behavior, so I don't think you can change it.
Well, I think we should find out, particularly as it's the sole user of that extra argument.
How can we find out? Anyone can write userspace usb gadget code. Some of those users may be proprietary. Is that likely? I don't know. I'd rather err on the side of not (potentially) breaking existing applications, though.
Yeah I don't want to risk that either. And since I can see this turning into a discussion on what potentially would be using it, seems like the path of less resistance...
Working on just changing it to a 64-bit type instead, then we can pass in both at once with res2 being the upper 32 bits. That'll keep the same API on the aio side.
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerQuoted 3 lines · Jens Axboe
Working on just changing it to a 64-bit type instead, then we can pass in both at once with res2 being the upper 32 bits. That'll keep the same API on the aio side.
Here's that as an incremental. Since we can only be passing in 32-bits anyway across 32/64-bit, we can just make it an explicit 64-bit instead. This generates the same code on 64-bit for calling ->ki_complete, and we can trivially ignore the usb gadget issue as we now can pass in both values (and fill them in on the aio side).
drivers/block/loop.c +1 -1
@@ -550,7 +550,7 @@ static void lo_rw_aio_do_completion(struct loop_cmd *cmd)blk_mq_complete_request (rq); } -static void lo_rw_aio_complete (struct kiocb *iocb,long ret) +static void lo_rw_aio_complete (struct kiocb *iocb,u64 ret) { struct loop_cmd *cmd = container_of(iocb, struct loop_cmd, iocb);
drivers/nvme/target/io-cmd-file.c +1 -1
@@ -123,7 +123,7 @@ static ssize_t nvmet_file_submit_bvec(struct nvmet_req *req, loff_t pos,return call_iter (iocb, &iter); } -static void nvmet_file_io_done (struct kiocb *iocb,long ret) +static void nvmet_file_io_done (struct kiocb *iocb,u64 ret) { struct nvmet_req *req = container_of(iocb, struct nvmet_req, f.iocb);u16 status =NVME_SC_SUCCESS ;
drivers/target/target_core_file.c +1 -1
@@ -245,7 +245,7 @@ struct target_core_file_cmd {struct bio_vec bvecs[]; }; -static void cmd_rw_aio_complete (struct kiocb *iocb,long ret) +static void cmd_rw_aio_complete (struct kiocb *iocb,u64 ret) {struct target_core_file_cmd *cmd;
drivers/usb/gadget/function/f_fs.c +1 -1
@@ -831,7 +831,7 @@ static void ffs_user_copy_worker(struct work_struct *work)kthread_unuse_mm (io_data->mm); } - io_data->kiocb->ki_complete (io_data->kiocb, ret); + io_data->kiocb->ki_complete (io_data->kiocb, ((u64 ) ret <<32 ) | ret);if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd)eventfd_signal (io_data->ffs->ffs_eventfd,1 );
drivers/usb/gadget/legacy/inode.c +6 -4
@@ -469,7 +469,7 @@ static void ep_user_copy_worker(struct work_struct *work) ret = -EFAULT ;/* completing the iocb can drop the ctx and mm, don't touch mm after */ - iocb->ki_complete (iocb, ret); + iocb->ki_complete (iocb, ((u64 ) ret <<32 ) | ret);kfree (priv->buf);kfree (priv->to_free);
@@ -492,14 +492,16 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)* complete the aio request immediately. */ if (priv->to_free ==NULL ||unlikely (req->actual ==0 )) { +u64 aio_ret; +kfree (req->buf);kfree (priv->to_free);kfree (priv); iocb->private =NULL ;/* aio_complete() reports bytes-transferred _and_ faults */ - - iocb->ki_complete (iocb, - req->actual ? req->actual : (long )req->status); + aio_ret = req->actual ? req->actual : (long )req->status; + aio_ret |= (u64 ) req->status <<32 ; + iocb->ki_complete (iocb, aio_ret); }else {/* ep_copy_to_user() won't report both; we hide some faults */ if (unlikely (0 != req->status))
fs/aio.c +3 -3
@@ -1417,7 +1417,7 @@ static void aio_remove_iocb(struct aio_kiocb *iocb)spin_unlock_irqrestore (&ctx->ctx_lock, flags); } -static void aio_complete_rw (struct kiocb *kiocb,long res) +static void aio_complete_rw (struct kiocb *kiocb,u64 res) { struct aio_kiocb *iocb = container_of(kiocb, struct aio_kiocb, rw);
@@ -1436,8 +1436,8 @@ static void aio_complete_rw(struct kiocb *kiocb, long res)file_end_write (kiocb->ki_filp); } - iocb->ki_res.res = res; - iocb->ki_res.res2 =0 ; + iocb->ki_res.res = res &0xffffffff ; + iocb->ki_res.res2 = res >>32 ;iocb_put (iocb); }
fs/cachefiles/io.c +4 -4
@@ -37,11 +37,11 @@ static inline void cachefiles_put_kiocb(struct cachefiles_kiocb *ki)/* * Handle completion of a read from the cache. */ -static void cachefiles_read_complete (struct kiocb *iocb,long ret) +static void cachefiles_read_complete (struct kiocb *iocb,u64 ret) { struct cachefiles_kiocb *ki = container_of(iocb, struct cachefiles_kiocb, iocb); -_enter ("%ld" , ret); +_enter ("%llu" , (unsigned long long ) ret);if (ki->term_func) {if (ret >=0 )
@@ -159,12 +159,12 @@ static int cachefiles_read(struct netfs_cache_resources *cres,/* * Handle completion of a write to the cache. */ -static void cachefiles_write_complete (struct kiocb *iocb,long ret) +static void cachefiles_write_complete (struct kiocb *iocb,u64 ret) { struct cachefiles_kiocb *ki = container_of(iocb, struct cachefiles_kiocb, iocb);struct inode *inode =file_inode (ki->iocb.ki_filp); -_enter ("%ld" , ret); +_enter ("%llu" , (unsigned long long ) ret);/* Tell lockdep we inherited freeze protection from submission thread */ __sb_writers_acquired (inode->i_sb,SB_FREEZE_WRITE );
fs/io_uring.c +2 -2
@@ -2672,7 +2672,7 @@ static void __io_complete_rw(struct io_kiocb *req, long res, long res2,__io_req_complete (req, issue_flags, req->result,io_put_rw_kbuf (req)); } -static void io_complete_rw (struct kiocb *kiocb,long res) +static void io_complete_rw (struct kiocb *kiocb,u64 res) { struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
@@ -2683,7 +2683,7 @@ static void io_complete_rw(struct kiocb *kiocb, long res)io_req_task_work_add (req); } -static void io_complete_rw_iopoll (struct kiocb *kiocb,long res) +static void io_complete_rw_iopoll (struct kiocb *kiocb,u64 res) { struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
fs/overlayfs/file.c +1 -1
@@ -272,7 +272,7 @@ static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req)kmem_cache_free (ovl_aio_request_cachep, aio_req); } -static void ovl_aio_rw_complete (struct kiocb *iocb,long res) +static void ovl_aio_rw_complete (struct kiocb *iocb,u64 res) {struct ovl_aio_req *aio_req =container_of (iocb, struct ovl_aio_req, iocb);
include/linux/fs.h +1 -1
@@ -330,7 +330,7 @@ struct kiocb {randomized_struct_fields_start loff_t ki_pos; -void (*ki_complete)(struct kiocb *iocb,long ret); +void (*ki_complete)(struct kiocb *iocb,u64 ret);void *private;int ki_flags;u16 ki_hint;
Signature · 1 line
Jens Axboe
Quoted 10 lines · Jens Axboe
Quoted 3 lines · Jens Axboe
Working on just changing it to a 64-bit type instead, then we can pass in both at once with res2 being the upper 32 bits. That'll keep the same API on the aio side.
Here's that as an incremental. Since we can only be passing in 32-bits anyway across 32/64-bit, we can just make it an explicit 64-bit instead. This generates the same code on 64-bit for calling ->ki_complete, and we can trivially ignore the usb gadget issue as we now can pass in both values (and fill them in on the aio side).
Yeah, I think that should work.
Cheers,
Jeff
Quoted 191 lines
drivers/block/loop.c +1
-1@@ -550,7 +550,7 @@ static void lo_rw_aio_do_completion(struct loop_cmd *cmd)blk_mq_complete_request (rq); } -static void lo_rw_aio_complete (struct kiocb *iocb,long ret) +static void lo_rw_aio_complete (struct kiocb *iocb,u64 ret) { struct loop_cmd *cmd = container_of(iocb, struct loop_cmd, iocb);drivers/nvme/target/io-cmd-file.c +1
-1@@ -123,7 +123,7 @@ static ssize_t nvmet_file_submit_bvec(struct nvmet_req *req, loff_t pos,return call_iter (iocb, &iter); } -static void nvmet_file_io_done (struct kiocb *iocb,long ret) +static void nvmet_file_io_done (struct kiocb *iocb,u64 ret) { struct nvmet_req *req = container_of(iocb, struct nvmet_req, f.iocb);u16 status =NVME_SC_SUCCESS ;drivers/target/target_core_file.c +1
-1@@ -245,7 +245,7 @@ struct target_core_file_cmd {struct bio_vec bvecs[]; }; -static void cmd_rw_aio_complete (struct kiocb *iocb,long ret) +static void cmd_rw_aio_complete (struct kiocb *iocb,u64 ret) {struct target_core_file_cmd *cmd;drivers/usb/gadget/function/f_fs.c +1
-1@@ -831,7 +831,7 @@ static void ffs_user_copy_worker(struct work_struct *work)kthread_unuse_mm (io_data->mm); } - io_data->kiocb->ki_complete (io_data->kiocb, ret); + io_data->kiocb->ki_complete (io_data->kiocb, ((u64 ) ret <<32 ) | ret);if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd)eventfd_signal (io_data->ffs->ffs_eventfd,1 );drivers/usb/gadget/legacy/inode.c +6
-4@@ -469,7 +469,7 @@ static void ep_user_copy_worker(struct work_struct *work) ret = -EFAULT ;/* completing the iocb can drop the ctx and mm, don't touch mm after */ - iocb->ki_complete (iocb, ret); + iocb->ki_complete (iocb, ((u64 ) ret <<32 ) | ret);kfree (priv->buf);kfree (priv->to_free);@@ -492,14 +492,16 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)* complete the aio request immediately. */ if (priv->to_free ==NULL ||unlikely (req->actual ==0 )) { +u64 aio_ret; +kfree (req->buf);kfree (priv->to_free);kfree (priv); iocb->private =NULL ;/* aio_complete() reports bytes-transferred _and_ faults */ - - iocb->ki_complete (iocb, - req->actual ? req->actual : (long )req->status); + aio_ret = req->actual ? req->actual : (long )req->status; + aio_ret |= (u64 ) req->status <<32 ; + iocb->ki_complete (iocb, aio_ret); }else {/* ep_copy_to_user() won't report both; we hide some faults */ if (unlikely (0 != req->status))fs/aio.c +3
-3@@ -1417,7 +1417,7 @@ static void aio_remove_iocb(struct aio_kiocb *iocb)spin_unlock_irqrestore (&ctx->ctx_lock, flags); } -static void aio_complete_rw (struct kiocb *kiocb,long res) +static void aio_complete_rw (struct kiocb *kiocb,u64 res) { struct aio_kiocb *iocb = container_of(kiocb, struct aio_kiocb, rw);@@ -1436,8 +1436,8 @@ static void aio_complete_rw(struct kiocb *kiocb, long res)file_end_write (kiocb->ki_filp); } - iocb->ki_res.res = res; - iocb->ki_res.res2 =0 ; + iocb->ki_res.res = res &0xffffffff ; + iocb->ki_res.res2 = res >>32 ;iocb_put (iocb); }fs/cachefiles/io.c +4
-4@@ -37,11 +37,11 @@ static inline void cachefiles_put_kiocb(struct cachefiles_kiocb *ki)/* * Handle completion of a read from the cache. */ -static void cachefiles_read_complete (struct kiocb *iocb,long ret) +static void cachefiles_read_complete (struct kiocb *iocb,u64 ret) { struct cachefiles_kiocb *ki = container_of(iocb, struct cachefiles_kiocb, iocb); -_enter ("%ld" , ret); +_enter ("%llu" , (unsigned long long ) ret);if (ki->term_func) {if (ret >=0 )@@ -159,12 +159,12 @@ static int cachefiles_read(struct netfs_cache_resources *cres,/* * Handle completion of a write to the cache. */ -static void cachefiles_write_complete (struct kiocb *iocb,long ret) +static void cachefiles_write_complete (struct kiocb *iocb,u64 ret) { struct cachefiles_kiocb *ki = container_of(iocb, struct cachefiles_kiocb, iocb);struct inode *inode =file_inode (ki->iocb.ki_filp); -_enter ("%ld" , ret); +_enter ("%llu" , (unsigned long long ) ret);/* Tell lockdep we inherited freeze protection from submission thread */ __sb_writers_acquired (inode->i_sb,SB_FREEZE_WRITE );fs/io_uring.c +2
-2@@ -2672,7 +2672,7 @@ static void __io_complete_rw(struct io_kiocb *req, long res, long res2,__io_req_complete (req, issue_flags, req->result,io_put_rw_kbuf (req)); } -static void io_complete_rw (struct kiocb *kiocb,long res) +static void io_complete_rw (struct kiocb *kiocb,u64 res) { struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);@@ -2683,7 +2683,7 @@ static void io_complete_rw(struct kiocb *kiocb, long res)io_req_task_work_add (req); } -static void io_complete_rw_iopoll (struct kiocb *kiocb,long res) +static void io_complete_rw_iopoll (struct kiocb *kiocb,u64 res) { struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);fs/overlayfs/file.c +1
-1@@ -272,7 +272,7 @@ static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req)kmem_cache_free (ovl_aio_request_cachep, aio_req); } -static void ovl_aio_rw_complete (struct kiocb *iocb,long res) +static void ovl_aio_rw_complete (struct kiocb *iocb,u64 res) {struct ovl_aio_req *aio_req =container_of (iocb, struct ovl_aio_req, iocb);include/linux/fs.h +1
-1@@ -330,7 +330,7 @@ struct kiocb {randomized_struct_fields_start loff_t ki_pos; -void (*ki_complete)(struct kiocb *iocb,long ret); +void (*ki_complete)(struct kiocb *iocb,u64 ret);void *private;int ki_flags;u16 ki_hint;
Jens Axboe
maintainerQuoted 7 lines · Jeff Moyer
Quoted 5 lines · Jens Axboe
Quoted 3 lines · Jens Axboe
Working on just changing it to a 64-bit type instead, then we can pass in both at once with res2 being the upper 32 bits. That'll keep the same API on the aio side.
Quoted 7 lines
Quoted 5 lines
Here's that as an incremental. Since we can only be passing in 32-bits anyway across 32/64-bit, we can just make it an explicit 64-bit instead. This generates the same code on 64-bit for calling ->ki_complete, and we can trivially ignore the usb gadget issue as we now can pass in both values (and fill them in on the aio side).
Yeah, I think that should work.
Passed test and allmodconfig sanity check, sent out as v2 :)
Signature · 1 line
Jens Axboe
Quoted 14 lines · Jens Axboe
Quoted 13 lines · Jeff Moyer
Quoted 10 lines · Jens Axboe
Quoted 3 lines · Jens Axboe
Working on just changing it to a 64-bit type instead, then we can pass in both at once with res2 being the upper 32 bits. That'll keep the same API on the aio side.
Here's that as an incremental. Since we can only be passing in 32-bits anyway across 32/64-bit, we can just make it an explicit 64-bit instead. This generates the same code on 64-bit for calling ->ki_complete, and we can trivially ignore the usb gadget issue as we now can pass in both values (and fill them in on the aio side).
Quoted 3 lines
Quoted 1 line
Yeah, I think that should work.
Passed test and allmodconfig sanity check, sent out as v2 :)
It passed the libaio tests on x64. I'll do some more testing and review the v2 posting.
Thanks!
Jeff
Jens Axboe
maintainerQuoted 16 lines · Jeff Moyer
Quoted 14 lines · Jens Axboe
Quoted 13 lines · Jeff Moyer
Quoted 10 lines · Jens Axboe
Quoted 3 lines · Jens Axboe
Working on just changing it to a 64-bit type instead, then we can pass in both at once with res2 being the upper 32 bits. That'll keep the same API on the aio side.
Here's that as an incremental. Since we can only be passing in 32-bits anyway across 32/64-bit, we can just make it an explicit 64-bit instead. This generates the same code on 64-bit for calling ->ki_complete, and we can trivially ignore the usb gadget issue as we now can pass in both values (and fill them in on the aio side).
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Yeah, I think that should work.
Passed test and allmodconfig sanity check, sent out as v2 :)
It passed the libaio tests on x64. I'll do some more testing and review the v2 posting.
Thanks Jeff!
Signature · 1 line
Jens Axboe