]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Nov 2017 13:20:40 +0000 (14:20 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Nov 2017 13:20:40 +0000 (14:20 +0100)
added patches:
dm-allocate-struct-mapped_device-with-kvzalloc.patch
dm-bufio-fix-integer-overflow-when-limiting-maximum-cache-size.patch

queue-4.9/dm-allocate-struct-mapped_device-with-kvzalloc.patch [new file with mode: 0644]
queue-4.9/dm-bufio-fix-integer-overflow-when-limiting-maximum-cache-size.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/dm-allocate-struct-mapped_device-with-kvzalloc.patch b/queue-4.9/dm-allocate-struct-mapped_device-with-kvzalloc.patch
new file mode 100644 (file)
index 0000000..55117e1
--- /dev/null
@@ -0,0 +1,91 @@
+From 856eb0916d181da6d043cc33e03f54d5c5bbe54a Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Tue, 31 Oct 2017 19:33:02 -0400
+Subject: dm: allocate struct mapped_device with kvzalloc
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 856eb0916d181da6d043cc33e03f54d5c5bbe54a upstream.
+
+The structure srcu_struct can be very big, its size is proportional to the
+value CONFIG_NR_CPUS. The Fedora kernel has CONFIG_NR_CPUS 8192, the field
+io_barrier in the struct mapped_device has 84kB in the debugging kernel
+and 50kB in the non-debugging kernel. The large size may result in failure
+of the function kzalloc_node.
+
+In order to avoid the allocation failure, we use the function
+kvzalloc_node, this function falls back to vmalloc if a large contiguous
+chunk of memory is not available. This patch also moves the field
+io_barrier to the last position of struct mapped_device - the reason is
+that on many processor architectures, short memory offsets result in
+smaller code than long memory offsets - on x86-64 it reduces code size by
+320 bytes.
+
+Note to stable kernel maintainers - the kernels 4.11 and older don't have
+the function kvzalloc_node, you can use the function vzalloc_node instead.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-core.h |    3 ++-
+ drivers/md/dm.c      |    7 ++++---
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/md/dm-core.h
++++ b/drivers/md/dm-core.h
+@@ -29,7 +29,6 @@ struct dm_kobject_holder {
+  * DM targets must _not_ deference a mapped_device to directly access its members!
+  */
+ struct mapped_device {
+-      struct srcu_struct io_barrier;
+       struct mutex suspend_lock;
+       /*
+@@ -127,6 +126,8 @@ struct mapped_device {
+       struct blk_mq_tag_set *tag_set;
+       bool use_blk_mq:1;
+       bool init_tio_pdu:1;
++
++      struct srcu_struct io_barrier;
+ };
+ void dm_init_md_queue(struct mapped_device *md);
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -21,6 +21,7 @@
+ #include <linux/delay.h>
+ #include <linux/wait.h>
+ #include <linux/pr.h>
++#include <linux/vmalloc.h>
+ #define DM_MSG_PREFIX "core"
+@@ -1511,7 +1512,7 @@ static struct mapped_device *alloc_dev(i
+       struct mapped_device *md;
+       void *old_md;
+-      md = kzalloc_node(sizeof(*md), GFP_KERNEL, numa_node_id);
++      md = vzalloc_node(sizeof(*md), numa_node_id);
+       if (!md) {
+               DMWARN("unable to allocate device, out of memory.");
+               return NULL;
+@@ -1605,7 +1606,7 @@ bad_io_barrier:
+ bad_minor:
+       module_put(THIS_MODULE);
+ bad_module_get:
+-      kfree(md);
++      kvfree(md);
+       return NULL;
+ }
+@@ -1624,7 +1625,7 @@ static void free_dev(struct mapped_devic
+       free_minor(minor);
+       module_put(THIS_MODULE);
+-      kfree(md);
++      kvfree(md);
+ }
+ static void __bind_mempools(struct mapped_device *md, struct dm_table *t)
diff --git a/queue-4.9/dm-bufio-fix-integer-overflow-when-limiting-maximum-cache-size.patch b/queue-4.9/dm-bufio-fix-integer-overflow-when-limiting-maximum-cache-size.patch
new file mode 100644 (file)
index 0000000..0ea7bbd
--- /dev/null
@@ -0,0 +1,72 @@
+From 74d4108d9e681dbbe4a2940ed8fdff1f6868184c Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 15 Nov 2017 16:38:09 -0800
+Subject: dm bufio: fix integer overflow when limiting maximum cache size
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 74d4108d9e681dbbe4a2940ed8fdff1f6868184c upstream.
+
+The default max_cache_size_bytes for dm-bufio is meant to be the lesser
+of 25% of the size of the vmalloc area and 2% of the size of lowmem.
+However, on 32-bit systems the intermediate result in the expression
+
+    (VMALLOC_END - VMALLOC_START) * DM_BUFIO_VMALLOC_PERCENT / 100
+
+overflows, causing the wrong result to be computed.  For example, on a
+32-bit system where the vmalloc area is 520093696 bytes, the result is
+1174405 rather than the expected 130023424, which makes the maximum
+cache size much too small (far less than 2% of lowmem).  This causes
+severe performance problems for dm-verity users on affected systems.
+
+Fix this by using mult_frac() to correctly multiply by a percentage.  Do
+this for all places in dm-bufio that multiply by a percentage.  Also
+replace (VMALLOC_END - VMALLOC_START) with VMALLOC_TOTAL, which contrary
+to the comment is now defined in include/linux/vmalloc.h.
+
+Depends-on: 9993bc635 ("sched/x86: Fix overflow in cyc2ns_offset")
+Fixes: 95d402f057f2 ("dm: add bufio")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-bufio.c |   15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+--- a/drivers/md/dm-bufio.c
++++ b/drivers/md/dm-bufio.c
+@@ -937,7 +937,8 @@ static void __get_memory_limit(struct dm
+               buffers = c->minimum_buffers;
+       *limit_buffers = buffers;
+-      *threshold_buffers = buffers * DM_BUFIO_WRITEBACK_PERCENT / 100;
++      *threshold_buffers = mult_frac(buffers,
++                                     DM_BUFIO_WRITEBACK_PERCENT, 100);
+ }
+ /*
+@@ -1856,19 +1857,15 @@ static int __init dm_bufio_init(void)
+       memset(&dm_bufio_caches, 0, sizeof dm_bufio_caches);
+       memset(&dm_bufio_cache_names, 0, sizeof dm_bufio_cache_names);
+-      mem = (__u64)((totalram_pages - totalhigh_pages) *
+-                    DM_BUFIO_MEMORY_PERCENT / 100) << PAGE_SHIFT;
++      mem = (__u64)mult_frac(totalram_pages - totalhigh_pages,
++                             DM_BUFIO_MEMORY_PERCENT, 100) << PAGE_SHIFT;
+       if (mem > ULONG_MAX)
+               mem = ULONG_MAX;
+ #ifdef CONFIG_MMU
+-      /*
+-       * Get the size of vmalloc space the same way as VMALLOC_TOTAL
+-       * in fs/proc/internal.h
+-       */
+-      if (mem > (VMALLOC_END - VMALLOC_START) * DM_BUFIO_VMALLOC_PERCENT / 100)
+-              mem = (VMALLOC_END - VMALLOC_START) * DM_BUFIO_VMALLOC_PERCENT / 100;
++      if (mem > mult_frac(VMALLOC_TOTAL, DM_BUFIO_VMALLOC_PERCENT, 100))
++              mem = mult_frac(VMALLOC_TOTAL, DM_BUFIO_VMALLOC_PERCENT, 100);
+ #endif
+       dm_bufio_default_cache_size = mem;
index 4e9ef8e0d09a554b162d4151d4b21d0fb3004d95..4520eff3a4d7a41ab7c84e4b8c403f3eb42f1ddb 100644 (file)
@@ -17,3 +17,5 @@ mips-ralink-fix-mt7628-pinmux.patch
 mips-ralink-fix-typo-in-mt7628-pinmux-function.patch
 pci-set-cavium-acs-capability-quirk-flags-to-assert-rr-cr-sv-uf.patch
 alsa-hda-add-raven-pci-id.patch
+dm-bufio-fix-integer-overflow-when-limiting-maximum-cache-size.patch
+dm-allocate-struct-mapped_device-with-kvzalloc.patch