History

io_uring: Fix mm_fault with READ/WRITE_FIXED

Commit fb5ccc98782f ("io_uring: Fix broken links with offloading") introduced a potential performance regression with unconditionally taking mm even for READ/WRITE_FIXED operations. Return the logic handling it back. mm-faulted requests will go through the generic submission path, so honoring links and drains, but will fail further on req->has_user check.

Pavel Begunkov committed 7 years ago

Commit 95a1b3f1 parent fa456221 file · +17 −24Browse files

Unified · Split

fs/io_uring.c+17−24
@@ -2726,13 +2726,14 @@ static bool io_get_sqring(struct io_ring_ctx *ctx, struct sqe_submit *s) · 2725 unmodified lines
27262726 }
27272727
27282728 static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr,
2729− bool has_user, bool mm_fault)
2729+ struct mm_struct **mm)
27302730 {
27312731 struct io_submit_state state, *statep = NULL;
27322732 struct io_kiocb *link = NULL;
27332733 struct io_kiocb *shadow_req = NULL;
27342734 bool prev_was_link = false;
27352735 int i, submitted = 0;
2736+ bool mm_fault = false;
27362737
27372738 if (nr > IO_PLUG_THRESHOLD) {
27382739 io_submit_state_start(&state, ctx, nr);
@@ -2745,6 +2746,14 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr, · 6 unmodified lines
27452746 if (!io_get_sqring(ctx, &s))
27462747 break;
27472748
2749+ if (io_sqe_needs_user(s.sqe) && !*mm) {
2750+ mm_fault = mm_fault || !mmget_not_zero(ctx->sqo_mm);
2751+ if (!mm_fault) {
2752+ use_mm(ctx->sqo_mm);
2753+ *mm = ctx->sqo_mm;
2754+ }
2755+ }
2756+
27482757 /*
27492758 * If previous wasn't linked and we have a linked command,
27502759 * that's the end of the chain. Submit the previous link.
@@ -2768,17 +2777,12 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr, · 17 unmodified lines
27682777 }
27692778
27702779 out:
2771− if (unlikely(mm_fault)) {
2772− io_cqring_add_event(ctx, s.sqe->user_data,
2773− -EFAULT);
2774− } else {
2775− s.has_user = has_user;
2776− s.in_async = true;
2777− s.needs_fixed_file = true;
2778− trace_io_uring_submit_sqe(ctx, true, true);
2779− io_submit_sqe(ctx, &s, statep, &link);
2780− submitted++;
2781− }
2780+ s.has_user = *mm != NULL;
2781+ s.in_async = true;
2782+ s.needs_fixed_file = true;
2783+ trace_io_uring_submit_sqe(ctx, true, true);
2784+ io_submit_sqe(ctx, &s, statep, &link);
2785+ submitted++;
27822786 }
27832787
27842788 if (link)
@@ -2805,7 +2809,6 @@ static int io_sq_thread(void *data) · 20 unmodified lines
28052809
28062810 timeout = inflight = 0;
28072811 while (!kthread_should_park()) {
2808− bool mm_fault = false;
28092812 unsigned int to_submit;
28102813
28112814 if (inflight) {
@@ -2890,18 +2893,8 @@ static int io_sq_thread(void *data) · 78 unmodified lines
28902893 ctx->rings->sq_flags &= ~IORING_SQ_NEED_WAKEUP;
28912894 }
28922895
2893− /* Unless all new commands are FIXED regions, grab mm */
2894− if (!cur_mm) {
2895− mm_fault = !mmget_not_zero(ctx->sqo_mm);
2896− if (!mm_fault) {
2897− use_mm(ctx->sqo_mm);
2898− cur_mm = ctx->sqo_mm;
2899− }
2900− }
2901−
29022896 to_submit = min(to_submit, ctx->sq_entries);
2903− inflight += io_submit_sqes(ctx, to_submit, cur_mm != NULL,
2904− mm_fault);
2897+ inflight += io_submit_sqes(ctx, to_submit, &cur_mm);
29052898
29062899 /* Commit SQ ring head once we've consumed all SQEs */
29072900 io_commit_sqring(ctx);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t