]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 10 May 2013 17:28:19 +0000 (10:28 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 10 May 2013 17:28:19 +0000 (10:28 -0700)
added patches:
dma-of-check-properties-value-before-running-be32_to_cpup-on-it.patch
dm-bufio-avoid-a-possible-__vmalloc-deadlock.patch
dm-cache-fix-error-return-code-in-cache_create.patch
dm-snapshot-fix-error-return-code-in-snapshot_ctr.patch
dm-stripe-fix-regression-in-stripe_width-calculation.patch
dm-table-fix-write-same-support.patch

queue-3.9/dm-bufio-avoid-a-possible-__vmalloc-deadlock.patch [new file with mode: 0644]
queue-3.9/dm-cache-fix-error-return-code-in-cache_create.patch [new file with mode: 0644]
queue-3.9/dm-snapshot-fix-error-return-code-in-snapshot_ctr.patch [new file with mode: 0644]
queue-3.9/dm-stripe-fix-regression-in-stripe_width-calculation.patch [new file with mode: 0644]
queue-3.9/dm-table-fix-write-same-support.patch [new file with mode: 0644]
queue-3.9/dma-of-check-properties-value-before-running-be32_to_cpup-on-it.patch [new file with mode: 0644]
queue-3.9/series

diff --git a/queue-3.9/dm-bufio-avoid-a-possible-__vmalloc-deadlock.patch b/queue-3.9/dm-bufio-avoid-a-possible-__vmalloc-deadlock.patch
new file mode 100644 (file)
index 0000000..126cc16
--- /dev/null
@@ -0,0 +1,78 @@
+From 502624bdad3dba45dfaacaf36b7d83e39e74b2d2 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Fri, 10 May 2013 14:37:15 +0100
+Subject: dm bufio: avoid a possible __vmalloc deadlock
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 502624bdad3dba45dfaacaf36b7d83e39e74b2d2 upstream.
+
+This patch uses memalloc_noio_save to avoid a possible deadlock in
+dm-bufio.  (it could happen only with large block size, at most
+PAGE_SIZE << MAX_ORDER (typically 8MiB).
+
+__vmalloc doesn't fully respect gfp flags. The specified gfp flags are
+used for allocation of requested pages, structures vmap_area, vmap_block
+and vm_struct and the radix tree nodes.
+
+However, the kernel pagetables are allocated always with GFP_KERNEL.
+Thus the allocation of pagetables can recurse back to the I/O layer and
+cause a deadlock.
+
+This patch uses the function memalloc_noio_save to set per-process
+PF_MEMALLOC_NOIO flag and the function memalloc_noio_restore to restore
+it. When this flag is set, all allocations in the process are done with
+implied GFP_NOIO flag, thus the deadlock can't happen.
+
+This should be backported to stable kernels, but they don't have the
+PF_MEMALLOC_NOIO flag and memalloc_noio_save/memalloc_noio_restore
+functions. So, PF_MEMALLOC should be set and restored instead.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-bufio.c |   24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+--- a/drivers/md/dm-bufio.c
++++ b/drivers/md/dm-bufio.c
+@@ -319,6 +319,9 @@ static void __cache_size_refresh(void)
+ static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask,
+                              enum data_mode *data_mode)
+ {
++      unsigned noio_flag;
++      void *ptr;
++
+       if (c->block_size <= DM_BUFIO_BLOCK_SIZE_SLAB_LIMIT) {
+               *data_mode = DATA_MODE_SLAB;
+               return kmem_cache_alloc(DM_BUFIO_CACHE(c), gfp_mask);
+@@ -332,7 +335,26 @@ static void *alloc_buffer_data(struct dm
+       }
+       *data_mode = DATA_MODE_VMALLOC;
+-      return __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL);
++
++      /*
++       * __vmalloc allocates the data pages and auxiliary structures with
++       * gfp_flags that were specified, but pagetables are always allocated
++       * with GFP_KERNEL, no matter what was specified as gfp_mask.
++       *
++       * Consequently, we must set per-process flag PF_MEMALLOC_NOIO so that
++       * all allocations done by this process (including pagetables) are done
++       * as if GFP_NOIO was specified.
++       */
++
++      if (gfp_mask & __GFP_NORETRY)
++              noio_flag = memalloc_noio_save();
++
++      ptr = __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL);
++
++      if (gfp_mask & __GFP_NORETRY)
++              memalloc_noio_restore(noio_flag);
++
++      return ptr;
+ }
+ /*
diff --git a/queue-3.9/dm-cache-fix-error-return-code-in-cache_create.patch b/queue-3.9/dm-cache-fix-error-return-code-in-cache_create.patch
new file mode 100644 (file)
index 0000000..0509b8d
--- /dev/null
@@ -0,0 +1,30 @@
+From fa4d683af3693863bec761e2761a07e4c1351f86 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Date: Fri, 10 May 2013 14:37:14 +0100
+Subject: dm cache: fix error return code in cache_create
+
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+
+commit fa4d683af3693863bec761e2761a07e4c1351f86 upstream.
+
+Return -ENOMEM if memory allocation fails in cache_create
+instead of 0 (to avoid NULL pointer dereference).
+
+Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-cache-target.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/md/dm-cache-target.c
++++ b/drivers/md/dm-cache-target.c
+@@ -1971,6 +1971,7 @@ static int cache_create(struct cache_arg
+       atomic_set(&cache->nr_migrations, 0);
+       init_waitqueue_head(&cache->migration_wait);
++      r = -ENOMEM;
+       cache->nr_dirty = 0;
+       cache->dirty_bitset = alloc_bitset(from_cblock(cache->cache_size));
+       if (!cache->dirty_bitset) {
diff --git a/queue-3.9/dm-snapshot-fix-error-return-code-in-snapshot_ctr.patch b/queue-3.9/dm-snapshot-fix-error-return-code-in-snapshot_ctr.patch
new file mode 100644 (file)
index 0000000..7098a11
--- /dev/null
@@ -0,0 +1,30 @@
+From 09e8b813897a0f85bb401435d009228644c81214 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Date: Fri, 10 May 2013 14:37:15 +0100
+Subject: dm snapshot: fix error return code in snapshot_ctr
+
+From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+
+commit 09e8b813897a0f85bb401435d009228644c81214 upstream.
+
+Return -ENOMEM instead of success if unable to allocate pending
+exception mempool in snapshot_ctr.
+
+Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-snap.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -1121,6 +1121,7 @@ static int snapshot_ctr(struct dm_target
+       s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache);
+       if (!s->pending_pool) {
+               ti->error = "Could not allocate mempool for pending exceptions";
++              r = -ENOMEM;
+               goto bad_pending_pool;
+       }
diff --git a/queue-3.9/dm-stripe-fix-regression-in-stripe_width-calculation.patch b/queue-3.9/dm-stripe-fix-regression-in-stripe_width-calculation.patch
new file mode 100644 (file)
index 0000000..0caa607
--- /dev/null
@@ -0,0 +1,74 @@
+From d793e684277124d55c5d2444007e224635821346 Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snitzer@redhat.com>
+Date: Fri, 10 May 2013 14:37:14 +0100
+Subject: dm stripe: fix regression in stripe_width calculation
+
+From: Mike Snitzer <snitzer@redhat.com>
+
+commit d793e684277124d55c5d2444007e224635821346 upstream.
+
+Fix a regression in the calculation of the stripe_width in the
+dm stripe target which led to incorrect processing of device limits.
+
+The stripe_width is the stripe device length divided by the number of
+stripes.  The group of commits in the range f14fa69 ("dm stripe: fix
+size test") to eb850de ("dm stripe: support for non power of 2
+chunksize") interfered with each other (a merging error) and led to the
+stripe_width being set incorrectly to the stripe device length divided by
+chunk_size * stripe_count.
+
+For example, a stripe device's table with: 0 33553920 striped 3 512 ...
+should result in a stripe_width of 11184640 (33553920 / 3), but due to
+the bug it was getting set to 21845 (33553920 / (512 * 3)).
+
+The impact of this bug is that device topologies that previously worked
+fine with the stripe target are no longer considered valid.  In
+particular, there is a higher risk of seeing this issue if one of the
+stripe devices has a 4K logical block size.  Resulting in an error
+message like this:
+"device-mapper: table: 253:4: len=21845 not aligned to h/w logical block size 4096 of dm-1"
+
+The fix is to swap the order of the divisions and to use a temporary
+variable for the second one, so that width retains the intended
+value.
+
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-stripe.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/md/dm-stripe.c
++++ b/drivers/md/dm-stripe.c
+@@ -94,7 +94,7 @@ static int get_stripe(struct dm_target *
+ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ {
+       struct stripe_c *sc;
+-      sector_t width;
++      sector_t width, tmp_len;
+       uint32_t stripes;
+       uint32_t chunk_size;
+       int r;
+@@ -116,15 +116,16 @@ static int stripe_ctr(struct dm_target *
+       }
+       width = ti->len;
+-      if (sector_div(width, chunk_size)) {
++      if (sector_div(width, stripes)) {
+               ti->error = "Target length not divisible by "
+-                  "chunk size";
++                  "number of stripes";
+               return -EINVAL;
+       }
+-      if (sector_div(width, stripes)) {
++      tmp_len = width;
++      if (sector_div(tmp_len, chunk_size)) {
+               ti->error = "Target length not divisible by "
+-                  "number of stripes";
++                  "chunk size";
+               return -EINVAL;
+       }
diff --git a/queue-3.9/dm-table-fix-write-same-support.patch b/queue-3.9/dm-table-fix-write-same-support.patch
new file mode 100644 (file)
index 0000000..cfa1346
--- /dev/null
@@ -0,0 +1,32 @@
+From dc019b21fb92d620a3b52ccecc135ac968a7c7ec Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snitzer@redhat.com>
+Date: Fri, 10 May 2013 14:37:16 +0100
+Subject: dm table: fix write same support
+
+From: Mike Snitzer <snitzer@redhat.com>
+
+commit dc019b21fb92d620a3b52ccecc135ac968a7c7ec upstream.
+
+If device_not_write_same_capable() returns true then the iterate_devices
+loop in dm_table_supports_write_same() should return false.
+
+Reported-by: Bharata B Rao <bharata.rao@gmail.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-table.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -1442,7 +1442,7 @@ static bool dm_table_supports_write_same
+                       return false;
+               if (!ti->type->iterate_devices ||
+-                  !ti->type->iterate_devices(ti, device_not_write_same_capable, NULL))
++                  ti->type->iterate_devices(ti, device_not_write_same_capable, NULL))
+                       return false;
+       }
diff --git a/queue-3.9/dma-of-check-properties-value-before-running-be32_to_cpup-on-it.patch b/queue-3.9/dma-of-check-properties-value-before-running-be32_to_cpup-on-it.patch
new file mode 100644 (file)
index 0000000..12bff74
--- /dev/null
@@ -0,0 +1,49 @@
+From 9a188eb126aa7bf27077ee46fcb914898d6fc281 Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Fri, 15 Mar 2013 14:18:20 +0530
+Subject: DMA: OF: Check properties value before running be32_to_cpup() on it
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+commit 9a188eb126aa7bf27077ee46fcb914898d6fc281 upstream.
+
+In of_dma_controller_register() routine we are calling of_get_property() as an
+parameter to be32_to_cpup(). In case the property doesn't exist we will get a
+crash.
+
+This patch changes this code to check if we got a valid property first and then
+runs be32_to_cpup() on it.
+
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Robert Richter <robert.richter@calxeda.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma/of-dma.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/dma/of-dma.c
++++ b/drivers/dma/of-dma.c
+@@ -93,6 +93,7 @@ int of_dma_controller_register(struct de
+ {
+       struct of_dma   *ofdma;
+       int             nbcells;
++      const __be32    *prop;
+       if (!np || !of_dma_xlate) {
+               pr_err("%s: not enough information provided\n", __func__);
+@@ -103,8 +104,11 @@ int of_dma_controller_register(struct de
+       if (!ofdma)
+               return -ENOMEM;
+-      nbcells = be32_to_cpup(of_get_property(np, "#dma-cells", NULL));
+-      if (!nbcells) {
++      prop = of_get_property(np, "#dma-cells", NULL);
++      if (prop)
++              nbcells = be32_to_cpup(prop);
++
++      if (!prop || !nbcells) {
+               pr_err("%s: #dma-cells property is missing or invalid\n",
+                      __func__);
+               kfree(ofdma);
index 102b21182a73627acf9cc481918121b79788994f..6d52cebbdaee68d94f50d53d5e5fc051f4d325b2 100644 (file)
@@ -9,3 +9,9 @@ acpica-fix-possible-buffer-overflow-during-a-field-unit-read-operation.patch
 revert-alsa-hda-don-t-set-up-active-streams-twice.patch
 alsa-hda-fix-oops-caused-by-dereference-null-pointer.patch
 alsa-hda-fix-3.9-regression-of-eapd-init-on-conexant-codecs.patch
+dma-of-check-properties-value-before-running-be32_to_cpup-on-it.patch
+dm-table-fix-write-same-support.patch
+dm-stripe-fix-regression-in-stripe_width-calculation.patch
+dm-bufio-avoid-a-possible-__vmalloc-deadlock.patch
+dm-snapshot-fix-error-return-code-in-snapshot_ctr.patch
+dm-cache-fix-error-return-code-in-cache_create.patch