aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMilan Broz <mbroz@redhat.com>2006-10-03 04:15:40 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-03 11:04:16 -0400
commit6a24c71843de1354d3bcc2ce47fd0b3bee936399 (patch)
tree7a826dd50061ca086e6ed05d6b7a9247c0e2c095 /drivers/md
parent23541d2d288cdb54f417ba1001dacc7f3ea10a97 (diff)
[PATCH] dm crypt: use private biosets
In the low memory situation dm-crypt needs to use a private mempool of bios to avoid blocking. Signed-off-by: Milan Broz <mbroz@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-crypt.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index c34433a6edd0..655d816760e5 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -77,6 +77,7 @@ struct crypt_config {
77 */ 77 */
78 mempool_t *io_pool; 78 mempool_t *io_pool;
79 mempool_t *page_pool; 79 mempool_t *page_pool;
80 struct bio_set *bs;
80 81
81 /* 82 /*
82 * crypto related data 83 * crypto related data
@@ -95,7 +96,7 @@ struct crypt_config {
95 u8 key[0]; 96 u8 key[0];
96}; 97};
97 98
98#define MIN_IOS 256 99#define MIN_IOS 16
99#define MIN_POOL_PAGES 32 100#define MIN_POOL_PAGES 32
100#define MIN_BIO_PAGES 8 101#define MIN_BIO_PAGES 8
101 102
@@ -311,6 +312,14 @@ static int crypt_convert(struct crypt_config *cc,
311 return r; 312 return r;
312} 313}
313 314
315 static void dm_crypt_bio_destructor(struct bio *bio)
316 {
317 struct crypt_io *io = bio->bi_private;
318 struct crypt_config *cc = io->target->private;
319
320 bio_free(bio, cc->bs);
321 }
322
314/* 323/*
315 * Generate a new unfragmented bio with the given size 324 * Generate a new unfragmented bio with the given size
316 * This should never violate the device limitations 325 * This should never violate the device limitations
@@ -325,18 +334,17 @@ crypt_alloc_buffer(struct crypt_config *cc, unsigned int size,
325 gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM; 334 gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
326 unsigned int i; 335 unsigned int i;
327 336
328 /* 337 if (base_bio) {
329 * Use __GFP_NOMEMALLOC to tell the VM to act less aggressively and 338 clone = bio_alloc_bioset(GFP_NOIO, base_bio->bi_max_vecs, cc->bs);
330 * to fail earlier. This is not necessary but increases throughput. 339 __bio_clone(clone, base_bio);
331 * FIXME: Is this really intelligent? 340 } else
332 */ 341 clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
333 if (base_bio) 342
334 clone = bio_clone(base_bio, GFP_NOIO|__GFP_NOMEMALLOC);
335 else
336 clone = bio_alloc(GFP_NOIO|__GFP_NOMEMALLOC, nr_iovecs);
337 if (!clone) 343 if (!clone)
338 return NULL; 344 return NULL;
339 345
346 clone->bi_destructor = dm_crypt_bio_destructor;
347
340 /* if the last bio was not complete, continue where that one ended */ 348 /* if the last bio was not complete, continue where that one ended */
341 clone->bi_idx = *bio_vec_idx; 349 clone->bi_idx = *bio_vec_idx;
342 clone->bi_vcnt = *bio_vec_idx; 350 clone->bi_vcnt = *bio_vec_idx;
@@ -517,13 +525,14 @@ static void process_read(struct crypt_io *io)
517 * copy the required bvecs because we need the original 525 * copy the required bvecs because we need the original
518 * one in order to decrypt the whole bio data *afterwards*. 526 * one in order to decrypt the whole bio data *afterwards*.
519 */ 527 */
520 clone = bio_alloc(GFP_NOIO, bio_segments(base_bio)); 528 clone = bio_alloc_bioset(GFP_NOIO, bio_segments(base_bio), cc->bs);
521 if (unlikely(!clone)) { 529 if (unlikely(!clone)) {
522 dec_pending(io, -ENOMEM); 530 dec_pending(io, -ENOMEM);
523 return; 531 return;
524 } 532 }
525 533
526 clone_init(io, clone); 534 clone_init(io, clone);
535 clone->bi_destructor = dm_crypt_bio_destructor;
527 clone->bi_idx = 0; 536 clone->bi_idx = 0;
528 clone->bi_vcnt = bio_segments(base_bio); 537 clone->bi_vcnt = bio_segments(base_bio);
529 clone->bi_size = base_bio->bi_size; 538 clone->bi_size = base_bio->bi_size;
@@ -594,7 +603,6 @@ static void process_write(struct crypt_io *io)
594 /* out of memory -> run queues */ 603 /* out of memory -> run queues */
595 if (remaining) 604 if (remaining)
596 blk_congestion_wait(bio_data_dir(clone), HZ/100); 605 blk_congestion_wait(bio_data_dir(clone), HZ/100);
597
598 } 606 }
599} 607}
600 608
@@ -804,6 +812,12 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
804 goto bad4; 812 goto bad4;
805 } 813 }
806 814
815 cc->bs = bioset_create(MIN_IOS, MIN_IOS, 4);
816 if (!cc->bs) {
817 ti->error = "Cannot allocate crypt bioset";
818 goto bad_bs;
819 }
820
807 if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) { 821 if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) {
808 ti->error = "Error setting key"; 822 ti->error = "Error setting key";
809 goto bad5; 823 goto bad5;
@@ -843,6 +857,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
843 return 0; 857 return 0;
844 858
845bad5: 859bad5:
860 bioset_free(cc->bs);
861bad_bs:
846 mempool_destroy(cc->page_pool); 862 mempool_destroy(cc->page_pool);
847bad4: 863bad4:
848 mempool_destroy(cc->io_pool); 864 mempool_destroy(cc->io_pool);
@@ -862,6 +878,7 @@ static void crypt_dtr(struct dm_target *ti)
862{ 878{
863 struct crypt_config *cc = (struct crypt_config *) ti->private; 879 struct crypt_config *cc = (struct crypt_config *) ti->private;
864 880
881 bioset_free(cc->bs);
865 mempool_destroy(cc->page_pool); 882 mempool_destroy(cc->page_pool);
866 mempool_destroy(cc->io_pool); 883 mempool_destroy(cc->io_pool);
867 884