aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/bfq-iosched.c8
-rw-r--r--block/blk-mq.c2
-rw-r--r--fs/io_uring.c41
-rw-r--r--include/linux/blkdev.h1
-rw-r--r--include/linux/bvec.h5
-rw-r--r--include/linux/elevator.h1
6 files changed, 43 insertions, 15 deletions
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index dfb8cb0af13a..5ba1e0d841b4 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -5396,7 +5396,7 @@ static unsigned int bfq_update_depths(struct bfq_data *bfqd,
5396 return min_shallow; 5396 return min_shallow;
5397} 5397}
5398 5398
5399static int bfq_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int index) 5399static void bfq_depth_updated(struct blk_mq_hw_ctx *hctx)
5400{ 5400{
5401 struct bfq_data *bfqd = hctx->queue->elevator->elevator_data; 5401 struct bfq_data *bfqd = hctx->queue->elevator->elevator_data;
5402 struct blk_mq_tags *tags = hctx->sched_tags; 5402 struct blk_mq_tags *tags = hctx->sched_tags;
@@ -5404,6 +5404,11 @@ static int bfq_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int index)
5404 5404
5405 min_shallow = bfq_update_depths(bfqd, &tags->bitmap_tags); 5405 min_shallow = bfq_update_depths(bfqd, &tags->bitmap_tags);
5406 sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, min_shallow); 5406 sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, min_shallow);
5407}
5408
5409static int bfq_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int index)
5410{
5411 bfq_depth_updated(hctx);
5407 return 0; 5412 return 0;
5408} 5413}
5409 5414
@@ -5826,6 +5831,7 @@ static struct elevator_type iosched_bfq_mq = {
5826 .requests_merged = bfq_requests_merged, 5831 .requests_merged = bfq_requests_merged,
5827 .request_merged = bfq_request_merged, 5832 .request_merged = bfq_request_merged,
5828 .has_work = bfq_has_work, 5833 .has_work = bfq_has_work,
5834 .depth_updated = bfq_depth_updated,
5829 .init_hctx = bfq_init_hctx, 5835 .init_hctx = bfq_init_hctx,
5830 .init_sched = bfq_init_queue, 5836 .init_sched = bfq_init_queue,
5831 .exit_sched = bfq_exit_queue, 5837 .exit_sched = bfq_exit_queue,
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 9516304a38ee..fc60ed7e940e 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -3135,6 +3135,8 @@ int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr)
3135 } 3135 }
3136 if (ret) 3136 if (ret)
3137 break; 3137 break;
3138 if (q->elevator && q->elevator->type->ops.depth_updated)
3139 q->elevator->type->ops.depth_updated(hctx);
3138 } 3140 }
3139 3141
3140 if (!ret) 3142 if (!ret)
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 89aa8412b5f5..f65f85d89217 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -338,7 +338,7 @@ static struct io_uring_cqe *io_get_cqring(struct io_ring_ctx *ctx)
338 tail = ctx->cached_cq_tail; 338 tail = ctx->cached_cq_tail;
339 /* See comment at the top of the file */ 339 /* See comment at the top of the file */
340 smp_rmb(); 340 smp_rmb();
341 if (tail + 1 == READ_ONCE(ring->r.head)) 341 if (tail - READ_ONCE(ring->r.head) == ring->ring_entries)
342 return NULL; 342 return NULL;
343 343
344 ctx->cached_cq_tail++; 344 ctx->cached_cq_tail++;
@@ -682,11 +682,9 @@ static void io_iopoll_req_issued(struct io_kiocb *req)
682 list_add_tail(&req->list, &ctx->poll_list); 682 list_add_tail(&req->list, &ctx->poll_list);
683} 683}
684 684
685static void io_file_put(struct io_submit_state *state, struct file *file) 685static void io_file_put(struct io_submit_state *state)
686{ 686{
687 if (!state) { 687 if (state->file) {
688 fput(file);
689 } else if (state->file) {
690 int diff = state->has_refs - state->used_refs; 688 int diff = state->has_refs - state->used_refs;
691 689
692 if (diff) 690 if (diff)
@@ -711,7 +709,7 @@ static struct file *io_file_get(struct io_submit_state *state, int fd)
711 state->ios_left--; 709 state->ios_left--;
712 return state->file; 710 return state->file;
713 } 711 }
714 io_file_put(state, NULL); 712 io_file_put(state);
715 } 713 }
716 state->file = fget_many(fd, state->ios_left); 714 state->file = fget_many(fd, state->ios_left);
717 if (!state->file) 715 if (!state->file)
@@ -1671,7 +1669,7 @@ out:
1671static void io_submit_state_end(struct io_submit_state *state) 1669static void io_submit_state_end(struct io_submit_state *state)
1672{ 1670{
1673 blk_finish_plug(&state->plug); 1671 blk_finish_plug(&state->plug);
1674 io_file_put(state, NULL); 1672 io_file_put(state);
1675 if (state->free_reqs) 1673 if (state->free_reqs)
1676 kmem_cache_free_bulk(req_cachep, state->free_reqs, 1674 kmem_cache_free_bulk(req_cachep, state->free_reqs,
1677 &state->reqs[state->cur_req]); 1675 &state->reqs[state->cur_req]);
@@ -1920,6 +1918,10 @@ static int io_sq_thread(void *data)
1920 unuse_mm(cur_mm); 1918 unuse_mm(cur_mm);
1921 mmput(cur_mm); 1919 mmput(cur_mm);
1922 } 1920 }
1921
1922 if (kthread_should_park())
1923 kthread_parkme();
1924
1923 return 0; 1925 return 0;
1924} 1926}
1925 1927
@@ -2054,6 +2056,7 @@ static void io_sq_thread_stop(struct io_ring_ctx *ctx)
2054 if (ctx->sqo_thread) { 2056 if (ctx->sqo_thread) {
2055 ctx->sqo_stop = 1; 2057 ctx->sqo_stop = 1;
2056 mb(); 2058 mb();
2059 kthread_park(ctx->sqo_thread);
2057 kthread_stop(ctx->sqo_thread); 2060 kthread_stop(ctx->sqo_thread);
2058 ctx->sqo_thread = NULL; 2061 ctx->sqo_thread = NULL;
2059 } 2062 }
@@ -2236,10 +2239,6 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx,
2236 mmgrab(current->mm); 2239 mmgrab(current->mm);
2237 ctx->sqo_mm = current->mm; 2240 ctx->sqo_mm = current->mm;
2238 2241
2239 ctx->sq_thread_idle = msecs_to_jiffies(p->sq_thread_idle);
2240 if (!ctx->sq_thread_idle)
2241 ctx->sq_thread_idle = HZ;
2242
2243 ret = -EINVAL; 2242 ret = -EINVAL;
2244 if (!cpu_possible(p->sq_thread_cpu)) 2243 if (!cpu_possible(p->sq_thread_cpu))
2245 goto err; 2244 goto err;
@@ -2249,10 +2248,18 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx,
2249 if (!capable(CAP_SYS_ADMIN)) 2248 if (!capable(CAP_SYS_ADMIN))
2250 goto err; 2249 goto err;
2251 2250
2251 ctx->sq_thread_idle = msecs_to_jiffies(p->sq_thread_idle);
2252 if (!ctx->sq_thread_idle)
2253 ctx->sq_thread_idle = HZ;
2254
2252 if (p->flags & IORING_SETUP_SQ_AFF) { 2255 if (p->flags & IORING_SETUP_SQ_AFF) {
2253 int cpu; 2256 int cpu;
2254 2257
2255 cpu = array_index_nospec(p->sq_thread_cpu, NR_CPUS); 2258 cpu = array_index_nospec(p->sq_thread_cpu, NR_CPUS);
2259 ret = -EINVAL;
2260 if (!cpu_possible(p->sq_thread_cpu))
2261 goto err;
2262
2256 ctx->sqo_thread = kthread_create_on_cpu(io_sq_thread, 2263 ctx->sqo_thread = kthread_create_on_cpu(io_sq_thread,
2257 ctx, cpu, 2264 ctx, cpu,
2258 "io_uring-sq"); 2265 "io_uring-sq");
@@ -2922,11 +2929,23 @@ SYSCALL_DEFINE2(io_uring_setup, u32, entries,
2922 2929
2923static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode, 2930static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
2924 void __user *arg, unsigned nr_args) 2931 void __user *arg, unsigned nr_args)
2932 __releases(ctx->uring_lock)
2933 __acquires(ctx->uring_lock)
2925{ 2934{
2926 int ret; 2935 int ret;
2927 2936
2928 percpu_ref_kill(&ctx->refs); 2937 percpu_ref_kill(&ctx->refs);
2938
2939 /*
2940 * Drop uring mutex before waiting for references to exit. If another
2941 * thread is currently inside io_uring_enter() it might need to grab
2942 * the uring_lock to make progress. If we hold it here across the drain
2943 * wait, then we can deadlock. It's safe to drop the mutex here, since
2944 * no new references will come in after we've killed the percpu ref.
2945 */
2946 mutex_unlock(&ctx->uring_lock);
2929 wait_for_completion(&ctx->ctx_done); 2947 wait_for_completion(&ctx->ctx_done);
2948 mutex_lock(&ctx->uring_lock);
2930 2949
2931 switch (opcode) { 2950 switch (opcode) {
2932 case IORING_REGISTER_BUFFERS: 2951 case IORING_REGISTER_BUFFERS:
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 5c58a3b2bf00..317ab30d2904 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -548,7 +548,6 @@ struct request_queue {
548 struct rcu_head rcu_head; 548 struct rcu_head rcu_head;
549 wait_queue_head_t mq_freeze_wq; 549 wait_queue_head_t mq_freeze_wq;
550 struct percpu_ref q_usage_counter; 550 struct percpu_ref q_usage_counter;
551 struct list_head all_q_node;
552 551
553 struct blk_mq_tag_set *tag_set; 552 struct blk_mq_tag_set *tag_set;
554 struct list_head tag_set_list; 553 struct list_head tag_set_list;
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index 3bc91879e1e2..ff13cbc1887d 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -160,8 +160,9 @@ static inline void bvec_advance(const struct bio_vec *bvec,
160 bv->bv_page = nth_page(bv->bv_page, 1); 160 bv->bv_page = nth_page(bv->bv_page, 1);
161 bv->bv_offset = 0; 161 bv->bv_offset = 0;
162 } else { 162 } else {
163 bv->bv_page = bvec->bv_page; 163 bv->bv_page = bvec_nth_page(bvec->bv_page, bvec->bv_offset /
164 bv->bv_offset = bvec->bv_offset; 164 PAGE_SIZE);
165 bv->bv_offset = bvec->bv_offset & ~PAGE_MASK;
165 } 166 }
166 bv->bv_len = min_t(unsigned int, PAGE_SIZE - bv->bv_offset, 167 bv->bv_len = min_t(unsigned int, PAGE_SIZE - bv->bv_offset,
167 bvec->bv_len - iter_all->done); 168 bvec->bv_len - iter_all->done);
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 2e9e2763bf47..6e8bc53740f0 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -31,6 +31,7 @@ struct elevator_mq_ops {
31 void (*exit_sched)(struct elevator_queue *); 31 void (*exit_sched)(struct elevator_queue *);
32 int (*init_hctx)(struct blk_mq_hw_ctx *, unsigned int); 32 int (*init_hctx)(struct blk_mq_hw_ctx *, unsigned int);
33 void (*exit_hctx)(struct blk_mq_hw_ctx *, unsigned int); 33 void (*exit_hctx)(struct blk_mq_hw_ctx *, unsigned int);
34 void (*depth_updated)(struct blk_mq_hw_ctx *);
34 35
35 bool (*allow_merge)(struct request_queue *, struct request *, struct bio *); 36 bool (*allow_merge)(struct request_queue *, struct request *, struct bio *);
36 bool (*bio_merge)(struct blk_mq_hw_ctx *, struct bio *); 37 bool (*bio_merge)(struct blk_mq_hw_ctx *, struct bio *);