commit:     c90ba25cf30f0a5d1aadc37493e2d3eb8e44c748
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Sep 28 23:57:34 2015 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Sep 28 23:57:34 2015 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c90ba25c

dm crypt: constrain crypt device's max_segment_size to PAGE_SIZE. See bug 
#561558. Thanks to kipplasterjoe for reporting.

 0000_README                                |  4 ++
 1600_dm-crypt-limit-max-segment-size.patch | 84 ++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+)

diff --git a/0000_README b/0000_README
index b88684d..4a96d2e 100644
--- a/0000_README
+++ b/0000_README
@@ -83,6 +83,10 @@ Patch:  
1510_fs-enable-link-security-restrictions-by-default.patch
 From:   
http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/
 Desc:   Enable link security restrictions by default.
 
+Patch:  1600_dm-crypt-limit-max-segment-size.patch
+From:   https://bugzilla.kernel.org/show_bug.cgi?id=104421
+Desc:   dm crypt: constrain crypt device's max_segment_size to PAGE_SIZE.
+
 Patch:  2700_ThinkPad-30-brightness-control-fix.patch
 From:   Seth Forshee <seth.fors...@canonical.com>
 Desc:   ACPI: Disable Windows 8 compatibility for some Lenovo ThinkPads.

diff --git a/1600_dm-crypt-limit-max-segment-size.patch 
b/1600_dm-crypt-limit-max-segment-size.patch
new file mode 100644
index 0000000..82aca44
--- /dev/null
+++ b/1600_dm-crypt-limit-max-segment-size.patch
@@ -0,0 +1,84 @@
+From 586b286b110e94eb31840ac5afc0c24e0881fe34 Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snit...@redhat.com>
+Date: Wed, 9 Sep 2015 21:34:51 -0400
+Subject: dm crypt: constrain crypt device's max_segment_size to PAGE_SIZE
+
+Setting the dm-crypt device's max_segment_size to PAGE_SIZE is an
+unfortunate constraint that is required to avoid the potential for
+exceeding dm-crypt's underlying device's max_segments limits -- due to
+crypt_alloc_buffer() possibly allocating pages for the encryption bio
+that are not as physically contiguous as the original bio.
+
+It is interesting to note that this problem was already fixed back in
+2007 via commit 91e106259 ("dm crypt: use bio_add_page").  But Linux 4.0
+commit cf2f1abfb ("dm crypt: don't allocate pages for a partial
+request") regressed dm-crypt back to _not_ using bio_add_page().  But
+given dm-crypt's cpu parallelization changes all depend on commit
+cf2f1abfb's abandoning of the more complex io fragments processing that
+dm-crypt previously had we cannot easily go back to using
+bio_add_page().
+
+So all said the cleanest way to resolve this issue is to fix dm-crypt to
+properly constrain the original bios entering dm-crypt so the encryption
+bios that dm-crypt generates from the original bios are always
+compatible with the underlying device's max_segments queue limits.
+
+It should be noted that technically Linux 4.3 does _not_ need this fix
+because of the block core's new late bio-splitting capability.  But, it
+is reasoned, there is little to be gained by having the block core split
+the encrypted bio that is composed of PAGE_SIZE segments.  That said, in
+the future we may revert this change.
+
+Fixes: cf2f1abfb ("dm crypt: don't allocate pages for a partial request")
+Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=104421
+Suggested-by: Jeff Moyer <jmo...@redhat.com>
+Signed-off-by: Mike Snitzer <snit...@redhat.com>
+Cc: sta...@vger.kernel.org # 4.0+
+
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index d60c88d..4b3b6f8 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -968,7 +968,8 @@ static void crypt_free_buffer_pages(struct crypt_config 
*cc, struct bio *clone);
+ 
+ /*
+  * Generate a new unfragmented bio with the given size
+- * This should never violate the device limitations
++ * This should never violate the device limitations (but only because
++ * max_segment_size is being constrained to PAGE_SIZE).
+  *
+  * This function may be called concurrently. If we allocate from the mempool
+  * concurrently, there is a possibility of deadlock. For example, if we have
+@@ -2045,9 +2046,20 @@ static int crypt_iterate_devices(struct dm_target *ti,
+       return fn(ti, cc->dev, cc->start, ti->len, data);
+ }
+ 
++static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)
++{
++      /*
++       * Unfortunate constraint that is required to avoid the potential
++       * for exceeding underlying device's max_segments limits -- due to
++       * crypt_alloc_buffer() possibly allocating pages for the encryption
++       * bio that are not as physically contiguous as the original bio.
++       */
++      limits->max_segment_size = PAGE_SIZE;
++}
++
+ static struct target_type crypt_target = {
+       .name   = "crypt",
+-      .version = {1, 14, 0},
++      .version = {1, 14, 1},
+       .module = THIS_MODULE,
+       .ctr    = crypt_ctr,
+       .dtr    = crypt_dtr,
+@@ -2058,6 +2070,7 @@ static struct target_type crypt_target = {
+       .resume = crypt_resume,
+       .message = crypt_message,
+       .iterate_devices = crypt_iterate_devices,
++      .io_hints = crypt_io_hints,
+ };
+ 
+ static int __init dm_crypt_init(void)
+-- 
+cgit v0.10.2
+

Reply via email to