aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-16 21:49:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-16 21:49:16 -0400
commitd82312c80860b8b83cd4473ac6eafd244e712061 (patch)
tree028b2e843e9d59d35aeb8924582864f18aa4ca36 /fs/aio.c
parent7d69cff26ceadce8638cb65191285932a3de3d4c (diff)
parent889fa31f00b218a2cef96c32a6b3f57e6d3bf918 (diff)
Merge branch 'for-4.1/core' of git://git.kernel.dk/linux-block
Pull block layer core bits from Jens Axboe: "This is the core pull request for 4.1. Not a lot of stuff in here for this round, mostly little fixes or optimizations. This pull request contains: - An optimization that speeds up queue runs on blk-mq, especially for the case where there's a large difference between nr_cpu_ids and the actual mapped software queues on a hardware queue. From Chong Yuan. - Honor node local allocations for requests on legacy devices. From David Rientjes. - Cleanup of blk_mq_rq_to_pdu() from me. - exit_aio() fixup from me, greatly speeding up exiting multiple IO contexts off exit_group(). For my particular test case, fio exit took ~6 seconds. A typical case of both exposing RCU grace periods to user space, and serializing exit of them. - Make blk_mq_queue_enter() honor the gfp mask passed in, so we only wait if __GFP_WAIT is set. From Keith Busch. - blk-mq exports and two added helpers from Mike Snitzer, which will be used by the dm-mq code. - Cleanups of blk-mq queue init from Wei Fang and Xiaoguang Wang" * 'for-4.1/core' of git://git.kernel.dk/linux-block: blk-mq: reduce unnecessary software queue looping aio: fix serial draining in exit_aio() blk-mq: cleanup blk_mq_rq_to_pdu() blk-mq: put blk_queue_rq_timeout together in blk_mq_init_queue() block: remove redundant check about 'set->nr_hw_queues' in blk_mq_alloc_tag_set() block: allocate request memory local to request queue blk-mq: don't wait in blk_mq_queue_enter() if __GFP_WAIT isn't set blk-mq: export blk_mq_run_hw_queues blk-mq: add blk_mq_init_allocated_queue and export blk_mq_register_disk
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 5785c4b58fea..fa8b16f47f1a 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -77,6 +77,11 @@ struct kioctx_cpu {
77 unsigned reqs_available; 77 unsigned reqs_available;
78}; 78};
79 79
80struct ctx_rq_wait {
81 struct completion comp;
82 atomic_t count;
83};
84
80struct kioctx { 85struct kioctx {
81 struct percpu_ref users; 86 struct percpu_ref users;
82 atomic_t dead; 87 atomic_t dead;
@@ -115,7 +120,7 @@ struct kioctx {
115 /* 120 /*
116 * signals when all in-flight requests are done 121 * signals when all in-flight requests are done
117 */ 122 */
118 struct completion *requests_done; 123 struct ctx_rq_wait *rq_wait;
119 124
120 struct { 125 struct {
121 /* 126 /*
@@ -572,8 +577,8 @@ static void free_ioctx_reqs(struct percpu_ref *ref)
572 struct kioctx *ctx = container_of(ref, struct kioctx, reqs); 577 struct kioctx *ctx = container_of(ref, struct kioctx, reqs);
573 578
574 /* At this point we know that there are no any in-flight requests */ 579 /* At this point we know that there are no any in-flight requests */
575 if (ctx->requests_done) 580 if (ctx->rq_wait && atomic_dec_and_test(&ctx->rq_wait->count))
576 complete(ctx->requests_done); 581 complete(&ctx->rq_wait->comp);
577 582
578 INIT_WORK(&ctx->free_work, free_ioctx); 583 INIT_WORK(&ctx->free_work, free_ioctx);
579 schedule_work(&ctx->free_work); 584 schedule_work(&ctx->free_work);
@@ -783,7 +788,7 @@ err:
783 * the rapid destruction of the kioctx. 788 * the rapid destruction of the kioctx.
784 */ 789 */
785static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx, 790static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx,
786 struct completion *requests_done) 791 struct ctx_rq_wait *wait)
787{ 792{
788 struct kioctx_table *table; 793 struct kioctx_table *table;
789 794
@@ -813,7 +818,7 @@ static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx,
813 if (ctx->mmap_size) 818 if (ctx->mmap_size)
814 vm_munmap(ctx->mmap_base, ctx->mmap_size); 819 vm_munmap(ctx->mmap_base, ctx->mmap_size);
815 820
816 ctx->requests_done = requests_done; 821 ctx->rq_wait = wait;
817 percpu_ref_kill(&ctx->users); 822 percpu_ref_kill(&ctx->users);
818 return 0; 823 return 0;
819} 824}
@@ -829,18 +834,24 @@ static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx,
829void exit_aio(struct mm_struct *mm) 834void exit_aio(struct mm_struct *mm)
830{ 835{
831 struct kioctx_table *table = rcu_dereference_raw(mm->ioctx_table); 836 struct kioctx_table *table = rcu_dereference_raw(mm->ioctx_table);
832 int i; 837 struct ctx_rq_wait wait;
838 int i, skipped;
833 839
834 if (!table) 840 if (!table)
835 return; 841 return;
836 842
843 atomic_set(&wait.count, table->nr);
844 init_completion(&wait.comp);
845
846 skipped = 0;
837 for (i = 0; i < table->nr; ++i) { 847 for (i = 0; i < table->nr; ++i) {
838 struct kioctx *ctx = table->table[i]; 848 struct kioctx *ctx = table->table[i];
839 struct completion requests_done =
840 COMPLETION_INITIALIZER_ONSTACK(requests_done);
841 849
842 if (!ctx) 850 if (!ctx) {
851 skipped++;
843 continue; 852 continue;
853 }
854
844 /* 855 /*
845 * We don't need to bother with munmap() here - exit_mmap(mm) 856 * We don't need to bother with munmap() here - exit_mmap(mm)
846 * is coming and it'll unmap everything. And we simply can't, 857 * is coming and it'll unmap everything. And we simply can't,
@@ -849,10 +860,12 @@ void exit_aio(struct mm_struct *mm)
849 * that it needs to unmap the area, just set it to 0. 860 * that it needs to unmap the area, just set it to 0.
850 */ 861 */
851 ctx->mmap_size = 0; 862 ctx->mmap_size = 0;
852 kill_ioctx(mm, ctx, &requests_done); 863 kill_ioctx(mm, ctx, &wait);
864 }
853 865
866 if (!atomic_sub_and_test(skipped, &wait.count)) {
854 /* Wait until all IO for the context are done. */ 867 /* Wait until all IO for the context are done. */
855 wait_for_completion(&requests_done); 868 wait_for_completion(&wait.comp);
856 } 869 }
857 870
858 RCU_INIT_POINTER(mm->ioctx_table, NULL); 871 RCU_INIT_POINTER(mm->ioctx_table, NULL);
@@ -1331,15 +1344,17 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
1331{ 1344{
1332 struct kioctx *ioctx = lookup_ioctx(ctx); 1345 struct kioctx *ioctx = lookup_ioctx(ctx);
1333 if (likely(NULL != ioctx)) { 1346 if (likely(NULL != ioctx)) {
1334 struct completion requests_done = 1347 struct ctx_rq_wait wait;
1335 COMPLETION_INITIALIZER_ONSTACK(requests_done);
1336 int ret; 1348 int ret;
1337 1349
1350 init_completion(&wait.comp);
1351 atomic_set(&wait.count, 1);
1352
1338 /* Pass requests_done to kill_ioctx() where it can be set 1353 /* Pass requests_done to kill_ioctx() where it can be set
1339 * in a thread-safe way. If we try to set it here then we have 1354 * in a thread-safe way. If we try to set it here then we have
1340 * a race condition if two io_destroy() called simultaneously. 1355 * a race condition if two io_destroy() called simultaneously.
1341 */ 1356 */
1342 ret = kill_ioctx(current->mm, ioctx, &requests_done); 1357 ret = kill_ioctx(current->mm, ioctx, &wait);
1343 percpu_ref_put(&ioctx->users); 1358 percpu_ref_put(&ioctx->users);
1344 1359
1345 /* Wait until all IO for the context are done. Otherwise kernel 1360 /* Wait until all IO for the context are done. Otherwise kernel
@@ -1347,7 +1362,7 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
1347 * is destroyed. 1362 * is destroyed.
1348 */ 1363 */
1349 if (!ret) 1364 if (!ret)
1350 wait_for_completion(&requests_done); 1365 wait_for_completion(&wait.comp);
1351 1366
1352 return ret; 1367 return ret;
1353 } 1368 }