diff options
-rw-r--r-- | block/bfq-iosched.c | 8 | ||||
-rw-r--r-- | block/blk-mq.c | 2 | ||||
-rw-r--r-- | fs/io_uring.c | 41 | ||||
-rw-r--r-- | include/linux/blkdev.h | 1 | ||||
-rw-r--r-- | include/linux/bvec.h | 5 | ||||
-rw-r--r-- | include/linux/elevator.h | 1 |
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 | ||
5399 | static int bfq_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int index) | 5399 | static 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 | |||
5409 | static 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 | ||
685 | static void io_file_put(struct io_submit_state *state, struct file *file) | 685 | static 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: | |||
1671 | static void io_submit_state_end(struct io_submit_state *state) | 1669 | static 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 | ||
2923 | static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode, | 2930 | static 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 *); |