Skip to contentSkip to conversation

fs: kill unused ret2 argument from iocb->ki_complete()

PATCH In review Jens Axboe 5 participants 18 messages Oct 20, 2021 – Oct 23, 2021

Subsystems (13)
VFS USB Block layer NFS client +9 more subsystems
lore
Share & tools
lore

Jens Axboe

author maintainer
#0 lore raw

PATCH 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
index d7eff331a07c..53408271771a 100644
@@ -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
index 8bd288d2b089..3dd5a773c320 100644
@@ -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
index 397bfafc4c25..92b87aa8be86 100644
@@ -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
index 7a249b752f3c..80a0f35ae1dc 100644
@@ -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
index b471e726bb3d..968ace2ddf64 100644
@@ -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
index 8260f38025b7..e20c19a0f106 100644
@@ -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
index 539220d7f5b6..ad1739dbfab9 100644
@@ -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
index 51b08ab01dff..836dc7e48db7 100644
@@ -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
index fac2e8e7b533..effe37ef8629 100644
@@ -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
index 5c1954ff3a82..41f4ca038191 100644
@@ -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
index 13f3182cf796..1b855fcb179e 100644
@@ -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
index 453dcff0e7f5..654443558047 100644
@@ -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
index 11404f8c21c7..e6039f22311b 100644
@@ -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
index 5edde3b2f72d..5ad046145f29 100644
@@ -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
index 83ecfba53abe..811c898125a5 100644
@@ -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
index 2e894fec036b..7a5f287c5391 100644
@@ -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
index c88ac571593d..ac461a499882 100644
@@ -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
index 31029a91f440..0dcb9020a7b3 100644
@@ -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
#1 lore raw
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_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.

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.

author maintainer
#2 lore raw
Quoted 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_complete users 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
#3 lore raw
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_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.

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

#4 lore raw
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_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.

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.

[1] https://github.com/aosp-mirror/platform_system_core/blob/34a0e57a257f0081c672c9be0e87230762e677ca/adb/daemon/usb.cpp#L527

author maintainer
#5 lore raw
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_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.

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::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.

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
author maintainer
#6 lore raw
In reply to John Keeping
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_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.

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::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.

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
#7 lore raw
Quoted 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_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.

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::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.

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

author maintainer
#8 lore raw
Quoted 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_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.

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::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.

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
#9 lore raw
In reply to 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_complete users 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 -2
 		iocb->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.

author maintainer
#10 lore raw
Quoted 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_complete users 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 -2
 		iocb->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
#11 lore raw
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_complete users 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

author maintainer
#12 lore raw
Quoted 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_complete users 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
author maintainer
#13 lore raw
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).

drivers/block/loop.c +1 -1
index 92b87aa8be86..66c6e0c5d638 100644
@@ -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
index 80a0f35ae1dc..83a2f5b0a3a0 100644
@@ -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
index 968ace2ddf64..c4ca7fa18e61 100644
@@ -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
index e20c19a0f106..8536f19d3c9a 100644
@@ -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
index ad1739dbfab9..d3deb23eb2ab 100644
@@ -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
index 836dc7e48db7..e39c61dccf37 100644
@@ -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
index effe37ef8629..b2f44ff8eae2 100644
@@ -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
index 5ad046145f29..0ed6c199f394 100644
@@ -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
index ac461a499882..ff7db16aea2e 100644
@@ -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
index 0dcb9020a7b3..3c809ce2518c 100644
@@ -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
#14 lore raw
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
index 92b87aa8be86..66c6e0c5d638 100644
@@ -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
index 80a0f35ae1dc..83a2f5b0a3a0 100644
@@ -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
index 968ace2ddf64..c4ca7fa18e61 100644
@@ -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
index e20c19a0f106..8536f19d3c9a 100644
@@ -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
index ad1739dbfab9..d3deb23eb2ab 100644
@@ -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
index 836dc7e48db7..e39c61dccf37 100644
@@ -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
index effe37ef8629..b2f44ff8eae2 100644
@@ -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
index 5ad046145f29..0ed6c199f394 100644
@@ -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
index ac461a499882..ff7db16aea2e 100644
@@ -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
index 0dcb9020a7b3..3c809ce2518c 100644
@@ -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;
author maintainer
#15 lore raw
Quoted 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
#16 lore raw
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

author maintainer
#17 lore raw
Quoted 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