History

io_uring: overflow processing for CQE32

This adds the overflow processing for large CQE's. This adds two parameters to the io_cqring_event_overflow function and uses these fields to initialize the large CQE fields. Allocate enough space for large CQE's in the overflow structue. If no large CQE's are used, the size of the allocation is unchanged. The cqe field can have a different size depending if its a large CQE or not. To be able to allocate different sizes, the two fields in the structure are re-ordered.

Stefan Roesch committed 4 years ago

Commit e45a3e01 parent 0e2e5c41 file · +23 −9Browse files

Unified · Split

fs/io_uring.c+23−9
@@ -220,8 +220,8 @@ struct io_mapped_ubuf { · 219 unmodified lines
220220 struct io_ring_ctx;
221221
222222 struct io_overflow_cqe {
223− struct io_uring_cqe cqe;
224223 struct list_head list;
224+ struct io_uring_cqe cqe;
225225 };
226226
227227 /*
@@ -2177,10 +2177,14 @@ static void io_cqring_ev_posted_iopoll(struct io_ring_ctx *ctx) · 1949 unmodified lines
21772177 static bool __io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force)
21782178 {
21792179 bool all_flushed, posted;
2180+ size_t cqe_size = sizeof(struct io_uring_cqe);
21802181
21812182 if (!force && __io_cqring_events(ctx) == ctx->cq_entries)
21822183 return false;
21832184
2185+ if (ctx->flags & IORING_SETUP_CQE32)
2186+ cqe_size <<= 1;
2187+
21842188 posted = false;
21852189 spin_lock(&ctx->completion_lock);
21862190 while (!list_empty(&ctx->cq_overflow_list)) {
@@ -2192,7 +2196,7 @@ static bool __io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force) · 5 unmodified lines
21922196 ocqe = list_first_entry(&ctx->cq_overflow_list,
21932197 struct io_overflow_cqe, list);
21942198 if (cqe)
2195− memcpy(cqe, &ocqe->cqe, sizeof(*cqe));
2199+ memcpy(cqe, &ocqe->cqe, cqe_size);
21962200 else
21972201 io_account_cq_overflow(ctx);
21982202
@@ -2280,11 +2284,17 @@ static __cold void io_uring_drop_tctx_refs(struct task_struct *task) · 81 unmodified lines
22802284 }
22812285
22822286 static bool io_cqring_event_overflow(struct io_ring_ctx *ctx, u64 user_data,
2283− s32 res, u32 cflags)
2287+ s32 res, u32 cflags, u64 extra1,
2288+ u64 extra2)
22842289 {
22852290 struct io_overflow_cqe *ocqe;
2291+ size_t ocq_size = sizeof(struct io_overflow_cqe);
2292+ bool is_cqe32 = (ctx->flags & IORING_SETUP_CQE32);
2293+
2294+ if (is_cqe32)
2295+ ocq_size += sizeof(struct io_uring_cqe);
22862296
2287− ocqe = kmalloc(sizeof(*ocqe), GFP_ATOMIC | __GFP_ACCOUNT);
2297+ ocqe = kmalloc(ocq_size, GFP_ATOMIC | __GFP_ACCOUNT);
22882298 trace_io_uring_cqe_overflow(ctx, user_data, res, cflags, ocqe);
22892299 if (!ocqe) {
22902300 /*
@@ -2304,6 +2314,10 @@ static bool io_cqring_event_overflow(struct io_ring_ctx *ctx, u64 user_data, · 13 unmodified lines
23042314 ocqe->cqe.user_data = user_data;
23052315 ocqe->cqe.res = res;
23062316 ocqe->cqe.flags = cflags;
2317+ if (is_cqe32) {
2318+ ocqe->cqe.big_cqe[0] = extra1;
2319+ ocqe->cqe.big_cqe[1] = extra2;
2320+ }
23072321 list_add_tail(&ocqe->list, &ctx->cq_overflow_list);
23082322 return true;
23092323 }
@@ -2325,7 +2339,7 @@ static inline bool __io_fill_cqe(struct io_ring_ctx *ctx, u64 user_data, · 15 unmodified lines
23252339 WRITE_ONCE(cqe->flags, cflags);
23262340 return true;
23272341 }
2328− return io_cqring_event_overflow(ctx, user_data, res, cflags);
2342+ return io_cqring_event_overflow(ctx, user_data, res, cflags, 0, 0);
23292343 }
23302344
23312345 static inline bool __io_fill_cqe_req_filled(struct io_ring_ctx *ctx,
@@ -2347,7 +2361,7 @@ static inline bool __io_fill_cqe_req_filled(struct io_ring_ctx *ctx, · 15 unmodified lines
23472361 return true;
23482362 }
23492363 return io_cqring_event_overflow(ctx, req->cqe.user_data,
2350− req->cqe.res, req->cqe.flags);
2364+ req->cqe.res, req->cqe.flags, 0, 0);
23512365 }
23522366
23532367 static inline bool __io_fill_cqe32_req_filled(struct io_ring_ctx *ctx,
@@ -2373,8 +2387,8 @@ static inline bool __io_fill_cqe32_req_filled(struct io_ring_ctx *ctx, · 19 unmodified lines
23732387 return true;
23742388 }
23752389
2376− return io_cqring_event_overflow(ctx, req->cqe.user_data,
2377− req->cqe.res, req->cqe.flags);
2390+ return io_cqring_event_overflow(ctx, req->cqe.user_data, req->cqe.res,
2391+ req->cqe.flags, extra1, extra2);
23782392 }
23792393
23802394 static inline bool __io_fill_cqe_req(struct io_kiocb *req, s32 res, u32 cflags)
@@ -2411,7 +2425,7 @@ static inline void __io_fill_cqe32_req(struct io_kiocb *req, s32 res, u32 cflags · 30 unmodified lines
24112425 return;
24122426 }
24132427
2414− io_cqring_event_overflow(ctx, req->cqe.user_data, res, cflags);
2428+ io_cqring_event_overflow(ctx, req->cqe.user_data, res, cflags, extra1, extra2);
24152429 }
24162430
24172431 static noinline bool io_fill_cqe_aux(struct io_ring_ctx *ctx, u64 user_data,