diff mbox series

io_uring: add separate freeptr type for slab

Message ID fe73d557-8c4f-4ad7-88c3-92a598efe4e5@kernel.dk (mailing list archive)
State New
Headers show
Series io_uring: add separate freeptr type for slab | expand

Commit Message

Jens Axboe Nov. 20, 2024, 2:05 a.m. UTC
io_uring: add separate freeptr type for slab

A previous commit used io_kiocb->work as the free pointer space. Which
is completely fine, but apparently m68k does odd alignment and the
struct ends up being 2-byte aligned rather than 4-byte aligned.

Add a union around io_kiocb->work, and add a specific freeptr_t type in
there to be used for slab. Mark it as needing sizeof(type) alignment, to
force m68k to do so. On anything normal, this won't change sizing or
alignment at all.

Reported-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Fixes: aaa736b18623 ("io_uring: specify freeptr usage for SLAB_TYPESAFE_BY_RCU io_kiocb cache")
Signed-off-by: Jens Axboe <axboe@kernel.dk>

---
diff mbox series

Patch

diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h
index aa5f5ea98076..91efc7e6bf3f 100644
--- a/include/linux/io_uring_types.h
+++ b/include/linux/io_uring_types.h
@@ -673,7 +673,16 @@  struct io_kiocb {
 	struct io_kiocb			*link;
 	/* custom credentials, valid IFF REQ_F_CREDS is set */
 	const struct cred		*creds;
-	struct io_wq_work		work;
+
+	/*
+	 * Use separate freeptr for slab, but overlay it with work as that
+	 * part is long done by the time the request is freed. Due to an m68k
+	 * quirk, ensure it's aligned to at least the size of the type.
+	 */
+	union {
+		struct io_wq_work	work;
+		freeptr_t		freeptr __aligned(sizeof(freeptr_t));
+	};
 
 	struct {
 		u64			extra1;
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index da8fd460977b..4bf25b9e5105 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -3813,7 +3813,7 @@  static int __init io_uring_init(void)
 	struct kmem_cache_args kmem_args = {
 		.useroffset = offsetof(struct io_kiocb, cmd.data),
 		.usersize = sizeof_field(struct io_kiocb, cmd.data),
-		.freeptr_offset = offsetof(struct io_kiocb, work),
+		.freeptr_offset = offsetof(struct io_kiocb, freeptr),
 		.use_freeptr_offset = true,
 	};