]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jan 2017 13:29:42 +0000 (14:29 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jan 2017 13:29:42 +0000 (14:29 +0100)
added patches:
asoc-intel-fix-crash-at-suspend-resume-without-card-registration.patch
blk-mq-do-not-invoke-.queue_rq-for-a-stopped-queue.patch
dm-crypt-mark-key-as-invalid-until-properly-loaded.patch
dm-flakey-return-einval-on-interval-bounds-error-in-flakey_ctr.patch
dm-raid-fix-discard-support-regression.patch
dm-rq-fix-a-race-condition-in-rq_completed.patch
dm-space-map-metadata-fix-struct-sm_metadata-leak-on-failed-create.patch
dm-table-an-all_blk_mq-table-must-be-loaded-for-a-blk-mq-dm-device.patch
dm-table-fix-all_blk_mq-inconsistency-when-an-empty-table-is-loaded.patch
pm-opp-don-t-use-opp-structure-outside-of-rcu-protected-section.patch
pm-opp-pass-opp_table-to-dev_pm_opp_put_regulator.patch

12 files changed:
queue-4.9/asoc-intel-fix-crash-at-suspend-resume-without-card-registration.patch [new file with mode: 0644]
queue-4.9/blk-mq-do-not-invoke-.queue_rq-for-a-stopped-queue.patch [new file with mode: 0644]
queue-4.9/dm-crypt-mark-key-as-invalid-until-properly-loaded.patch [new file with mode: 0644]
queue-4.9/dm-flakey-return-einval-on-interval-bounds-error-in-flakey_ctr.patch [new file with mode: 0644]
queue-4.9/dm-raid-fix-discard-support-regression.patch [new file with mode: 0644]
queue-4.9/dm-rq-fix-a-race-condition-in-rq_completed.patch [new file with mode: 0644]
queue-4.9/dm-space-map-metadata-fix-struct-sm_metadata-leak-on-failed-create.patch [new file with mode: 0644]
queue-4.9/dm-table-an-all_blk_mq-table-must-be-loaded-for-a-blk-mq-dm-device.patch [new file with mode: 0644]
queue-4.9/dm-table-fix-all_blk_mq-inconsistency-when-an-empty-table-is-loaded.patch [new file with mode: 0644]
queue-4.9/pm-opp-don-t-use-opp-structure-outside-of-rcu-protected-section.patch [new file with mode: 0644]
queue-4.9/pm-opp-pass-opp_table-to-dev_pm_opp_put_regulator.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/asoc-intel-fix-crash-at-suspend-resume-without-card-registration.patch b/queue-4.9/asoc-intel-fix-crash-at-suspend-resume-without-card-registration.patch
new file mode 100644 (file)
index 0000000..94e33f2
--- /dev/null
@@ -0,0 +1,67 @@
+From 2fc995a87f2efcd803438f07bfecd35cc3d90d32 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 25 Nov 2016 16:54:06 +0100
+Subject: ASoC: intel: Fix crash at suspend/resume without card registration
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 2fc995a87f2efcd803438f07bfecd35cc3d90d32 upstream.
+
+When ASoC Intel SST Medfield driver is probed but without codec / card
+assigned, it causes an Oops and freezes the kernel at suspend/resume,
+
+ PM: Suspending system (freeze)
+ Suspending console(s) (use no_console_suspend to debug)
+ BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
+ IP: [<ffffffffc09d9409>] sst_soc_prepare+0x19/0xa0 [snd_soc_sst_mfld_platform]
+ Oops: 0000 [#1] PREEMPT SMP
+ CPU: 0 PID: 1552 Comm: systemd-sleep Tainted: G W 4.9.0-rc6-1.g5f5c2ad-default #1
+ Call Trace:
+  [<ffffffffb45318f9>] dpm_prepare+0x209/0x460
+  [<ffffffffb4531b61>] dpm_suspend_start+0x11/0x60
+  [<ffffffffb40d3cc2>] suspend_devices_and_enter+0xb2/0x710
+  [<ffffffffb40d462e>] pm_suspend+0x30e/0x390
+  [<ffffffffb40d2eba>] state_store+0x8a/0x90
+  [<ffffffffb43c670f>] kobj_attr_store+0xf/0x20
+  [<ffffffffb42b0d97>] sysfs_kf_write+0x37/0x40
+  [<ffffffffb42b02bc>] kernfs_fop_write+0x11c/0x1b0
+  [<ffffffffb422be68>] __vfs_write+0x28/0x140
+  [<ffffffffb43728a8>] ? apparmor_file_permission+0x18/0x20
+  [<ffffffffb433b2ab>] ? security_file_permission+0x3b/0xc0
+  [<ffffffffb422d095>] vfs_write+0xb5/0x1a0
+  [<ffffffffb422e3d6>] SyS_write+0x46/0xa0
+  [<ffffffffb4719fbb>] entry_SYSCALL_64_fastpath+0x1e/0xad
+
+Add proper NULL checks in the PM code of mdfld driver.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Acked-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/intel/atom/sst-mfld-platform-pcm.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
++++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+@@ -771,6 +771,9 @@ static int sst_soc_prepare(struct device
+       struct sst_data *drv = dev_get_drvdata(dev);
+       struct snd_soc_pcm_runtime *rtd;
++      if (!drv->soc_card)
++              return 0;
++
+       /* suspend all pcms first */
+       snd_soc_suspend(drv->soc_card->dev);
+       snd_soc_poweroff(drv->soc_card->dev);
+@@ -793,6 +796,9 @@ static void sst_soc_complete(struct devi
+       struct sst_data *drv = dev_get_drvdata(dev);
+       struct snd_soc_pcm_runtime *rtd;
++      if (!drv->soc_card)
++              return;
++
+       /* restart SSPs */
+       list_for_each_entry(rtd, &drv->soc_card->rtd_list, list) {
+               struct snd_soc_dai *dai = rtd->cpu_dai;
diff --git a/queue-4.9/blk-mq-do-not-invoke-.queue_rq-for-a-stopped-queue.patch b/queue-4.9/blk-mq-do-not-invoke-.queue_rq-for-a-stopped-queue.patch
new file mode 100644 (file)
index 0000000..a77a4c8
--- /dev/null
@@ -0,0 +1,42 @@
+From bc27c01b5c46d3bfec42c96537c7a3fae0bb2cc4 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Fri, 28 Oct 2016 17:18:48 -0700
+Subject: blk-mq: Do not invoke .queue_rq() for a stopped queue
+
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+
+commit bc27c01b5c46d3bfec42c96537c7a3fae0bb2cc4 upstream.
+
+The meaning of the BLK_MQ_S_STOPPED flag is "do not call
+.queue_rq()". Hence modify blk_mq_make_request() such that requests
+are queued instead of issued if a queue has been stopped.
+
+Reported-by: Ming Lei <tom.leiming@gmail.com>
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Ming Lei <tom.leiming@gmail.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-mq.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1332,9 +1332,9 @@ static blk_qc_t blk_mq_make_request(stru
+               blk_mq_put_ctx(data.ctx);
+               if (!old_rq)
+                       goto done;
+-              if (!blk_mq_direct_issue_request(old_rq, &cookie))
+-                      goto done;
+-              blk_mq_insert_request(old_rq, false, true, true);
++              if (test_bit(BLK_MQ_S_STOPPED, &data.hctx->state) ||
++                  blk_mq_direct_issue_request(old_rq, &cookie) != 0)
++                      blk_mq_insert_request(old_rq, false, true, true);
+               goto done;
+       }
diff --git a/queue-4.9/dm-crypt-mark-key-as-invalid-until-properly-loaded.patch b/queue-4.9/dm-crypt-mark-key-as-invalid-until-properly-loaded.patch
new file mode 100644 (file)
index 0000000..0507692
--- /dev/null
@@ -0,0 +1,43 @@
+From 265e9098bac02bc5e36cda21fdbad34cb5b2f48d Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Wed, 2 Nov 2016 15:02:08 +0100
+Subject: dm crypt: mark key as invalid until properly loaded
+
+From: Ondrej Kozina <okozina@redhat.com>
+
+commit 265e9098bac02bc5e36cda21fdbad34cb5b2f48d upstream.
+
+In crypt_set_key(), if a failure occurs while replacing the old key
+(e.g. tfm->setkey() fails) the key must not have DM_CRYPT_KEY_VALID flag
+set.  Otherwise, the crypto layer would have an invalid key that still
+has DM_CRYPT_KEY_VALID flag set.
+
+Signed-off-by: Ondrej Kozina <okozina@redhat.com>
+Reviewed-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-crypt.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -1503,12 +1503,15 @@ static int crypt_set_key(struct crypt_co
+       if (!cc->key_size && strcmp(key, "-"))
+               goto out;
++      /* clear the flag since following operations may invalidate previously valid key */
++      clear_bit(DM_CRYPT_KEY_VALID, &cc->flags);
++
+       if (cc->key_size && crypt_decode_key(cc->key, key, cc->key_size) < 0)
+               goto out;
+-      set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+-
+       r = crypt_setkey_allcpus(cc);
++      if (!r)
++              set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+ out:
+       /* Hex key string not needed after here, so wipe it. */
diff --git a/queue-4.9/dm-flakey-return-einval-on-interval-bounds-error-in-flakey_ctr.patch b/queue-4.9/dm-flakey-return-einval-on-interval-bounds-error-in-flakey_ctr.patch
new file mode 100644 (file)
index 0000000..f6b3b4b
--- /dev/null
@@ -0,0 +1,37 @@
+From bff7e067ee518f9ed7e1cbc63e4c9e01670d0b71 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <weiyj.lk@gmail.com>
+Date: Mon, 8 Aug 2016 14:09:27 +0000
+Subject: dm flakey: return -EINVAL on interval bounds error in flakey_ctr()
+
+From: Wei Yongjun <weiyj.lk@gmail.com>
+
+commit bff7e067ee518f9ed7e1cbc63e4c9e01670d0b71 upstream.
+
+Fix to return error code -EINVAL instead of 0, as is done elsewhere in
+this function.
+
+Fixes: e80d1c805a3b ("dm: do not override error code returned from dm_get_device()")
+Signed-off-by: Wei Yongjun <weiyj.lk@gmail.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-flakey.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/md/dm-flakey.c
++++ b/drivers/md/dm-flakey.c
+@@ -200,11 +200,13 @@ static int flakey_ctr(struct dm_target *
+       if (!(fc->up_interval + fc->down_interval)) {
+               ti->error = "Total (up + down) interval is zero";
++              r = -EINVAL;
+               goto bad;
+       }
+       if (fc->up_interval + fc->down_interval < fc->up_interval) {
+               ti->error = "Interval overflow";
++              r = -EINVAL;
+               goto bad;
+       }
diff --git a/queue-4.9/dm-raid-fix-discard-support-regression.patch b/queue-4.9/dm-raid-fix-discard-support-regression.patch
new file mode 100644 (file)
index 0000000..35bcd34
--- /dev/null
@@ -0,0 +1,50 @@
+From 11e2968478edc07a75ee1efb45011b3033c621c2 Mon Sep 17 00:00:00 2001
+From: Heinz Mauelshagen <heinzm@redhat.com>
+Date: Tue, 29 Nov 2016 22:37:30 +0100
+Subject: dm raid: fix discard support regression
+
+From: Heinz Mauelshagen <heinzm@redhat.com>
+
+commit 11e2968478edc07a75ee1efb45011b3033c621c2 upstream.
+
+Commit ecbfb9f118 ("dm raid: add raid level takeover support") moved the
+configure_discard_support() call from raid_ctr() to raid_preresume().
+
+Enabling/disabling discard _must_ happen during table load (through the
+.ctr hook).  Fix this regression by moving the
+configure_discard_support() call back to raid_ctr().
+
+Fixes: ecbfb9f118 ("dm raid: add raid level takeover support")
+Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-raid.c |    9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -2994,6 +2994,9 @@ static int raid_ctr(struct dm_target *ti
+               }
+       }
++      /* Disable/enable discard support on raid set. */
++      configure_discard_support(rs);
++
+       mddev_unlock(&rs->md);
+       return 0;
+@@ -3580,12 +3583,6 @@ static int raid_preresume(struct dm_targ
+       if (test_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags))
+               rs_update_sbs(rs);
+-      /*
+-       * Disable/enable discard support on raid set after any
+-       * conversion, because devices can have been added
+-       */
+-      configure_discard_support(rs);
+-
+       /* Load the bitmap from disk unless raid0 */
+       r = __load_dirty_region_bitmap(rs);
+       if (r)
diff --git a/queue-4.9/dm-rq-fix-a-race-condition-in-rq_completed.patch b/queue-4.9/dm-rq-fix-a-race-condition-in-rq_completed.patch
new file mode 100644 (file)
index 0000000..3e1aa46
--- /dev/null
@@ -0,0 +1,47 @@
+From d15bb3a6467e102e60d954aadda5fb19ce6fd8ec Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Fri, 11 Nov 2016 17:05:27 -0800
+Subject: dm rq: fix a race condition in rq_completed()
+
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+
+commit d15bb3a6467e102e60d954aadda5fb19ce6fd8ec upstream.
+
+It is required to hold the queue lock when calling blk_run_queue_async()
+to avoid that a race between blk_run_queue_async() and
+blk_cleanup_queue() is triggered.
+
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-rq.c |   10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -226,6 +226,9 @@ static void rq_end_stats(struct mapped_d
+  */
+ static void rq_completed(struct mapped_device *md, int rw, bool run_queue)
+ {
++      struct request_queue *q = md->queue;
++      unsigned long flags;
++
+       atomic_dec(&md->pending[rw]);
+       /* nudge anyone waiting on suspend queue */
+@@ -238,8 +241,11 @@ static void rq_completed(struct mapped_d
+        * back into ->request_fn() could deadlock attempting to grab the
+        * queue lock again.
+        */
+-      if (!md->queue->mq_ops && run_queue)
+-              blk_run_queue_async(md->queue);
++      if (!q->mq_ops && run_queue) {
++              spin_lock_irqsave(q->queue_lock, flags);
++              blk_run_queue_async(q);
++              spin_unlock_irqrestore(q->queue_lock, flags);
++      }
+       /*
+        * dm_put() must be at the end of this function. See the comment above
diff --git a/queue-4.9/dm-space-map-metadata-fix-struct-sm_metadata-leak-on-failed-create.patch b/queue-4.9/dm-space-map-metadata-fix-struct-sm_metadata-leak-on-failed-create.patch
new file mode 100644 (file)
index 0000000..ca15acf
--- /dev/null
@@ -0,0 +1,57 @@
+From 314c25c56c1ee5026cf99c570bdfe01847927acb Mon Sep 17 00:00:00 2001
+From: Benjamin Marzinski <bmarzins@redhat.com>
+Date: Wed, 30 Nov 2016 17:56:14 -0600
+Subject: dm space map metadata: fix 'struct sm_metadata' leak on failed create
+
+From: Benjamin Marzinski <bmarzins@redhat.com>
+
+commit 314c25c56c1ee5026cf99c570bdfe01847927acb upstream.
+
+In dm_sm_metadata_create() we temporarily change the dm_space_map
+operations from 'ops' (whose .destroy function deallocates the
+sm_metadata) to 'bootstrap_ops' (whose .destroy function doesn't).
+
+If dm_sm_metadata_create() fails in sm_ll_new_metadata() or
+sm_ll_extend(), it exits back to dm_tm_create_internal(), which calls
+dm_sm_destroy() with the intention of freeing the sm_metadata, but it
+doesn't (because the dm_space_map operations is still set to
+'bootstrap_ops').
+
+Fix this by setting the dm_space_map operations back to 'ops' if
+dm_sm_metadata_create() fails when it is set to 'bootstrap_ops'.
+
+Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
+Acked-by: Joe Thornber <ejt@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/persistent-data/dm-space-map-metadata.c |   14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+--- a/drivers/md/persistent-data/dm-space-map-metadata.c
++++ b/drivers/md/persistent-data/dm-space-map-metadata.c
+@@ -775,17 +775,15 @@ int dm_sm_metadata_create(struct dm_spac
+       memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm));
+       r = sm_ll_new_metadata(&smm->ll, tm);
++      if (!r) {
++              if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS)
++                      nr_blocks = DM_SM_METADATA_MAX_BLOCKS;
++              r = sm_ll_extend(&smm->ll, nr_blocks);
++      }
++      memcpy(&smm->sm, &ops, sizeof(smm->sm));
+       if (r)
+               return r;
+-      if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS)
+-              nr_blocks = DM_SM_METADATA_MAX_BLOCKS;
+-      r = sm_ll_extend(&smm->ll, nr_blocks);
+-      if (r)
+-              return r;
+-
+-      memcpy(&smm->sm, &ops, sizeof(smm->sm));
+-
+       /*
+        * Now we need to update the newly created data structures with the
+        * allocated blocks that they were built from.
diff --git a/queue-4.9/dm-table-an-all_blk_mq-table-must-be-loaded-for-a-blk-mq-dm-device.patch b/queue-4.9/dm-table-an-all_blk_mq-table-must-be-loaded-for-a-blk-mq-dm-device.patch
new file mode 100644 (file)
index 0000000..63f9673
--- /dev/null
@@ -0,0 +1,37 @@
+From 301fc3f5efb98633115bd887655b19f42c6dfaa8 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Wed, 7 Dec 2016 16:56:06 -0800
+Subject: dm table: an 'all_blk_mq' table must be loaded for a blk-mq DM device
+
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+
+commit 301fc3f5efb98633115bd887655b19f42c6dfaa8 upstream.
+
+When dm_table_set_type() is used by a target to establish a DM table's
+type (e.g. DM_TYPE_MQ_REQUEST_BASED in the case of DM multipath) the
+DM core must go on to verify that the devices in the table are
+compatible with the established type.
+
+Fixes: e83068a5 ("dm mpath: add optional "queue_mode" feature")
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-table.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -981,6 +981,11 @@ verify_rq_based:
+               t->all_blk_mq = true;
+       }
++      if (t->type == DM_TYPE_MQ_REQUEST_BASED && !t->all_blk_mq) {
++              DMERR("table load rejected: all devices are not blk-mq request-stackable");
++              return -EINVAL;
++      }
++
+       return 0;
+ }
diff --git a/queue-4.9/dm-table-fix-all_blk_mq-inconsistency-when-an-empty-table-is-loaded.patch b/queue-4.9/dm-table-fix-all_blk_mq-inconsistency-when-an-empty-table-is-loaded.patch
new file mode 100644 (file)
index 0000000..01993b3
--- /dev/null
@@ -0,0 +1,63 @@
+From 6936c12cf809850180b24947271b8f068fdb15e9 Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snitzer@redhat.com>
+Date: Wed, 23 Nov 2016 13:51:09 -0500
+Subject: dm table: fix 'all_blk_mq' inconsistency when an empty table is loaded
+
+From: Mike Snitzer <snitzer@redhat.com>
+
+commit 6936c12cf809850180b24947271b8f068fdb15e9 upstream.
+
+An earlier DM multipath table could have been build ontop of underlying
+devices that were all using blk-mq.  In that case, if that active
+multipath table is replaced with an empty DM multipath table (that
+reflects all paths have failed) then it is important that the
+'all_blk_mq' state of the active table is transfered to the new empty DM
+table.  Otherwise dm-rq.c:dm_old_prep_tio() will incorrectly clone a
+request that isn't needed by the DM multipath target when it is to issue
+IO to an underlying blk-mq device.
+
+Fixes: e83068a5 ("dm mpath: add optional "queue_mode" feature")
+Reported-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Tested-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-table.c |   19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -924,12 +924,6 @@ static int dm_table_determine_type(struc
+       BUG_ON(!request_based); /* No targets in this table */
+-      if (list_empty(devices) && __table_type_request_based(live_md_type)) {
+-              /* inherit live MD type */
+-              t->type = live_md_type;
+-              return 0;
+-      }
+-
+       /*
+        * The only way to establish DM_TYPE_MQ_REQUEST_BASED is by
+        * having a compatible target use dm_table_set_type.
+@@ -948,6 +942,19 @@ verify_rq_based:
+               return -EINVAL;
+       }
++      if (list_empty(devices)) {
++              int srcu_idx;
++              struct dm_table *live_table = dm_get_live_table(t->md, &srcu_idx);
++
++              /* inherit live table's type and all_blk_mq */
++              if (live_table) {
++                      t->type = live_table->type;
++                      t->all_blk_mq = live_table->all_blk_mq;
++              }
++              dm_put_live_table(t->md, srcu_idx);
++              return 0;
++      }
++
+       /* Non-request-stackable devices can't be used for request-based dm */
+       list_for_each_entry(dd, devices, list) {
+               struct request_queue *q = bdev_get_queue(dd->dm_dev->bdev);
diff --git a/queue-4.9/pm-opp-don-t-use-opp-structure-outside-of-rcu-protected-section.patch b/queue-4.9/pm-opp-don-t-use-opp-structure-outside-of-rcu-protected-section.patch
new file mode 100644 (file)
index 0000000..3c856a4
--- /dev/null
@@ -0,0 +1,61 @@
+From dc39d06fcd7a4a82d72eae7b71e94e888b96d29e Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Thu, 1 Dec 2016 16:28:16 +0530
+Subject: PM / OPP: Don't use OPP structure outside of rcu protected section
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+commit dc39d06fcd7a4a82d72eae7b71e94e888b96d29e upstream.
+
+The OPP structure must not be used out of the rcu protected section.
+Cache the values to be used in separate variables instead.
+
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
+Tested-by: Dave Gerlach <d-gerlach@ti.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/power/opp/core.c |   16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/drivers/base/power/opp/core.c
++++ b/drivers/base/power/opp/core.c
+@@ -584,6 +584,7 @@ int dev_pm_opp_set_rate(struct device *d
+       struct clk *clk;
+       unsigned long freq, old_freq;
+       unsigned long u_volt, u_volt_min, u_volt_max;
++      unsigned long old_u_volt, old_u_volt_min, old_u_volt_max;
+       int ret;
+       if (unlikely(!target_freq)) {
+@@ -633,6 +634,14 @@ int dev_pm_opp_set_rate(struct device *d
+               return ret;
+       }
++      if (IS_ERR(old_opp)) {
++              old_u_volt = 0;
++      } else {
++              old_u_volt = old_opp->u_volt;
++              old_u_volt_min = old_opp->u_volt_min;
++              old_u_volt_max = old_opp->u_volt_max;
++      }
++
+       u_volt = opp->u_volt;
+       u_volt_min = opp->u_volt_min;
+       u_volt_max = opp->u_volt_max;
+@@ -677,9 +686,10 @@ restore_freq:
+                       __func__, old_freq);
+ restore_voltage:
+       /* This shouldn't harm even if the voltages weren't updated earlier */
+-      if (!IS_ERR(old_opp))
+-              _set_opp_voltage(dev, reg, old_opp->u_volt,
+-                               old_opp->u_volt_min, old_opp->u_volt_max);
++      if (old_u_volt) {
++              _set_opp_voltage(dev, reg, old_u_volt, old_u_volt_min,
++                               old_u_volt_max);
++      }
+       return ret;
+ }
diff --git a/queue-4.9/pm-opp-pass-opp_table-to-dev_pm_opp_put_regulator.patch b/queue-4.9/pm-opp-pass-opp_table-to-dev_pm_opp_put_regulator.patch
new file mode 100644 (file)
index 0000000..7ecf20f
--- /dev/null
@@ -0,0 +1,198 @@
+From 91291d9ad92faa65a56a9a19d658d8049b78d3d4 Mon Sep 17 00:00:00 2001
+From: Stephen Boyd <sboyd@codeaurora.org>
+Date: Wed, 30 Nov 2016 16:21:25 +0530
+Subject: PM / OPP: Pass opp_table to dev_pm_opp_put_regulator()
+
+From: Stephen Boyd <sboyd@codeaurora.org>
+
+commit 91291d9ad92faa65a56a9a19d658d8049b78d3d4 upstream.
+
+Joonyoung Shim reported an interesting problem on his ARM octa-core
+Odoroid-XU3 platform. During system suspend, dev_pm_opp_put_regulator()
+was failing for a struct device for which dev_pm_opp_set_regulator() is
+called earlier.
+
+This happened because an earlier call to
+dev_pm_opp_of_cpumask_remove_table() function (from cpufreq-dt.c file)
+removed all the entries from opp_table->dev_list apart from the last CPU
+device in the cpumask of CPUs sharing the OPP.
+
+But both dev_pm_opp_set_regulator() and dev_pm_opp_put_regulator()
+routines get CPU device for the first CPU in the cpumask. And so the OPP
+core failed to find the OPP table for the struct device.
+
+This patch attempts to fix this problem by returning a pointer to the
+opp_table from dev_pm_opp_set_regulator() and using that as the
+parameter to dev_pm_opp_put_regulator(). This ensures that the
+dev_pm_opp_put_regulator() doesn't fail to find the opp table.
+
+Note that similar design problem also exists with other
+dev_pm_opp_put_*() APIs, but those aren't used currently by anyone and
+so we don't need to update them for now.
+
+Reported-by: Joonyoung Shim <jy0922.shim@samsung.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+[ Viresh: Wrote commit log and tested on exynos 5250 ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/power/opp/core.c |   22 ++++++----------------
+ drivers/cpufreq/cpufreq-dt.c  |   12 ++++++++----
+ include/linux/pm_opp.h        |   11 ++++++-----
+ 3 files changed, 20 insertions(+), 25 deletions(-)
+
+--- a/drivers/base/power/opp/core.c
++++ b/drivers/base/power/opp/core.c
+@@ -1316,7 +1316,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_na
+  * that this function is *NOT* called under RCU protection or in contexts where
+  * mutex cannot be locked.
+  */
+-int dev_pm_opp_set_regulator(struct device *dev, const char *name)
++struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name)
+ {
+       struct opp_table *opp_table;
+       struct regulator *reg;
+@@ -1354,20 +1354,20 @@ int dev_pm_opp_set_regulator(struct devi
+       opp_table->regulator = reg;
+       mutex_unlock(&opp_table_lock);
+-      return 0;
++      return opp_table;
+ err:
+       _remove_opp_table(opp_table);
+ unlock:
+       mutex_unlock(&opp_table_lock);
+-      return ret;
++      return ERR_PTR(ret);
+ }
+ EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulator);
+ /**
+  * dev_pm_opp_put_regulator() - Releases resources blocked for regulator
+- * @dev: Device for which regulator was set.
++ * @opp_table: OPP table returned from dev_pm_opp_set_regulator().
+  *
+  * Locking: The internal opp_table and opp structures are RCU protected.
+  * Hence this function internally uses RCU updater strategy with mutex locks
+@@ -1375,22 +1375,12 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulat
+  * that this function is *NOT* called under RCU protection or in contexts where
+  * mutex cannot be locked.
+  */
+-void dev_pm_opp_put_regulator(struct device *dev)
++void dev_pm_opp_put_regulator(struct opp_table *opp_table)
+ {
+-      struct opp_table *opp_table;
+-
+       mutex_lock(&opp_table_lock);
+-      /* Check for existing table for 'dev' first */
+-      opp_table = _find_opp_table(dev);
+-      if (IS_ERR(opp_table)) {
+-              dev_err(dev, "Failed to find opp_table: %ld\n",
+-                      PTR_ERR(opp_table));
+-              goto unlock;
+-      }
+-
+       if (IS_ERR(opp_table->regulator)) {
+-              dev_err(dev, "%s: Doesn't have regulator set\n", __func__);
++              pr_err("%s: Doesn't have regulator set\n", __func__);
+               goto unlock;
+       }
+--- a/drivers/cpufreq/cpufreq-dt.c
++++ b/drivers/cpufreq/cpufreq-dt.c
+@@ -28,6 +28,7 @@
+ #include "cpufreq-dt.h"
+ struct private_data {
++      struct opp_table *opp_table;
+       struct device *cpu_dev;
+       struct thermal_cooling_device *cdev;
+       const char *reg_name;
+@@ -143,6 +144,7 @@ static int resources_available(void)
+ static int cpufreq_init(struct cpufreq_policy *policy)
+ {
+       struct cpufreq_frequency_table *freq_table;
++      struct opp_table *opp_table = NULL;
+       struct private_data *priv;
+       struct device *cpu_dev;
+       struct clk *cpu_clk;
+@@ -186,8 +188,9 @@ static int cpufreq_init(struct cpufreq_p
+        */
+       name = find_supply_name(cpu_dev);
+       if (name) {
+-              ret = dev_pm_opp_set_regulator(cpu_dev, name);
+-              if (ret) {
++              opp_table = dev_pm_opp_set_regulator(cpu_dev, name);
++              if (IS_ERR(opp_table)) {
++                      ret = PTR_ERR(opp_table);
+                       dev_err(cpu_dev, "Failed to set regulator for cpu%d: %d\n",
+                               policy->cpu, ret);
+                       goto out_put_clk;
+@@ -237,6 +240,7 @@ static int cpufreq_init(struct cpufreq_p
+       }
+       priv->reg_name = name;
++      priv->opp_table = opp_table;
+       ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
+       if (ret) {
+@@ -285,7 +289,7 @@ out_free_priv:
+ out_free_opp:
+       dev_pm_opp_of_cpumask_remove_table(policy->cpus);
+       if (name)
+-              dev_pm_opp_put_regulator(cpu_dev);
++              dev_pm_opp_put_regulator(opp_table);
+ out_put_clk:
+       clk_put(cpu_clk);
+@@ -300,7 +304,7 @@ static int cpufreq_exit(struct cpufreq_p
+       dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
+       dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
+       if (priv->reg_name)
+-              dev_pm_opp_put_regulator(priv->cpu_dev);
++              dev_pm_opp_put_regulator(priv->opp_table);
+       clk_put(policy->clk);
+       kfree(priv);
+--- a/include/linux/pm_opp.h
++++ b/include/linux/pm_opp.h
+@@ -19,6 +19,7 @@
+ struct dev_pm_opp;
+ struct device;
++struct opp_table;
+ enum dev_pm_opp_event {
+       OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
+@@ -62,8 +63,8 @@ int dev_pm_opp_set_supported_hw(struct d
+ void dev_pm_opp_put_supported_hw(struct device *dev);
+ int dev_pm_opp_set_prop_name(struct device *dev, const char *name);
+ void dev_pm_opp_put_prop_name(struct device *dev);
+-int dev_pm_opp_set_regulator(struct device *dev, const char *name);
+-void dev_pm_opp_put_regulator(struct device *dev);
++struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name);
++void dev_pm_opp_put_regulator(struct opp_table *opp_table);
+ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
+ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
+ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
+@@ -170,12 +171,12 @@ static inline int dev_pm_opp_set_prop_na
+ static inline void dev_pm_opp_put_prop_name(struct device *dev) {}
+-static inline int dev_pm_opp_set_regulator(struct device *dev, const char *name)
++static inline struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name)
+ {
+-      return -ENOTSUPP;
++      return ERR_PTR(-ENOTSUPP);
+ }
+-static inline void dev_pm_opp_put_regulator(struct device *dev) {}
++static inline void dev_pm_opp_put_regulator(struct opp_table *opp_table) {}
+ static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
+ {
index 09a6f0906f599ba4ad82d1cbe84e583cd444d06e..ed427ccc2c0cc19162de31c11a742e519c9f827f 100644 (file)
@@ -53,3 +53,14 @@ nvmet-fix-possible-infinite-loop-triggered-on-hot-namespace-removal.patch
 mm-vmscan.c-set-correct-defer-count-for-shrinker.patch
 mm-page_alloc-keep-pcp-count-and-list-contents-in-sync-if-struct-page-is-corrupted.patch
 usb-gadget-composite-always-set-ep-mult-to-a-sensible-value.patch
+pm-opp-pass-opp_table-to-dev_pm_opp_put_regulator.patch
+pm-opp-don-t-use-opp-structure-outside-of-rcu-protected-section.patch
+blk-mq-do-not-invoke-.queue_rq-for-a-stopped-queue.patch
+dm-table-fix-all_blk_mq-inconsistency-when-an-empty-table-is-loaded.patch
+dm-table-an-all_blk_mq-table-must-be-loaded-for-a-blk-mq-dm-device.patch
+dm-flakey-return-einval-on-interval-bounds-error-in-flakey_ctr.patch
+dm-crypt-mark-key-as-invalid-until-properly-loaded.patch
+dm-rq-fix-a-race-condition-in-rq_completed.patch
+dm-raid-fix-discard-support-regression.patch
+dm-space-map-metadata-fix-struct-sm_metadata-leak-on-failed-create.patch
+asoc-intel-fix-crash-at-suspend-resume-without-card-registration.patch