dm crypt: fix ctx pending

Fix regression in dm-crypt introduced in commit
3a7f6c990ad04e6f576a159876c602d14d6f7fef ("dm crypt: use async crypto").

If write requests need to be split into pieces, the code must not process them
in parallel because the crypto context cannot be shared. So there can be
parallel crypto operations on one part of the write, but only one write bio
can be processed at a time.

This is not optimal and the workqueue code needs to be optimized for parallel
processing, but for now it solves the problem without affecting the
performance of synchronous crypto operation (most of current dm-crypt users).

http://bugzilla.kernel.org/show_bug.cgi?id=10242
http://bugzilla.kernel.org/show_bug.cgi?id=10207

Signed-off-by: Milan Broz <mbroz@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Milan Broz and committed by Linus Torvalds 3f1e9070 ab473a52

+31 -29
+31 -29
drivers/md/dm-crypt.c
··· 1 /* 2 * Copyright (C) 2003 Christophe Saout <christophe@saout.de> 3 * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org> 4 - * Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved. 5 * 6 * This file is released under the GPL. 7 */ ··· 93 94 struct workqueue_struct *io_queue; 95 struct workqueue_struct *crypt_queue; 96 /* 97 * crypto related data 98 */ ··· 333 ctx->idx_out = bio_out ? bio_out->bi_idx : 0; 334 ctx->sector = sector + cc->iv_offset; 335 init_completion(&ctx->restart); 336 - /* 337 - * Crypto operation can be asynchronous, 338 - * ctx->pending is increased after request submission. 339 - * We need to ensure that we don't call the crypt finish 340 - * operation before pending got incremented 341 - * (dependent on crypt submission return code). 342 - */ 343 - atomic_set(&ctx->pending, 2); 344 } 345 346 static int crypt_convert_block(struct crypt_config *cc, ··· 406 static int crypt_convert(struct crypt_config *cc, 407 struct convert_context *ctx) 408 { 409 - int r = 0; 410 411 while(ctx->idx_in < ctx->bio_in->bi_vcnt && 412 ctx->idx_out < ctx->bio_out->bi_vcnt) { 413 414 crypt_alloc_req(cc, ctx); 415 416 r = crypt_convert_block(cc, ctx, cc->req); 417 418 switch (r) { 419 case -EBUSY: 420 wait_for_completion(&ctx->restart); 421 INIT_COMPLETION(ctx->restart); 422 /* fall through*/ 423 case -EINPROGRESS: 424 - atomic_inc(&ctx->pending); 425 cc->req = NULL; 426 - r = 0; 427 - /* fall through*/ 428 - case 0: 429 ctx->sector++; 430 continue; 431 - } 432 433 - break; 434 } 435 436 - /* 437 - * If there are pending crypto operation run async 438 - * code. Otherwise process return code synchronously. 439 - * The step of 2 ensures that async finish doesn't 440 - * call crypto finish too early. 441 - */ 442 - if (atomic_sub_return(2, &ctx->pending)) 443 - return -EINPROGRESS; 444 - 445 - return r; 446 } 447 448 static void dm_crypt_bio_destructor(struct bio *bio) ··· 618 static void kcryptd_io_write(struct dm_crypt_io *io) 619 { 620 struct bio *clone = io->ctx.bio_out; 621 622 generic_make_request(clone); 623 } 624 625 static void kcryptd_io(struct work_struct *work) ··· 694 695 r = crypt_convert(cc, &io->ctx); 696 697 - if (r != -EINPROGRESS) { 698 kcryptd_crypt_write_io_submit(io, r, 0); 699 if (unlikely(r < 0)) 700 return; ··· 703 atomic_inc(&io->pending); 704 705 /* out of memory -> run queues */ 706 - if (unlikely(remaining)) 707 congestion_wait(WRITE, HZ/100); 708 } 709 } 710 ··· 747 748 r = crypt_convert(cc, &io->ctx); 749 750 - if (r != -EINPROGRESS) 751 kcryptd_crypt_read_done(io, r); 752 753 crypt_dec_pending(io); ··· 1048 goto bad_crypt_queue; 1049 } 1050 1051 ti->private = cc; 1052 return 0; 1053
··· 1 /* 2 * Copyright (C) 2003 Christophe Saout <christophe@saout.de> 3 * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org> 4 + * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. 5 * 6 * This file is released under the GPL. 7 */ ··· 93 94 struct workqueue_struct *io_queue; 95 struct workqueue_struct *crypt_queue; 96 + wait_queue_head_t writeq; 97 + 98 /* 99 * crypto related data 100 */ ··· 331 ctx->idx_out = bio_out ? bio_out->bi_idx : 0; 332 ctx->sector = sector + cc->iv_offset; 333 init_completion(&ctx->restart); 334 + atomic_set(&ctx->pending, 1); 335 } 336 337 static int crypt_convert_block(struct crypt_config *cc, ··· 411 static int crypt_convert(struct crypt_config *cc, 412 struct convert_context *ctx) 413 { 414 + int r; 415 416 while(ctx->idx_in < ctx->bio_in->bi_vcnt && 417 ctx->idx_out < ctx->bio_out->bi_vcnt) { 418 419 crypt_alloc_req(cc, ctx); 420 421 + atomic_inc(&ctx->pending); 422 + 423 r = crypt_convert_block(cc, ctx, cc->req); 424 425 switch (r) { 426 + /* async */ 427 case -EBUSY: 428 wait_for_completion(&ctx->restart); 429 INIT_COMPLETION(ctx->restart); 430 /* fall through*/ 431 case -EINPROGRESS: 432 cc->req = NULL; 433 ctx->sector++; 434 continue; 435 436 + /* sync */ 437 + case 0: 438 + atomic_dec(&ctx->pending); 439 + ctx->sector++; 440 + continue; 441 + 442 + /* error */ 443 + default: 444 + atomic_dec(&ctx->pending); 445 + return r; 446 + } 447 } 448 449 + return 0; 450 } 451 452 static void dm_crypt_bio_destructor(struct bio *bio) ··· 624 static void kcryptd_io_write(struct dm_crypt_io *io) 625 { 626 struct bio *clone = io->ctx.bio_out; 627 + struct crypt_config *cc = io->target->private; 628 629 generic_make_request(clone); 630 + wake_up(&cc->writeq); 631 } 632 633 static void kcryptd_io(struct work_struct *work) ··· 698 699 r = crypt_convert(cc, &io->ctx); 700 701 + if (atomic_dec_and_test(&io->ctx.pending)) { 702 + /* processed, no running async crypto */ 703 kcryptd_crypt_write_io_submit(io, r, 0); 704 if (unlikely(r < 0)) 705 return; ··· 706 atomic_inc(&io->pending); 707 708 /* out of memory -> run queues */ 709 + if (unlikely(remaining)) { 710 + /* wait for async crypto then reinitialize pending */ 711 + wait_event(cc->writeq, !atomic_read(&io->ctx.pending)); 712 + atomic_set(&io->ctx.pending, 1); 713 congestion_wait(WRITE, HZ/100); 714 + } 715 } 716 } 717 ··· 746 747 r = crypt_convert(cc, &io->ctx); 748 749 + if (atomic_dec_and_test(&io->ctx.pending)) 750 kcryptd_crypt_read_done(io, r); 751 752 crypt_dec_pending(io); ··· 1047 goto bad_crypt_queue; 1048 } 1049 1050 + init_waitqueue_head(&cc->writeq); 1051 ti->private = cc; 1052 return 0; 1053