]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Nov 2016 16:29:27 +0000 (17:29 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Nov 2016 16:29:27 +0000 (17:29 +0100)
added patches:
clk-imx-fix-integer-overflow-in-av-pll-round-rate.patch
clk-mmp-mmp2-fix-return-value-check-in-mmp2_clk_init.patch
clk-mmp-pxa168-fix-return-value-check-in-pxa168_clk_init.patch
clk-mmp-pxa910-fix-return-value-check-in-pxa910_clk_init.patch
ib-cm-mark-stale-cm-id-s-whenever-the-mad-agent-was-unregistered.patch
ib-core-avoid-unsigned-int-overflow-in-sg_alloc_table.patch
ib-hfi1-remove-incorrect-is_err-check.patch
ib-mlx4-check-gid_index-return-value.patch
ib-mlx4-fix-create-cq-error-flow.patch
ib-mlx5-fix-fatal-error-dispatching.patch
ib-mlx5-fix-memory-leak-in-query-device.patch
ib-mlx5-fix-null-pointer-dereference-on-debug-print.patch
ib-mlx5-use-cache-line-size-to-select-cqe-stride.patch
ib-mlx5-validate-requested-rqt-size.patch
ib-rxe-clear-queue-buffer-when-modifying-qp-to-reset.patch
ib-rxe-fix-handling-of-erroneous-wr.patch
ib-rxe-fix-kernel-panic-in-udp-tunnel-with-gro-and-rx-checksum.patch
ib-rxe-update-qp-state-for-user-query.patch
ib-uverbs-fix-leak-of-xrc-target-qps.patch
iwlwifi-mvm-fix-d3_test-with-unified-d0-d3-images.patch
iwlwifi-mvm-fix-netdetect-starting-stopping-for-unified-images.patch
iwlwifi-mvm-wake-the-wait-queue-when-the-rx-sync-counter-is-zero.patch
iwlwifi-pcie-fix-splc-structure-parsing.patch
iwlwifi-pcie-mark-command-queue-lock-with-separate-lockdep-class.patch
mfd-core-fix-device-reference-leak-in-mfd_clone_cell.patch
netfilter-nft_dynset-fix-element-timeout-for-hz-1000.patch
perf-hists-fix-column-length-on-hierarchy.patch
pm-sleep-don-t-suspend-parent-when-async-child-suspend_-noirq-late-fails.patch
pm-sleep-fix-device-reference-leak-in-test_suspend.patch
rtc-omap-fix-selecting-external-osc.patch
sunrpc-svc_age_temp_xprts_now-should-not-call-setsockopt-non-tcp-transports.patch
uwb-fix-device-reference-leaks.patch

33 files changed:
queue-4.8/clk-imx-fix-integer-overflow-in-av-pll-round-rate.patch [new file with mode: 0644]
queue-4.8/clk-mmp-mmp2-fix-return-value-check-in-mmp2_clk_init.patch [new file with mode: 0644]
queue-4.8/clk-mmp-pxa168-fix-return-value-check-in-pxa168_clk_init.patch [new file with mode: 0644]
queue-4.8/clk-mmp-pxa910-fix-return-value-check-in-pxa910_clk_init.patch [new file with mode: 0644]
queue-4.8/ib-cm-mark-stale-cm-id-s-whenever-the-mad-agent-was-unregistered.patch [new file with mode: 0644]
queue-4.8/ib-core-avoid-unsigned-int-overflow-in-sg_alloc_table.patch [new file with mode: 0644]
queue-4.8/ib-hfi1-remove-incorrect-is_err-check.patch [new file with mode: 0644]
queue-4.8/ib-mlx4-check-gid_index-return-value.patch [new file with mode: 0644]
queue-4.8/ib-mlx4-fix-create-cq-error-flow.patch [new file with mode: 0644]
queue-4.8/ib-mlx5-fix-fatal-error-dispatching.patch [new file with mode: 0644]
queue-4.8/ib-mlx5-fix-memory-leak-in-query-device.patch [new file with mode: 0644]
queue-4.8/ib-mlx5-fix-null-pointer-dereference-on-debug-print.patch [new file with mode: 0644]
queue-4.8/ib-mlx5-use-cache-line-size-to-select-cqe-stride.patch [new file with mode: 0644]
queue-4.8/ib-mlx5-validate-requested-rqt-size.patch [new file with mode: 0644]
queue-4.8/ib-rxe-clear-queue-buffer-when-modifying-qp-to-reset.patch [new file with mode: 0644]
queue-4.8/ib-rxe-fix-handling-of-erroneous-wr.patch [new file with mode: 0644]
queue-4.8/ib-rxe-fix-kernel-panic-in-udp-tunnel-with-gro-and-rx-checksum.patch [new file with mode: 0644]
queue-4.8/ib-rxe-update-qp-state-for-user-query.patch [new file with mode: 0644]
queue-4.8/ib-uverbs-fix-leak-of-xrc-target-qps.patch [new file with mode: 0644]
queue-4.8/iwlwifi-mvm-fix-d3_test-with-unified-d0-d3-images.patch [new file with mode: 0644]
queue-4.8/iwlwifi-mvm-fix-netdetect-starting-stopping-for-unified-images.patch [new file with mode: 0644]
queue-4.8/iwlwifi-mvm-wake-the-wait-queue-when-the-rx-sync-counter-is-zero.patch [new file with mode: 0644]
queue-4.8/iwlwifi-pcie-fix-splc-structure-parsing.patch [new file with mode: 0644]
queue-4.8/iwlwifi-pcie-mark-command-queue-lock-with-separate-lockdep-class.patch [new file with mode: 0644]
queue-4.8/mfd-core-fix-device-reference-leak-in-mfd_clone_cell.patch [new file with mode: 0644]
queue-4.8/netfilter-nft_dynset-fix-element-timeout-for-hz-1000.patch [new file with mode: 0644]
queue-4.8/perf-hists-fix-column-length-on-hierarchy.patch [new file with mode: 0644]
queue-4.8/pm-sleep-don-t-suspend-parent-when-async-child-suspend_-noirq-late-fails.patch [new file with mode: 0644]
queue-4.8/pm-sleep-fix-device-reference-leak-in-test_suspend.patch [new file with mode: 0644]
queue-4.8/rtc-omap-fix-selecting-external-osc.patch [new file with mode: 0644]
queue-4.8/series
queue-4.8/sunrpc-svc_age_temp_xprts_now-should-not-call-setsockopt-non-tcp-transports.patch [new file with mode: 0644]
queue-4.8/uwb-fix-device-reference-leaks.patch [new file with mode: 0644]

diff --git a/queue-4.8/clk-imx-fix-integer-overflow-in-av-pll-round-rate.patch b/queue-4.8/clk-imx-fix-integer-overflow-in-av-pll-round-rate.patch
new file mode 100644 (file)
index 0000000..2e7597a
--- /dev/null
@@ -0,0 +1,53 @@
+From 5c2f117a22e46a4afee6ddee29b653a7a2a6b41f Mon Sep 17 00:00:00 2001
+From: Emil Lundmark <emil@limesaudio.com>
+Date: Wed, 12 Oct 2016 12:31:40 +0200
+Subject: clk: imx: fix integer overflow in AV PLL round rate
+
+From: Emil Lundmark <emil@limesaudio.com>
+
+commit 5c2f117a22e46a4afee6ddee29b653a7a2a6b41f upstream.
+
+Since 'parent_rate * mfn' may overflow 32 bits, the result should be
+stored using 64 bits.
+
+The problem was discovered when trying to set the rate of the audio PLL
+(pll4_post_div) on an i.MX6Q. The desired rate was 196.608 MHz, but
+the actual rate returned was 192.000570 MHz. The round rate function should
+have been able to return 196.608 MHz, i.e., the desired rate.
+
+Fixes: ba7f4f557eb6 ("clk: imx: correct AV PLL rate formula")
+Cc: Anson Huang <b20788@freescale.com>
+Signed-off-by: Emil Lundmark <emil@limesaudio.com>
+Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
+Acked-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/imx/clk-pllv3.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/imx/clk-pllv3.c
++++ b/drivers/clk/imx/clk-pllv3.c
+@@ -223,7 +223,7 @@ static unsigned long clk_pllv3_av_recalc
+       temp64 *= mfn;
+       do_div(temp64, mfd);
+-      return (parent_rate * div) + (u32)temp64;
++      return parent_rate * div + (unsigned long)temp64;
+ }
+ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
+@@ -247,7 +247,11 @@ static long clk_pllv3_av_round_rate(stru
+       do_div(temp64, parent_rate);
+       mfn = temp64;
+-      return parent_rate * div + parent_rate * mfn / mfd;
++      temp64 = (u64)parent_rate;
++      temp64 *= mfn;
++      do_div(temp64, mfd);
++
++      return parent_rate * div + (unsigned long)temp64;
+ }
+ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
diff --git a/queue-4.8/clk-mmp-mmp2-fix-return-value-check-in-mmp2_clk_init.patch b/queue-4.8/clk-mmp-mmp2-fix-return-value-check-in-mmp2_clk_init.patch
new file mode 100644 (file)
index 0000000..e89f3ec
--- /dev/null
@@ -0,0 +1,32 @@
+From a29e52a6e66f4c0c895e7083e4bad2e7957f1fb5 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <weiyongjun1@huawei.com>
+Date: Sat, 17 Sep 2016 15:54:13 +0000
+Subject: clk: mmp: mmp2: fix return value check in mmp2_clk_init()
+
+From: Wei Yongjun <weiyongjun1@huawei.com>
+
+commit a29e52a6e66f4c0c895e7083e4bad2e7957f1fb5 upstream.
+
+Fix the retrn value check which testing the wrong variable
+in mmp2_clk_init().
+
+Fixes: 1ec770d92a62 ("clk: mmp: add mmp2 DT support for clock driver")
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/mmp/clk-of-mmp2.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/mmp/clk-of-mmp2.c
++++ b/drivers/clk/mmp/clk-of-mmp2.c
+@@ -313,7 +313,7 @@ static void __init mmp2_clk_init(struct
+       }
+       pxa_unit->apmu_base = of_iomap(np, 1);
+-      if (!pxa_unit->mpmu_base) {
++      if (!pxa_unit->apmu_base) {
+               pr_err("failed to map apmu registers\n");
+               return;
+       }
diff --git a/queue-4.8/clk-mmp-pxa168-fix-return-value-check-in-pxa168_clk_init.patch b/queue-4.8/clk-mmp-pxa168-fix-return-value-check-in-pxa168_clk_init.patch
new file mode 100644 (file)
index 0000000..1c484c4
--- /dev/null
@@ -0,0 +1,32 @@
+From deab07261d54b4db7b627d38e0efac97f176c6d6 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <weiyongjun1@huawei.com>
+Date: Sat, 17 Sep 2016 15:54:28 +0000
+Subject: clk: mmp: pxa168: fix return value check in pxa168_clk_init()
+
+From: Wei Yongjun <weiyongjun1@huawei.com>
+
+commit deab07261d54b4db7b627d38e0efac97f176c6d6 upstream.
+
+Fix the retrn value check which testing the wrong variable
+in pxa168_clk_init().
+
+Fixes: ab08aefcd12d ("clk: mmp: add pxa168 DT support for clock driver")
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/mmp/clk-of-pxa168.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/mmp/clk-of-pxa168.c
++++ b/drivers/clk/mmp/clk-of-pxa168.c
+@@ -262,7 +262,7 @@ static void __init pxa168_clk_init(struc
+       }
+       pxa_unit->apmu_base = of_iomap(np, 1);
+-      if (!pxa_unit->mpmu_base) {
++      if (!pxa_unit->apmu_base) {
+               pr_err("failed to map apmu registers\n");
+               return;
+       }
diff --git a/queue-4.8/clk-mmp-pxa910-fix-return-value-check-in-pxa910_clk_init.patch b/queue-4.8/clk-mmp-pxa910-fix-return-value-check-in-pxa910_clk_init.patch
new file mode 100644 (file)
index 0000000..271731d
--- /dev/null
@@ -0,0 +1,41 @@
+From 10f2bfb092e3b49000526c02cfe8b2abbbdbb752 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <weiyongjun1@huawei.com>
+Date: Sat, 17 Sep 2016 15:55:56 +0000
+Subject: clk: mmp: pxa910: fix return value check in pxa910_clk_init()
+
+From: Wei Yongjun <weiyongjun1@huawei.com>
+
+commit 10f2bfb092e3b49000526c02cfe8b2abbbdbb752 upstream.
+
+Fix the retrn value check which testing the wrong variable
+in pxa910_clk_init().
+
+Fixes: 2bc61da9f7ff ("clk: mmp: add pxa910 DT support for clock driver")
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/mmp/clk-of-pxa910.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/mmp/clk-of-pxa910.c
++++ b/drivers/clk/mmp/clk-of-pxa910.c
+@@ -282,7 +282,7 @@ static void __init pxa910_clk_init(struc
+       }
+       pxa_unit->apmu_base = of_iomap(np, 1);
+-      if (!pxa_unit->mpmu_base) {
++      if (!pxa_unit->apmu_base) {
+               pr_err("failed to map apmu registers\n");
+               return;
+       }
+@@ -294,7 +294,7 @@ static void __init pxa910_clk_init(struc
+       }
+       pxa_unit->apbcp_base = of_iomap(np, 3);
+-      if (!pxa_unit->mpmu_base) {
++      if (!pxa_unit->apbcp_base) {
+               pr_err("failed to map apbcp registers\n");
+               return;
+       }
diff --git a/queue-4.8/ib-cm-mark-stale-cm-id-s-whenever-the-mad-agent-was-unregistered.patch b/queue-4.8/ib-cm-mark-stale-cm-id-s-whenever-the-mad-agent-was-unregistered.patch
new file mode 100644 (file)
index 0000000..6ad53af
--- /dev/null
@@ -0,0 +1,359 @@
+From 9db0ff53cb9b43ed75bacd42a89c1a0ab048b2b0 Mon Sep 17 00:00:00 2001
+From: Mark Bloch <markb@mellanox.com>
+Date: Thu, 27 Oct 2016 16:36:27 +0300
+Subject: IB/cm: Mark stale CM id's whenever the mad agent was unregistered
+
+From: Mark Bloch <markb@mellanox.com>
+
+commit 9db0ff53cb9b43ed75bacd42a89c1a0ab048b2b0 upstream.
+
+When there is a CM id object that has port assigned to it, it means that
+the cm-id asked for the specific port that it should go by it, but if
+that port was removed (hot-unplug event) the cm-id was not updated.
+In order to fix that the port keeps a list of all the cm-id's that are
+planning to go by it, whenever the port is removed it marks all of them
+as invalid.
+
+This commit fixes a kernel panic which happens when running traffic between
+guests and we force reboot a guest mid traffic, it triggers a kernel panic:
+
+ Call Trace:
+  [<ffffffff815271fa>] ? panic+0xa7/0x16f
+  [<ffffffff8152b534>] ? oops_end+0xe4/0x100
+  [<ffffffff8104a00b>] ? no_context+0xfb/0x260
+  [<ffffffff81084db2>] ? del_timer_sync+0x22/0x30
+  [<ffffffff8104a295>] ? __bad_area_nosemaphore+0x125/0x1e0
+  [<ffffffff81084240>] ? process_timeout+0x0/0x10
+  [<ffffffff8104a363>] ? bad_area_nosemaphore+0x13/0x20
+  [<ffffffff8104aabf>] ? __do_page_fault+0x31f/0x480
+  [<ffffffff81065df0>] ? default_wake_function+0x0/0x20
+  [<ffffffffa0752675>] ? free_msg+0x55/0x70 [mlx5_core]
+  [<ffffffffa0753434>] ? cmd_exec+0x124/0x840 [mlx5_core]
+  [<ffffffff8105a924>] ? find_busiest_group+0x244/0x9f0
+  [<ffffffff8152d45e>] ? do_page_fault+0x3e/0xa0
+  [<ffffffff8152a815>] ? page_fault+0x25/0x30
+  [<ffffffffa024da25>] ? cm_alloc_msg+0x35/0xc0 [ib_cm]
+  [<ffffffffa024e821>] ? ib_send_cm_dreq+0xb1/0x1e0 [ib_cm]
+  [<ffffffffa024f836>] ? cm_destroy_id+0x176/0x320 [ib_cm]
+  [<ffffffffa024fb00>] ? ib_destroy_cm_id+0x10/0x20 [ib_cm]
+  [<ffffffffa034f527>] ? ipoib_cm_free_rx_reap_list+0xa7/0x110 [ib_ipoib]
+  [<ffffffffa034f590>] ? ipoib_cm_rx_reap+0x0/0x20 [ib_ipoib]
+  [<ffffffffa034f5a5>] ? ipoib_cm_rx_reap+0x15/0x20 [ib_ipoib]
+  [<ffffffff81094d20>] ? worker_thread+0x170/0x2a0
+  [<ffffffff8109b2a0>] ? autoremove_wake_function+0x0/0x40
+  [<ffffffff81094bb0>] ? worker_thread+0x0/0x2a0
+  [<ffffffff8109aef6>] ? kthread+0x96/0xa0
+  [<ffffffff8100c20a>] ? child_rip+0xa/0x20
+  [<ffffffff8109ae60>] ? kthread+0x0/0xa0
+  [<ffffffff8100c200>] ? child_rip+0x0/0x20
+
+Fixes: a977049dacde ("[PATCH] IB: Add the kernel CM implementation")
+Signed-off-by: Mark Bloch <markb@mellanox.com>
+Signed-off-by: Erez Shitrit <erezsh@mellanox.com>
+Reviewed-by: Maor Gottlieb <maorg@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/cm.c |  126 +++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 110 insertions(+), 16 deletions(-)
+
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -80,6 +80,8 @@ static struct ib_cm {
+       __be32 random_id_operand;
+       struct list_head timewait_list;
+       struct workqueue_struct *wq;
++      /* Sync on cm change port state */
++      spinlock_t state_lock;
+ } cm;
+ /* Counter indexes ordered by attribute ID */
+@@ -161,6 +163,8 @@ struct cm_port {
+       struct ib_mad_agent *mad_agent;
+       struct kobject port_obj;
+       u8 port_num;
++      struct list_head cm_priv_prim_list;
++      struct list_head cm_priv_altr_list;
+       struct cm_counter_group counter_group[CM_COUNTER_GROUPS];
+ };
+@@ -241,6 +245,12 @@ struct cm_id_private {
+       u8 service_timeout;
+       u8 target_ack_delay;
++      struct list_head prim_list;
++      struct list_head altr_list;
++      /* Indicates that the send port mad is registered and av is set */
++      int prim_send_port_not_ready;
++      int altr_send_port_not_ready;
++
+       struct list_head work_list;
+       atomic_t work_count;
+ };
+@@ -259,20 +269,47 @@ static int cm_alloc_msg(struct cm_id_pri
+       struct ib_mad_agent *mad_agent;
+       struct ib_mad_send_buf *m;
+       struct ib_ah *ah;
++      struct cm_av *av;
++      unsigned long flags, flags2;
++      int ret = 0;
++      /* don't let the port to be released till the agent is down */
++      spin_lock_irqsave(&cm.state_lock, flags2);
++      spin_lock_irqsave(&cm.lock, flags);
++      if (!cm_id_priv->prim_send_port_not_ready)
++              av = &cm_id_priv->av;
++      else if (!cm_id_priv->altr_send_port_not_ready &&
++               (cm_id_priv->alt_av.port))
++              av = &cm_id_priv->alt_av;
++      else {
++              pr_info("%s: not valid CM id\n", __func__);
++              ret = -ENODEV;
++              spin_unlock_irqrestore(&cm.lock, flags);
++              goto out;
++      }
++      spin_unlock_irqrestore(&cm.lock, flags);
++      /* Make sure the port haven't released the mad yet */
+       mad_agent = cm_id_priv->av.port->mad_agent;
+-      ah = ib_create_ah(mad_agent->qp->pd, &cm_id_priv->av.ah_attr);
+-      if (IS_ERR(ah))
+-              return PTR_ERR(ah);
++      if (!mad_agent) {
++              pr_info("%s: not a valid MAD agent\n", __func__);
++              ret = -ENODEV;
++              goto out;
++      }
++      ah = ib_create_ah(mad_agent->qp->pd, &av->ah_attr);
++      if (IS_ERR(ah)) {
++              ret = PTR_ERR(ah);
++              goto out;
++      }
+       m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn,
+-                             cm_id_priv->av.pkey_index,
++                             av->pkey_index,
+                              0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
+                              GFP_ATOMIC,
+                              IB_MGMT_BASE_VERSION);
+       if (IS_ERR(m)) {
+               ib_destroy_ah(ah);
+-              return PTR_ERR(m);
++              ret = PTR_ERR(m);
++              goto out;
+       }
+       /* Timeout set by caller if response is expected. */
+@@ -282,7 +319,10 @@ static int cm_alloc_msg(struct cm_id_pri
+       atomic_inc(&cm_id_priv->refcount);
+       m->context[0] = cm_id_priv;
+       *msg = m;
+-      return 0;
++
++out:
++      spin_unlock_irqrestore(&cm.state_lock, flags2);
++      return ret;
+ }
+ static int cm_alloc_response_msg(struct cm_port *port,
+@@ -352,7 +392,8 @@ static void cm_init_av_for_response(stru
+                          grh, &av->ah_attr);
+ }
+-static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
++static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av,
++                            struct cm_id_private *cm_id_priv)
+ {
+       struct cm_device *cm_dev;
+       struct cm_port *port = NULL;
+@@ -387,7 +428,17 @@ static int cm_init_av_by_path(struct ib_
+                            &av->ah_attr);
+       av->timeout = path->packet_life_time + 1;
+-      return 0;
++      spin_lock_irqsave(&cm.lock, flags);
++      if (&cm_id_priv->av == av)
++              list_add_tail(&cm_id_priv->prim_list, &port->cm_priv_prim_list);
++      else if (&cm_id_priv->alt_av == av)
++              list_add_tail(&cm_id_priv->altr_list, &port->cm_priv_altr_list);
++      else
++              ret = -EINVAL;
++
++      spin_unlock_irqrestore(&cm.lock, flags);
++
++      return ret;
+ }
+ static int cm_alloc_id(struct cm_id_private *cm_id_priv)
+@@ -677,6 +728,8 @@ struct ib_cm_id *ib_create_cm_id(struct
+       spin_lock_init(&cm_id_priv->lock);
+       init_completion(&cm_id_priv->comp);
+       INIT_LIST_HEAD(&cm_id_priv->work_list);
++      INIT_LIST_HEAD(&cm_id_priv->prim_list);
++      INIT_LIST_HEAD(&cm_id_priv->altr_list);
+       atomic_set(&cm_id_priv->work_count, -1);
+       atomic_set(&cm_id_priv->refcount, 1);
+       return &cm_id_priv->id;
+@@ -892,6 +945,15 @@ retest:
+               break;
+       }
++      spin_lock_irq(&cm.lock);
++      if (!list_empty(&cm_id_priv->altr_list) &&
++          (!cm_id_priv->altr_send_port_not_ready))
++              list_del(&cm_id_priv->altr_list);
++      if (!list_empty(&cm_id_priv->prim_list) &&
++          (!cm_id_priv->prim_send_port_not_ready))
++              list_del(&cm_id_priv->prim_list);
++      spin_unlock_irq(&cm.lock);
++
+       cm_free_id(cm_id->local_id);
+       cm_deref_id(cm_id_priv);
+       wait_for_completion(&cm_id_priv->comp);
+@@ -1192,12 +1254,13 @@ int ib_send_cm_req(struct ib_cm_id *cm_i
+               goto out;
+       }
+-      ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av);
++      ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av,
++                               cm_id_priv);
+       if (ret)
+               goto error1;
+       if (param->alternate_path) {
+               ret = cm_init_av_by_path(param->alternate_path,
+-                                       &cm_id_priv->alt_av);
++                                       &cm_id_priv->alt_av, cm_id_priv);
+               if (ret)
+                       goto error1;
+       }
+@@ -1653,7 +1716,8 @@ static int cm_req_handler(struct cm_work
+                       dev_put(gid_attr.ndev);
+               }
+               work->path[0].gid_type = gid_attr.gid_type;
+-              ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
++              ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av,
++                                       cm_id_priv);
+       }
+       if (ret) {
+               int err = ib_get_cached_gid(work->port->cm_dev->ib_device,
+@@ -1672,7 +1736,8 @@ static int cm_req_handler(struct cm_work
+               goto rejected;
+       }
+       if (req_msg->alt_local_lid) {
+-              ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av);
++              ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av,
++                                       cm_id_priv);
+               if (ret) {
+                       ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_ALT_GID,
+                                      &work->path[0].sgid,
+@@ -2727,7 +2792,8 @@ int ib_send_cm_lap(struct ib_cm_id *cm_i
+               goto out;
+       }
+-      ret = cm_init_av_by_path(alternate_path, &cm_id_priv->alt_av);
++      ret = cm_init_av_by_path(alternate_path, &cm_id_priv->alt_av,
++                               cm_id_priv);
+       if (ret)
+               goto out;
+       cm_id_priv->alt_av.timeout =
+@@ -2839,7 +2905,8 @@ static int cm_lap_handler(struct cm_work
+       cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
+                               work->mad_recv_wc->recv_buf.grh,
+                               &cm_id_priv->av);
+-      cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av);
++      cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av,
++                         cm_id_priv);
+       ret = atomic_inc_and_test(&cm_id_priv->work_count);
+       if (!ret)
+               list_add_tail(&work->list, &cm_id_priv->work_list);
+@@ -3031,7 +3098,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id
+               return -EINVAL;
+       cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+-      ret = cm_init_av_by_path(param->path, &cm_id_priv->av);
++      ret = cm_init_av_by_path(param->path, &cm_id_priv->av, cm_id_priv);
+       if (ret)
+               goto out;
+@@ -3468,7 +3535,9 @@ out:
+ static int cm_migrate(struct ib_cm_id *cm_id)
+ {
+       struct cm_id_private *cm_id_priv;
++      struct cm_av tmp_av;
+       unsigned long flags;
++      int tmp_send_port_not_ready;
+       int ret = 0;
+       cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+@@ -3477,7 +3546,14 @@ static int cm_migrate(struct ib_cm_id *c
+           (cm_id->lap_state == IB_CM_LAP_UNINIT ||
+            cm_id->lap_state == IB_CM_LAP_IDLE)) {
+               cm_id->lap_state = IB_CM_LAP_IDLE;
++              /* Swap address vector */
++              tmp_av = cm_id_priv->av;
+               cm_id_priv->av = cm_id_priv->alt_av;
++              cm_id_priv->alt_av = tmp_av;
++              /* Swap port send ready state */
++              tmp_send_port_not_ready = cm_id_priv->prim_send_port_not_ready;
++              cm_id_priv->prim_send_port_not_ready = cm_id_priv->altr_send_port_not_ready;
++              cm_id_priv->altr_send_port_not_ready = tmp_send_port_not_ready;
+       } else
+               ret = -EINVAL;
+       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+@@ -3888,6 +3964,9 @@ static void cm_add_one(struct ib_device
+               port->cm_dev = cm_dev;
+               port->port_num = i;
++              INIT_LIST_HEAD(&port->cm_priv_prim_list);
++              INIT_LIST_HEAD(&port->cm_priv_altr_list);
++
+               ret = cm_create_port_fs(port);
+               if (ret)
+                       goto error1;
+@@ -3945,6 +4024,8 @@ static void cm_remove_one(struct ib_devi
+ {
+       struct cm_device *cm_dev = client_data;
+       struct cm_port *port;
++      struct cm_id_private *cm_id_priv;
++      struct ib_mad_agent *cur_mad_agent;
+       struct ib_port_modify port_modify = {
+               .clr_port_cap_mask = IB_PORT_CM_SUP
+       };
+@@ -3968,15 +4049,27 @@ static void cm_remove_one(struct ib_devi
+               port = cm_dev->port[i-1];
+               ib_modify_port(ib_device, port->port_num, 0, &port_modify);
++              /* Mark all the cm_id's as not valid */
++              spin_lock_irq(&cm.lock);
++              list_for_each_entry(cm_id_priv, &port->cm_priv_altr_list, altr_list)
++                      cm_id_priv->altr_send_port_not_ready = 1;
++              list_for_each_entry(cm_id_priv, &port->cm_priv_prim_list, prim_list)
++                      cm_id_priv->prim_send_port_not_ready = 1;
++              spin_unlock_irq(&cm.lock);
+               /*
+                * We flush the queue here after the going_down set, this
+                * verify that no new works will be queued in the recv handler,
+                * after that we can call the unregister_mad_agent
+                */
+               flush_workqueue(cm.wq);
+-              ib_unregister_mad_agent(port->mad_agent);
++              spin_lock_irq(&cm.state_lock);
++              cur_mad_agent = port->mad_agent;
++              port->mad_agent = NULL;
++              spin_unlock_irq(&cm.state_lock);
++              ib_unregister_mad_agent(cur_mad_agent);
+               cm_remove_port_fs(port);
+       }
++
+       device_unregister(cm_dev->device);
+       kfree(cm_dev);
+ }
+@@ -3989,6 +4082,7 @@ static int __init ib_cm_init(void)
+       INIT_LIST_HEAD(&cm.device_list);
+       rwlock_init(&cm.device_lock);
+       spin_lock_init(&cm.lock);
++      spin_lock_init(&cm.state_lock);
+       cm.listen_service_table = RB_ROOT;
+       cm.listen_service_id = be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID);
+       cm.remote_id_table = RB_ROOT;
diff --git a/queue-4.8/ib-core-avoid-unsigned-int-overflow-in-sg_alloc_table.patch b/queue-4.8/ib-core-avoid-unsigned-int-overflow-in-sg_alloc_table.patch
new file mode 100644 (file)
index 0000000..ab56bf7
--- /dev/null
@@ -0,0 +1,35 @@
+From 3c7ba5760ab8eedec01159b267bb9bfcffe522ac Mon Sep 17 00:00:00 2001
+From: Mark Bloch <markb@mellanox.com>
+Date: Thu, 27 Oct 2016 16:36:31 +0300
+Subject: IB/core: Avoid unsigned int overflow in sg_alloc_table
+
+From: Mark Bloch <markb@mellanox.com>
+
+commit 3c7ba5760ab8eedec01159b267bb9bfcffe522ac upstream.
+
+sg_alloc_table gets unsigned int as parameter while the driver
+returns it as size_t. Check npages isn't greater than maximum
+unsigned int.
+
+Fixes: eeb8461e36c9 ("IB: Refactor umem to use linear SG table")
+Signed-off-by: Mark Bloch <markb@mellanox.com>
+Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/umem.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/infiniband/core/umem.c
++++ b/drivers/infiniband/core/umem.c
+@@ -174,7 +174,7 @@ struct ib_umem *ib_umem_get(struct ib_uc
+       cur_base = addr & PAGE_MASK;
+-      if (npages == 0) {
++      if (npages == 0 || npages > UINT_MAX) {
+               ret = -EINVAL;
+               goto out;
+       }
diff --git a/queue-4.8/ib-hfi1-remove-incorrect-is_err-check.patch b/queue-4.8/ib-hfi1-remove-incorrect-is_err-check.patch
new file mode 100644 (file)
index 0000000..750bfe1
--- /dev/null
@@ -0,0 +1,34 @@
+From 2b16056f845207967a32497f41cf92b57849f934 Mon Sep 17 00:00:00 2001
+From: Dennis Dalessandro <dennis.dalessandro@intel.com>
+Date: Tue, 25 Oct 2016 13:12:46 -0700
+Subject: IB/hfi1: Remove incorrect IS_ERR check
+
+From: Dennis Dalessandro <dennis.dalessandro@intel.com>
+
+commit 2b16056f845207967a32497f41cf92b57849f934 upstream.
+
+Remove IS_ERR check from caching code as the function being called does
+not actually return error pointers.
+
+Fixes: f19bd643dbde: "IB/hfi1: Prevent NULL pointer deferences in caching code"
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Dean Luick <dean.luick@intel.com>
+Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/hfi1/user_sdma.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/infiniband/hw/hfi1/user_sdma.c
++++ b/drivers/infiniband/hw/hfi1/user_sdma.c
+@@ -1152,7 +1152,7 @@ static int pin_vector_pages(struct user_
+       rb_node = hfi1_mmu_rb_extract(pq->handler,
+                                     (unsigned long)iovec->iov.iov_base,
+                                     iovec->iov.iov_len);
+-      if (rb_node && !IS_ERR(rb_node))
++      if (rb_node)
+               node = container_of(rb_node, struct sdma_mmu_node, rb);
+       else
+               rb_node = NULL;
diff --git a/queue-4.8/ib-mlx4-check-gid_index-return-value.patch b/queue-4.8/ib-mlx4-check-gid_index-return-value.patch
new file mode 100644 (file)
index 0000000..412e7a2
--- /dev/null
@@ -0,0 +1,37 @@
+From 37995116fecfce2b61ee3da6e73b3e394c6818f9 Mon Sep 17 00:00:00 2001
+From: Daniel Jurgens <danielj@mellanox.com>
+Date: Thu, 10 Nov 2016 11:30:54 +0200
+Subject: IB/mlx4: Check gid_index return value
+
+From: Daniel Jurgens <danielj@mellanox.com>
+
+commit 37995116fecfce2b61ee3da6e73b3e394c6818f9 upstream.
+
+Check the returned GID index value and return an error if it is invalid.
+
+Fixes: 5070cd2239bd ('IB/mlx4: Replace mechanism for RoCE GID management')
+Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
+Reviewed-by: Mark Bloch <markb@mellanox.com>
+Reviewed-by: Yuval Shaia <yuval.shaia@oracle.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/mlx4/ah.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/infiniband/hw/mlx4/ah.c
++++ b/drivers/infiniband/hw/mlx4/ah.c
+@@ -102,7 +102,10 @@ static struct ib_ah *create_iboe_ah(stru
+       if (vlan_tag < 0x1000)
+               vlan_tag |= (ah_attr->sl & 7) << 13;
+       ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
+-      ah->av.eth.gid_index = mlx4_ib_gid_index_to_real_index(ibdev, ah_attr->port_num, ah_attr->grh.sgid_index);
++      ret = mlx4_ib_gid_index_to_real_index(ibdev, ah_attr->port_num, ah_attr->grh.sgid_index);
++      if (ret < 0)
++              return ERR_PTR(ret);
++      ah->av.eth.gid_index = ret;
+       ah->av.eth.vlan = cpu_to_be16(vlan_tag);
+       ah->av.eth.hop_limit = ah_attr->grh.hop_limit;
+       if (ah_attr->static_rate) {
diff --git a/queue-4.8/ib-mlx4-fix-create-cq-error-flow.patch b/queue-4.8/ib-mlx4-fix-create-cq-error-flow.patch
new file mode 100644 (file)
index 0000000..e65527a
--- /dev/null
@@ -0,0 +1,42 @@
+From 593ff73bcfdc79f79a8a0df55504f75ad3e5d1a9 Mon Sep 17 00:00:00 2001
+From: Matan Barak <matanb@mellanox.com>
+Date: Thu, 10 Nov 2016 11:30:55 +0200
+Subject: IB/mlx4: Fix create CQ error flow
+
+From: Matan Barak <matanb@mellanox.com>
+
+commit 593ff73bcfdc79f79a8a0df55504f75ad3e5d1a9 upstream.
+
+Currently, if ib_copy_to_udata fails, the CQ
+won't be deleted from the radix tree and the HW (HW2SW).
+
+Fixes: 225c7b1feef1 ('IB/mlx4: Add a driver Mellanox ConnectX InfiniBand adapters')
+Signed-off-by: Matan Barak <matanb@mellanox.com>
+Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
+Reviewed-by: Mark Bloch <markb@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/mlx4/cq.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/infiniband/hw/mlx4/cq.c
++++ b/drivers/infiniband/hw/mlx4/cq.c
+@@ -253,11 +253,14 @@ struct ib_cq *mlx4_ib_create_cq(struct i
+       if (context)
+               if (ib_copy_to_udata(udata, &cq->mcq.cqn, sizeof (__u32))) {
+                       err = -EFAULT;
+-                      goto err_dbmap;
++                      goto err_cq_free;
+               }
+       return &cq->ibcq;
++err_cq_free:
++      mlx4_cq_free(dev->dev, &cq->mcq);
++
+ err_dbmap:
+       if (context)
+               mlx4_ib_db_unmap_user(to_mucontext(context), &cq->db);
diff --git a/queue-4.8/ib-mlx5-fix-fatal-error-dispatching.patch b/queue-4.8/ib-mlx5-fix-fatal-error-dispatching.patch
new file mode 100644 (file)
index 0000000..70df77b
--- /dev/null
@@ -0,0 +1,54 @@
+From dbaaff2a2caa03d472b5cc53a3fbfd415c97dc26 Mon Sep 17 00:00:00 2001
+From: Eli Cohen <eli@mellanox.com>
+Date: Thu, 27 Oct 2016 16:36:44 +0300
+Subject: IB/mlx5: Fix fatal error dispatching
+
+From: Eli Cohen <eli@mellanox.com>
+
+commit dbaaff2a2caa03d472b5cc53a3fbfd415c97dc26 upstream.
+
+When an internal error condition is detected, make sure to set the
+device inactive after dispatching the event so ULPs can get a
+notification of this event.
+
+Fixes: e126ba97dba9 ('mlx5: Add driver for Mellanox Connect-IB adapters')
+Signed-off-by: Eli Cohen <eli@mellanox.com>
+Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
+Reviewed-by: Mohamad Haj Yahia <mohamad@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/mlx5/main.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/infiniband/hw/mlx5/main.c
++++ b/drivers/infiniband/hw/mlx5/main.c
+@@ -2100,14 +2100,14 @@ static void mlx5_ib_event(struct mlx5_co
+ {
+       struct mlx5_ib_dev *ibdev = (struct mlx5_ib_dev *)context;
+       struct ib_event ibev;
+-
++      bool fatal = false;
+       u8 port = 0;
+       switch (event) {
+       case MLX5_DEV_EVENT_SYS_ERROR:
+-              ibdev->ib_active = false;
+               ibev.event = IB_EVENT_DEVICE_FATAL;
+               mlx5_ib_handle_internal_error(ibdev);
++              fatal = true;
+               break;
+       case MLX5_DEV_EVENT_PORT_UP:
+@@ -2154,6 +2154,9 @@ static void mlx5_ib_event(struct mlx5_co
+       if (ibdev->ib_active)
+               ib_dispatch_event(&ibev);
++
++      if (fatal)
++              ibdev->ib_active = false;
+ }
+ static void get_ext_port_caps(struct mlx5_ib_dev *dev)
diff --git a/queue-4.8/ib-mlx5-fix-memory-leak-in-query-device.patch b/queue-4.8/ib-mlx5-fix-memory-leak-in-query-device.patch
new file mode 100644 (file)
index 0000000..d17bb68
--- /dev/null
@@ -0,0 +1,44 @@
+From 90be7c8ab72853ff9fc407f01518a898df1f3045 Mon Sep 17 00:00:00 2001
+From: Majd Dibbiny <majd@mellanox.com>
+Date: Thu, 27 Oct 2016 16:36:39 +0300
+Subject: IB/mlx5: Fix memory leak in query device
+
+From: Majd Dibbiny <majd@mellanox.com>
+
+commit 90be7c8ab72853ff9fc407f01518a898df1f3045 upstream.
+
+We need to free dev->port when we fail to enable RoCE or
+initialize node data.
+
+Fixes: 0837e86a7a34 ('IB/mlx5: Add per port counters')
+Signed-off-by: Majd Dibbiny <majd@mellanox.com>
+Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
+Reviewed-by: Mark Bloch <markb@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/mlx5/main.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/infiniband/hw/mlx5/main.c
++++ b/drivers/infiniband/hw/mlx5/main.c
+@@ -2835,7 +2835,7 @@ static void *mlx5_ib_add(struct mlx5_cor
+       }
+       err = init_node_data(dev);
+       if (err)
+-              goto err_dealloc;
++              goto err_free_port;
+       mutex_init(&dev->flow_db.lock);
+       mutex_init(&dev->cap_mask_mutex);
+@@ -2845,7 +2845,7 @@ static void *mlx5_ib_add(struct mlx5_cor
+       if (ll == IB_LINK_LAYER_ETHERNET) {
+               err = mlx5_enable_roce(dev);
+               if (err)
+-                      goto err_dealloc;
++                      goto err_free_port;
+       }
+       err = create_dev_resources(&dev->devr);
diff --git a/queue-4.8/ib-mlx5-fix-null-pointer-dereference-on-debug-print.patch b/queue-4.8/ib-mlx5-fix-null-pointer-dereference-on-debug-print.patch
new file mode 100644 (file)
index 0000000..49e211b
--- /dev/null
@@ -0,0 +1,36 @@
+From a1ab8402d15d2305d2315d96ec3294bfdf16587e Mon Sep 17 00:00:00 2001
+From: Eli Cohen <eli@mellanox.com>
+Date: Thu, 27 Oct 2016 16:36:46 +0300
+Subject: IB/mlx5: Fix NULL pointer dereference on debug print
+
+From: Eli Cohen <eli@mellanox.com>
+
+commit a1ab8402d15d2305d2315d96ec3294bfdf16587e upstream.
+
+For XRC QP CQs may not exist. Check before attempting dereference.
+
+Fixes: e126ba97dba9 ('mlx5: Add driver for Mellanox Connect-IB adapters')
+Signed-off-by: Eli Cohen <eli@mellanox.com>
+Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
+Reviewed-by: Yishai Hadas <yishaih@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/mlx5/qp.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -2037,8 +2037,8 @@ struct ib_qp *mlx5_ib_create_qp(struct i
+               mlx5_ib_dbg(dev, "ib qpnum 0x%x, mlx qpn 0x%x, rcqn 0x%x, scqn 0x%x\n",
+                           qp->ibqp.qp_num, qp->trans_qp.base.mqp.qpn,
+-                          to_mcq(init_attr->recv_cq)->mcq.cqn,
+-                          to_mcq(init_attr->send_cq)->mcq.cqn);
++                          init_attr->recv_cq ? to_mcq(init_attr->recv_cq)->mcq.cqn : -1,
++                          init_attr->send_cq ? to_mcq(init_attr->send_cq)->mcq.cqn : -1);
+               qp->trans_qp.xrcdn = xrcdn;
diff --git a/queue-4.8/ib-mlx5-use-cache-line-size-to-select-cqe-stride.patch b/queue-4.8/ib-mlx5-use-cache-line-size-to-select-cqe-stride.patch
new file mode 100644 (file)
index 0000000..463519a
--- /dev/null
@@ -0,0 +1,41 @@
+From 16b0e0695a73b68d8ca40288c8f9614ef208917b Mon Sep 17 00:00:00 2001
+From: Daniel Jurgens <danielj@mellanox.com>
+Date: Thu, 27 Oct 2016 16:36:41 +0300
+Subject: IB/mlx5: Use cache line size to select CQE stride
+
+From: Daniel Jurgens <danielj@mellanox.com>
+
+commit 16b0e0695a73b68d8ca40288c8f9614ef208917b upstream.
+
+When creating kernel CQs use 128B CQE stride if the
+cache line size is 128B, 64B otherwise.  This prevents
+multiple CQEs from residing in a 128B cache line,
+which can cause retries when there are concurrent
+read and writes in one cache line.
+
+Tested with IPoIB on PPC64, saw ~5% throughput
+improvement.
+
+Fixes: e126ba97dba9 ('mlx5: Add driver for Mellanox Connect-IB adapters')
+Signed-off-by: Daniel Jurgens <danielj@mellanox.com>
+Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/mlx5/cq.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/infiniband/hw/mlx5/cq.c
++++ b/drivers/infiniband/hw/mlx5/cq.c
+@@ -917,8 +917,7 @@ struct ib_cq *mlx5_ib_create_cq(struct i
+               if (err)
+                       goto err_create;
+       } else {
+-              /* for now choose 64 bytes till we have a proper interface */
+-              cqe_size = 64;
++              cqe_size = cache_line_size() == 128 ? 128 : 64;
+               err = create_cq_kernel(dev, cq, entries, cqe_size, &cqb,
+                                      &index, &inlen);
+               if (err)
diff --git a/queue-4.8/ib-mlx5-validate-requested-rqt-size.patch b/queue-4.8/ib-mlx5-validate-requested-rqt-size.patch
new file mode 100644 (file)
index 0000000..ec2a4a6
--- /dev/null
@@ -0,0 +1,39 @@
+From efd7f40082a0dfd112eb87ff2124467a5739216f Mon Sep 17 00:00:00 2001
+From: Maor Gottlieb <maorg@mellanox.com>
+Date: Thu, 27 Oct 2016 16:36:40 +0300
+Subject: IB/mlx5: Validate requested RQT size
+
+From: Maor Gottlieb <maorg@mellanox.com>
+
+commit efd7f40082a0dfd112eb87ff2124467a5739216f upstream.
+
+Validate that the requested size of RQT is supported by firmware.
+
+Fixes: c5f9092936fe ('IB/mlx5: Add Receive Work Queue Indirection table operations')
+Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
+Reviewed-by: Yishai Hadas <yishaih@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/mlx5/qp.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -4702,6 +4702,14 @@ struct ib_rwq_ind_table *mlx5_ib_create_
+                                udata->inlen))
+               return ERR_PTR(-EOPNOTSUPP);
++      if (init_attr->log_ind_tbl_size >
++          MLX5_CAP_GEN(dev->mdev, log_max_rqt_size)) {
++              mlx5_ib_dbg(dev, "log_ind_tbl_size = %d is bigger than supported = %d\n",
++                          init_attr->log_ind_tbl_size,
++                          MLX5_CAP_GEN(dev->mdev, log_max_rqt_size));
++              return ERR_PTR(-EINVAL);
++      }
++
+       min_resp_len = offsetof(typeof(resp), reserved) + sizeof(resp.reserved);
+       if (udata->outlen && udata->outlen < min_resp_len)
+               return ERR_PTR(-EINVAL);
diff --git a/queue-4.8/ib-rxe-clear-queue-buffer-when-modifying-qp-to-reset.patch b/queue-4.8/ib-rxe-clear-queue-buffer-when-modifying-qp-to-reset.patch
new file mode 100644 (file)
index 0000000..d9b93e4
--- /dev/null
@@ -0,0 +1,68 @@
+From aa75b07b478a774b1432e2df1be5cd8ae834de0f Mon Sep 17 00:00:00 2001
+From: Yonatan Cohen <yonatanc@mellanox.com>
+Date: Wed, 16 Nov 2016 10:39:17 +0200
+Subject: IB/rxe: Clear queue buffer when modifying QP to reset
+
+From: Yonatan Cohen <yonatanc@mellanox.com>
+
+commit aa75b07b478a774b1432e2df1be5cd8ae834de0f upstream.
+
+RXE resets the send-q only once in rxe_qp_init_req() when
+QP is created, but when the QP is reused after QP reset, the send-q
+holds previous garbage data.
+
+This garbage data wrongly fails CQEs that otherwise
+should have completed successfully.
+
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Signed-off-by: Yonatan Cohen <yonatanc@mellanox.com>
+Reviewed-by: Moni Shoua <monis@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/sw/rxe/rxe_qp.c    |    1 +
+ drivers/infiniband/sw/rxe/rxe_queue.c |    9 +++++++++
+ drivers/infiniband/sw/rxe/rxe_queue.h |    2 ++
+ 3 files changed, 12 insertions(+)
+
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -522,6 +522,7 @@ static void rxe_qp_reset(struct rxe_qp *
+       if (qp->sq.queue) {
+               __rxe_do_task(&qp->comp.task);
+               __rxe_do_task(&qp->req.task);
++              rxe_queue_reset(qp->sq.queue);
+       }
+       /* cleanup attributes */
+--- a/drivers/infiniband/sw/rxe/rxe_queue.c
++++ b/drivers/infiniband/sw/rxe/rxe_queue.c
+@@ -84,6 +84,15 @@ err1:
+       return -EINVAL;
+ }
++inline void rxe_queue_reset(struct rxe_queue *q)
++{
++      /* queue is comprised from header and the memory
++       * of the actual queue. See "struct rxe_queue_buf" in rxe_queue.h
++       * reset only the queue itself and not the management header
++       */
++      memset(q->buf->data, 0, q->buf_size - sizeof(struct rxe_queue_buf));
++}
++
+ struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe,
+                                int *num_elem,
+                                unsigned int elem_size)
+--- a/drivers/infiniband/sw/rxe/rxe_queue.h
++++ b/drivers/infiniband/sw/rxe/rxe_queue.h
+@@ -84,6 +84,8 @@ int do_mmap_info(struct rxe_dev *rxe,
+                size_t buf_size,
+                struct rxe_mmap_info **ip_p);
++void rxe_queue_reset(struct rxe_queue *q);
++
+ struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe,
+                                int *num_elem,
+                                unsigned int elem_size);
diff --git a/queue-4.8/ib-rxe-fix-handling-of-erroneous-wr.patch b/queue-4.8/ib-rxe-fix-handling-of-erroneous-wr.patch
new file mode 100644 (file)
index 0000000..5548eb0
--- /dev/null
@@ -0,0 +1,99 @@
+From 002e062e13db10973adb8302f231e48b477c7ccf Mon Sep 17 00:00:00 2001
+From: Yonatan Cohen <yonatanc@mellanox.com>
+Date: Wed, 16 Nov 2016 10:39:15 +0200
+Subject: IB/rxe: Fix handling of erroneous WR
+
+From: Yonatan Cohen <yonatanc@mellanox.com>
+
+commit 002e062e13db10973adb8302f231e48b477c7ccf upstream.
+
+To correctly handle a erroneous WR this fix does the following
+1. Make sure the bad WQE causes a user completion event.
+2. Call rxe_completer to handle the erred WQE.
+
+Before the fix, when rxe_requester found a bad WQE, it changed its
+status to IB_WC_LOC_PROT_ERR and exit with 0 for non RC QPs.
+
+If this was the 1st WQE then there would be no ACK to invoke the
+completer and this bad WQE would be stuck in the QP's send-q.
+
+On top of that the requester exiting with 0 caused rxe_do_task to
+endlessly invoke rxe_requester, resulting in a soft-lockup attached
+below.
+
+In case the WQE was not the 1st and rxe_completer did get a chance to
+handle the bad WQE, it did not cause a complete event since the WQE's
+IB_SEND_SIGNALED flag was not set.
+
+Setting WQE status to IB_SEND_SIGNALED is subject to IBA spec
+version 1.2.1, section 10.7.3.1 Signaled Completions.
+
+NMI watchdog: BUG: soft lockup - CPU#7 stuck for 22s!
+[<ffffffffa0590145>] ? rxe_pool_get_index+0x35/0xb0 [rdma_rxe]
+[<ffffffffa05952ec>] lookup_mem+0x3c/0xc0 [rdma_rxe]
+[<ffffffffa0595534>] copy_data+0x1c4/0x230 [rdma_rxe]
+[<ffffffffa058c180>] rxe_requester+0x9d0/0x1100 [rdma_rxe]
+[<ffffffff8158e98a>] ? kfree_skbmem+0x5a/0x60
+[<ffffffffa05962c9>] rxe_do_task+0x89/0xf0 [rdma_rxe]
+[<ffffffffa05963e2>] rxe_run_task+0x12/0x30 [rdma_rxe]
+[<ffffffffa059110a>] rxe_post_send+0x41a/0x550 [rdma_rxe]
+[<ffffffff811ef922>] ? __kmalloc+0x182/0x200
+[<ffffffff816ba512>] ? down_read+0x12/0x40
+[<ffffffffa054bd32>] ib_uverbs_post_send+0x532/0x540 [ib_uverbs]
+[<ffffffff815f8722>] ? tcp_sendmsg+0x402/0xb80
+[<ffffffffa05453dc>] ib_uverbs_write+0x18c/0x3f0 [ib_uverbs]
+[<ffffffff81623c2e>] ? inet_recvmsg+0x7e/0xb0
+[<ffffffff8158764d>] ? sock_recvmsg+0x3d/0x50
+[<ffffffff81215b87>] __vfs_write+0x37/0x140
+[<ffffffff81216892>] vfs_write+0xb2/0x1b0
+[<ffffffff81217ce5>] SyS_write+0x55/0xc0
+[<ffffffff816bc672>] entry_SYSCALL_64_fastpath+0x1a/0xa
+
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Signed-off-by: Yonatan Cohen <yonatanc@mellanox.com>
+Reviewed-by: Moni Shoua <monis@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/sw/rxe/rxe_req.c |   21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/drivers/infiniband/sw/rxe/rxe_req.c
++++ b/drivers/infiniband/sw/rxe/rxe_req.c
+@@ -695,7 +695,8 @@ next_wqe:
+                                                      qp->req.wqe_index);
+                       wqe->state = wqe_state_done;
+                       wqe->status = IB_WC_SUCCESS;
+-                      goto complete;
++                      __rxe_do_task(&qp->comp.task);
++                      return 0;
+               }
+               payload = mtu;
+       }
+@@ -744,13 +745,17 @@ err:
+       wqe->status = IB_WC_LOC_PROT_ERR;
+       wqe->state = wqe_state_error;
+-complete:
+-      if (qp_type(qp) != IB_QPT_RC) {
+-              while (rxe_completer(qp) == 0)
+-                      ;
+-      }
+-
+-      return 0;
++      /*
++       * IBA Spec. Section 10.7.3.1 SIGNALED COMPLETIONS
++       * ---------8<---------8<-------------
++       * ...Note that if a completion error occurs, a Work Completion
++       * will always be generated, even if the signaling
++       * indicator requests an Unsignaled Completion.
++       * ---------8<---------8<-------------
++       */
++      wqe->wr.send_flags |= IB_SEND_SIGNALED;
++      __rxe_do_task(&qp->comp.task);
++      return -EAGAIN;
+ exit:
+       return -EAGAIN;
diff --git a/queue-4.8/ib-rxe-fix-kernel-panic-in-udp-tunnel-with-gro-and-rx-checksum.patch b/queue-4.8/ib-rxe-fix-kernel-panic-in-udp-tunnel-with-gro-and-rx-checksum.patch
new file mode 100644 (file)
index 0000000..2f24a43
--- /dev/null
@@ -0,0 +1,108 @@
+From 1454ca3a97e147bb91e98b087446c39cf6692a48 Mon Sep 17 00:00:00 2001
+From: Yonatan Cohen <yonatanc@mellanox.com>
+Date: Wed, 16 Nov 2016 10:39:14 +0200
+Subject: IB/rxe: Fix kernel panic in UDP tunnel with GRO and RX checksum
+
+From: Yonatan Cohen <yonatanc@mellanox.com>
+
+commit 1454ca3a97e147bb91e98b087446c39cf6692a48 upstream.
+
+Missing initialization of udp_tunnel_sock_cfg causes to following
+kernel panic, while kernel tries to execute gro_receive().
+
+While being there, we converted udp_port_cfg to use the same
+initialization scheme as udp_tunnel_sock_cfg.
+
+------------[ cut here ]------------
+kernel tried to execute NX-protected page - exploit attempt? (uid: 0)
+BUG: unable to handle kernel paging request at ffffffffa0588c50
+IP: [<ffffffffa0588c50>] __this_module+0x50/0xffffffffffff8400 [ib_rxe]
+PGD 1c09067 PUD 1c0a063 PMD bb394067 PTE 80000000ad5e8163
+Oops: 0011 [#1] SMP
+Modules linked in: ib_rxe ip6_udp_tunnel udp_tunnel
+CPU: 5 PID: 0 Comm: swapper/5 Not tainted 4.7.0-rc3+ #2
+Hardware name: Red Hat KVM, BIOS Bochs 01/01/2011
+task: ffff880235e4e680 ti: ffff880235e68000 task.ti: ffff880235e68000
+RIP: 0010:[<ffffffffa0588c50>]
+[<ffffffffa0588c50>] __this_module+0x50/0xffffffffffff8400 [ib_rxe]
+RSP: 0018:ffff880237343c80  EFLAGS: 00010282
+RAX: 00000000dffe482d RBX: ffff8800ae330900 RCX: 000000002001b712
+RDX: ffff8800ae330900 RSI: ffff8800ae102578 RDI: ffff880235589c00
+RBP: ffff880237343cb0 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000000 R12: ffff8800ae33e262
+R13: ffff880235589c00 R14: 0000000000000014 R15: ffff8800ae102578
+FS:  0000000000000000(0000) GS:ffff880237340000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: ffffffffa0588c50 CR3: 0000000001c06000 CR4: 00000000000006e0
+Stack:
+ffffffff8160860e ffff8800ae330900 ffff8800ae102578 0000000000000014
+000000000000004e ffff8800ae102578 ffff880237343ce0 ffffffff816088fb
+0000000000000000 ffff8800ae330900 0000000000000000 00000000ffad0000
+Call Trace:
+<IRQ>
+[<ffffffff8160860e>] ? udp_gro_receive+0xde/0x130
+[<ffffffff816088fb>] udp4_gro_receive+0x10b/0x2d0
+[<ffffffff81611373>] inet_gro_receive+0x1d3/0x270
+[<ffffffff81594e29>] dev_gro_receive+0x269/0x3b0
+[<ffffffff81595188>] napi_gro_receive+0x38/0x120
+[<ffffffffa011caee>] mlx5e_handle_rx_cqe+0x27e/0x340 [mlx5_core]
+[<ffffffffa011d076>] mlx5e_poll_rx_cq+0x66/0x6d0 [mlx5_core]
+[<ffffffffa011d7ae>] mlx5e_napi_poll+0x8e/0x400 [mlx5_core]
+[<ffffffff815949a0>] net_rx_action+0x160/0x380
+[<ffffffff816a9197>] __do_softirq+0xd7/0x2c5
+[<ffffffff81085c35>] irq_exit+0xf5/0x100
+[<ffffffff816a8f16>] do_IRQ+0x56/0xd0
+[<ffffffff816a6dcc>] common_interrupt+0x8c/0x8c
+<EOI>
+[<ffffffff81061f96>] ? native_safe_halt+0x6/0x10
+[<ffffffff81037ade>] default_idle+0x1e/0xd0
+[<ffffffff8103828f>] arch_cpu_idle+0xf/0x20
+[<ffffffff810c37dc>] default_idle_call+0x3c/0x50
+[<ffffffff810c3b13>] cpu_startup_entry+0x323/0x3c0
+[<ffffffff81050d8c>] start_secondary+0x15c/0x1a0
+RIP  [<ffffffffa0588c50>] __this_module+0x50/0xffffffffffff8400 [ib_rxe]
+RSP <ffff880237343c80>
+CR2: ffffffffa0588c50
+---[ end trace 489ee31fa7614ac5 ]---
+Kernel panic - not syncing: Fatal exception in interrupt
+Kernel Offset: disabled
+---[ end Kernel panic - not syncing: Fatal exception in interrupt
+------------[ cut here ]------------
+
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Signed-off-by: Yonatan Cohen <yonatanc@mellanox.com>
+Reviewed-by: Moni Shoua <monis@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/sw/rxe/rxe_net.c |    8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/infiniband/sw/rxe/rxe_net.c
++++ b/drivers/infiniband/sw/rxe/rxe_net.c
+@@ -243,10 +243,8 @@ static struct socket *rxe_setup_udp_tunn
+ {
+       int err;
+       struct socket *sock;
+-      struct udp_port_cfg udp_cfg;
+-      struct udp_tunnel_sock_cfg tnl_cfg;
+-
+-      memset(&udp_cfg, 0, sizeof(udp_cfg));
++      struct udp_port_cfg udp_cfg = {0};
++      struct udp_tunnel_sock_cfg tnl_cfg = {0};
+       if (ipv6) {
+               udp_cfg.family = AF_INET6;
+@@ -264,10 +262,8 @@ static struct socket *rxe_setup_udp_tunn
+               return ERR_PTR(err);
+       }
+-      tnl_cfg.sk_user_data = NULL;
+       tnl_cfg.encap_type = 1;
+       tnl_cfg.encap_rcv = rxe_udp_encap_recv;
+-      tnl_cfg.encap_destroy = NULL;
+       /* Setup UDP tunnel */
+       setup_udp_tunnel_sock(net, sock, &tnl_cfg);
diff --git a/queue-4.8/ib-rxe-update-qp-state-for-user-query.patch b/queue-4.8/ib-rxe-update-qp-state-for-user-query.patch
new file mode 100644 (file)
index 0000000..33a1579
--- /dev/null
@@ -0,0 +1,36 @@
+From 6d931308f55faaef3f30bd0346c47f99528b229d Mon Sep 17 00:00:00 2001
+From: Yonatan Cohen <yonatanc@mellanox.com>
+Date: Wed, 16 Nov 2016 10:39:18 +0200
+Subject: IB/rxe: Update qp state for user query
+
+From: Yonatan Cohen <yonatanc@mellanox.com>
+
+commit 6d931308f55faaef3f30bd0346c47f99528b229d upstream.
+
+The method rxe_qp_error() transitions QP to error state
+and make sure the QP is drained. It did not though update
+the QP state for user's query.
+
+This patch fixes this.
+
+Fixes: 8700e3e7c485 ("Soft RoCE driver")
+Signed-off-by: Yonatan Cohen <yonatanc@mellanox.com>
+Reviewed-by: Moni Shoua <monis@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/sw/rxe/rxe_qp.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -573,6 +573,7 @@ void rxe_qp_error(struct rxe_qp *qp)
+ {
+       qp->req.state = QP_STATE_ERROR;
+       qp->resp.state = QP_STATE_ERROR;
++      qp->attr.qp_state = IB_QPS_ERR;
+       /* drain work and packet queues */
+       rxe_run_task(&qp->resp.task, 1);
diff --git a/queue-4.8/ib-uverbs-fix-leak-of-xrc-target-qps.patch b/queue-4.8/ib-uverbs-fix-leak-of-xrc-target-qps.patch
new file mode 100644 (file)
index 0000000..f3b3a31
--- /dev/null
@@ -0,0 +1,42 @@
+From 5b810a242c28e1d8d64d718cebe75b79d86a0b2d Mon Sep 17 00:00:00 2001
+From: Tariq Toukan <tariqt@mellanox.com>
+Date: Thu, 27 Oct 2016 16:36:26 +0300
+Subject: IB/uverbs: Fix leak of XRC target QPs
+
+From: Tariq Toukan <tariqt@mellanox.com>
+
+commit 5b810a242c28e1d8d64d718cebe75b79d86a0b2d upstream.
+
+The real QP is destroyed in case of the ref count reaches zero, but
+for XRC target QPs this call was missed and caused to QP leaks.
+
+Let's call to destroy for all flows.
+
+Fixes: 0e0ec7e0638e ('RDMA/core: Export ib_open_qp() to share XRC...')
+Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
+Signed-off-by: Noa Osherovich <noaos@mellanox.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/uverbs_main.c |    7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/infiniband/core/uverbs_main.c
++++ b/drivers/infiniband/core/uverbs_main.c
+@@ -262,12 +262,9 @@ static int ib_uverbs_cleanup_ucontext(st
+                       container_of(uobj, struct ib_uqp_object, uevent.uobject);
+               idr_remove_uobj(&ib_uverbs_qp_idr, uobj);
+-              if (qp != qp->real_qp) {
+-                      ib_close_qp(qp);
+-              } else {
++              if (qp == qp->real_qp)
+                       ib_uverbs_detach_umcast(qp, uqp);
+-                      ib_destroy_qp(qp);
+-              }
++              ib_destroy_qp(qp);
+               ib_uverbs_release_uevent(file, &uqp->uevent);
+               kfree(uqp);
+       }
diff --git a/queue-4.8/iwlwifi-mvm-fix-d3_test-with-unified-d0-d3-images.patch b/queue-4.8/iwlwifi-mvm-fix-d3_test-with-unified-d0-d3-images.patch
new file mode 100644 (file)
index 0000000..887eed6
--- /dev/null
@@ -0,0 +1,64 @@
+From 85cd69b8f1f7e289fe931a82889e673fd0f04842 Mon Sep 17 00:00:00 2001
+From: Luca Coelho <luciano.coelho@intel.com>
+Date: Wed, 5 Oct 2016 11:24:12 +0300
+Subject: iwlwifi: mvm: fix d3_test with unified D0/D3 images
+
+From: Luca Coelho <luciano.coelho@intel.com>
+
+commit 85cd69b8f1f7e289fe931a82889e673fd0f04842 upstream.
+
+When a unified D0/D3 image is used, we don't restart the FW in the
+D0->D3->D0 transitions.  Therefore, the d3_test functionality should
+not call ieee8021_restart_hw() when the resuming either.
+
+Fixes: commit 23ae61282b88 ("iwlwifi: mvm: Do not switch to D3 image on suspend")
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/d3.c |   25 +++++++++++++++----------
+ 1 file changed, 15 insertions(+), 10 deletions(-)
+
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+@@ -2290,7 +2290,8 @@ static void iwl_mvm_d3_test_disconn_work
+ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
+ {
+       struct iwl_mvm *mvm = inode->i_private;
+-      int remaining_time = 10;
++      bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
++                                       IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
+       mvm->d3_test_active = false;
+@@ -2301,17 +2302,21 @@ static int iwl_mvm_d3_test_release(struc
+       mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
+       iwl_abort_notification_waits(&mvm->notif_wait);
+-      ieee80211_restart_hw(mvm->hw);
++      if (!unified_image) {
++              int remaining_time = 10;
+-      /* wait for restart and disconnect all interfaces */
+-      while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
+-             remaining_time > 0) {
+-              remaining_time--;
+-              msleep(1000);
+-      }
++              ieee80211_restart_hw(mvm->hw);
++
++              /* wait for restart and disconnect all interfaces */
++              while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
++                     remaining_time > 0) {
++                      remaining_time--;
++                      msleep(1000);
++              }
+-      if (remaining_time == 0)
+-              IWL_ERR(mvm, "Timed out waiting for HW restart to finish!\n");
++              if (remaining_time == 0)
++                      IWL_ERR(mvm, "Timed out waiting for HW restart!\n");
++      }
+       ieee80211_iterate_active_interfaces_atomic(
+               mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
diff --git a/queue-4.8/iwlwifi-mvm-fix-netdetect-starting-stopping-for-unified-images.patch b/queue-4.8/iwlwifi-mvm-fix-netdetect-starting-stopping-for-unified-images.patch
new file mode 100644 (file)
index 0000000..8c6f5dd
--- /dev/null
@@ -0,0 +1,107 @@
+From 5a143db8c4a28dab6423cb6197e9f1389da375f2 Mon Sep 17 00:00:00 2001
+From: Luca Coelho <luciano.coelho@intel.com>
+Date: Wed, 5 Oct 2016 09:28:53 +0300
+Subject: iwlwifi: mvm: fix netdetect starting/stopping for unified images
+
+From: Luca Coelho <luciano.coelho@intel.com>
+
+commit 5a143db8c4a28dab6423cb6197e9f1389da375f2 upstream.
+
+With unified images, we need to make sure the net-detect scan is
+stopped after resuming, since we don't restart the FW.  Also, we need
+to make sure we check if there are enough scan slots available to run
+it, as we do with other scans.
+
+Fixes: commit 23ae61282b88 ("iwlwifi: mvm: Do not switch to D3 image on suspend")
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/d3.c   |   19 ++++++++++++++
+ drivers/net/wireless/intel/iwlwifi/mvm/scan.c |   33 +++++++++++++++++++++-----
+ 2 files changed, 46 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+@@ -1087,6 +1087,15 @@ iwl_mvm_netdetect_config(struct iwl_mvm
+               ret = iwl_mvm_switch_to_d3(mvm);
+               if (ret)
+                       return ret;
++      } else {
++              /* In theory, we wouldn't have to stop a running sched
++               * scan in order to start another one (for
++               * net-detect).  But in practice this doesn't seem to
++               * work properly, so stop any running sched_scan now.
++               */
++              ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true);
++              if (ret)
++                      return ret;
+       }
+       /* rfkill release can be either for wowlan or netdetect */
+@@ -2088,6 +2097,16 @@ static int __iwl_mvm_resume(struct iwl_m
+       iwl_mvm_update_changed_regdom(mvm);
+       if (mvm->net_detect) {
++              /* If this is a non-unified image, we restart the FW,
++               * so no need to stop the netdetect scan.  If that
++               * fails, continue and try to get the wake-up reasons,
++               * but trigger a HW restart by keeping a failure code
++               * in ret.
++               */
++              if (unified_image)
++                      ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_NETDETECT,
++                                              false);
++
+               iwl_mvm_query_netdetect_reasons(mvm, vif);
+               /* has unlocked the mutex, so skip that */
+               goto out;
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+@@ -1185,6 +1185,9 @@ static int iwl_mvm_num_scans(struct iwl_
+ static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type)
+ {
++      bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
++                                       IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
++
+       /* This looks a bit arbitrary, but the idea is that if we run
+        * out of possible simultaneous scans and the userspace is
+        * trying to run a scan type that is already running, we
+@@ -1211,12 +1214,30 @@ static int iwl_mvm_check_running_scans(s
+                       return -EBUSY;
+               return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);
+       case IWL_MVM_SCAN_NETDETECT:
+-              /* No need to stop anything for net-detect since the
+-               * firmware is restarted anyway.  This way, any sched
+-               * scans that were running will be restarted when we
+-               * resume.
+-              */
+-              return 0;
++              /* For non-unified images, there's no need to stop
++               * anything for net-detect since the firmware is
++               * restarted anyway.  This way, any sched scans that
++               * were running will be restarted when we resume.
++               */
++              if (!unified_image)
++                      return 0;
++
++              /* If this is a unified image and we ran out of scans,
++               * we need to stop something.  Prefer stopping regular
++               * scans, because the results are useless at this
++               * point, and we should be able to keep running
++               * another scheduled scan while suspended.
++               */
++              if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK)
++                      return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR,
++                                               true);
++              if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK)
++                      return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED,
++                                               true);
++
++              /* fall through, something is wrong if no scan was
++               * running but we ran out of scans.
++               */
+       default:
+               WARN_ON(1);
+               break;
diff --git a/queue-4.8/iwlwifi-mvm-wake-the-wait-queue-when-the-rx-sync-counter-is-zero.patch b/queue-4.8/iwlwifi-mvm-wake-the-wait-queue-when-the-rx-sync-counter-is-zero.patch
new file mode 100644 (file)
index 0000000..61b9d70
--- /dev/null
@@ -0,0 +1,81 @@
+From 3a732c65de427fdae67a243fd331356034b5a1e8 Mon Sep 17 00:00:00 2001
+From: Sara Sharon <sara.sharon@intel.com>
+Date: Sun, 9 Oct 2016 17:34:24 +0300
+Subject: iwlwifi: mvm: wake the wait queue when the RX sync counter is zero
+
+From: Sara Sharon <sara.sharon@intel.com>
+
+commit 3a732c65de427fdae67a243fd331356034b5a1e8 upstream.
+
+When we sync the RX queues the driver waits to receive echo
+notification on all the RX queues.
+The wait queue is set with timeout until all queues have received
+the notification.
+However, iwl_mvm_rx_queue_notif() never woke up the wait queue,
+with the result of the counter value being checked only when the
+timeout expired.
+This may cause a latency of up to 1 second.
+
+Fixes: 0636b938214c ("iwlwifi: mvm: implement driver RX queues sync command")
+Signed-off-by: Sara Sharon <sara.sharon@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |    3 +--
+ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h      |    1 +
+ drivers/net/wireless/intel/iwlwifi/mvm/ops.c      |    1 +
+ drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c     |    3 ++-
+ 4 files changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -4097,7 +4097,6 @@ void iwl_mvm_sync_rx_queues_internal(str
+                                    struct iwl_mvm_internal_rxq_notif *notif,
+                                    u32 size)
+ {
+-      DECLARE_WAIT_QUEUE_HEAD_ONSTACK(notif_waitq);
+       u32 qmask = BIT(mvm->trans->num_rx_queues) - 1;
+       int ret;
+@@ -4119,7 +4118,7 @@ void iwl_mvm_sync_rx_queues_internal(str
+       }
+       if (notif->sync)
+-              ret = wait_event_timeout(notif_waitq,
++              ret = wait_event_timeout(mvm->rx_sync_waitq,
+                                        atomic_read(&mvm->queue_sync_counter) == 0,
+                                        HZ);
+       WARN_ON_ONCE(!ret);
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+@@ -932,6 +932,7 @@ struct iwl_mvm {
+       /* sync d0i3_tx queue and IWL_MVM_STATUS_IN_D0I3 status flag */
+       spinlock_t d0i3_tx_lock;
+       wait_queue_head_t d0i3_exit_waitq;
++      wait_queue_head_t rx_sync_waitq;
+       /* BT-Coex */
+       struct iwl_bt_coex_profile_notif last_bt_notif;
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -618,6 +618,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *
+       spin_lock_init(&mvm->refs_lock);
+       skb_queue_head_init(&mvm->d0i3_tx);
+       init_waitqueue_head(&mvm->d0i3_exit_waitq);
++      init_waitqueue_head(&mvm->rx_sync_waitq);
+       atomic_set(&mvm->queue_sync_counter, 0);
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+@@ -545,7 +545,8 @@ void iwl_mvm_rx_queue_notif(struct iwl_m
+                                 "Received expired RX queue sync message\n");
+                       return;
+               }
+-              atomic_dec(&mvm->queue_sync_counter);
++              if (!atomic_dec_return(&mvm->queue_sync_counter))
++                      wake_up(&mvm->rx_sync_waitq);
+       }
+       switch (internal_notif->type) {
diff --git a/queue-4.8/iwlwifi-pcie-fix-splc-structure-parsing.patch b/queue-4.8/iwlwifi-pcie-fix-splc-structure-parsing.patch
new file mode 100644 (file)
index 0000000..9f26144
--- /dev/null
@@ -0,0 +1,153 @@
+From e0d9727c111a5917a1184c71c1a8e6f78c7fc41d Mon Sep 17 00:00:00 2001
+From: Luca Coelho <luciano.coelho@intel.com>
+Date: Thu, 13 Oct 2016 10:07:07 +0300
+Subject: iwlwifi: pcie: fix SPLC structure parsing
+
+From: Luca Coelho <luciano.coelho@intel.com>
+
+commit e0d9727c111a5917a1184c71c1a8e6f78c7fc41d upstream.
+
+The SPLC data parsing is too restrictive and was not trying find the
+correct element for WiFi.  This causes problems with some BIOSes where
+the SPLC method exists, but doesn't have a WiFi entry on the first
+element of the list.  The domain type values are also incorrect
+according to the specification.
+
+Fix this by complying with the actual specification.
+
+Additionally, replace all occurrences of SPLX to SPLC, since SPLX is
+only a structure internal to the ACPI tables, and may not even exist.
+
+Fixes: bcb079a14d75 ("iwlwifi: pcie: retrieve and parse ACPI power limitations")
+Reported-by: Chris Rorvick <chris@rorvick.com>
+Tested-by: Paul Bolle <pebolle@tiscali.nl>
+Tested-by: Chris Rorvick <chris@rorvick.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/intel/iwlwifi/pcie/drv.c |   77 +++++++++++++++-----------
+ 1 file changed, 47 insertions(+), 30 deletions(-)
+
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+@@ -526,48 +526,64 @@ static const struct pci_device_id iwl_hw
+ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
+ #ifdef CONFIG_ACPI
+-#define SPL_METHOD            "SPLC"
+-#define SPL_DOMAINTYPE_MODULE BIT(0)
+-#define SPL_DOMAINTYPE_WIFI   BIT(1)
+-#define SPL_DOMAINTYPE_WIGIG  BIT(2)
+-#define SPL_DOMAINTYPE_RFEM   BIT(3)
++#define ACPI_SPLC_METHOD      "SPLC"
++#define ACPI_SPLC_DOMAIN_WIFI (0x07)
+-static u64 splx_get_pwr_limit(struct iwl_trans *trans, union acpi_object *splx)
++static u64 splc_get_pwr_limit(struct iwl_trans *trans, union acpi_object *splc)
+ {
+-      union acpi_object *limits, *domain_type, *power_limit;
++      union acpi_object *data_pkg, *dflt_pwr_limit;
++      int i;
+-      if (splx->type != ACPI_TYPE_PACKAGE ||
+-          splx->package.count != 2 ||
+-          splx->package.elements[0].type != ACPI_TYPE_INTEGER ||
+-          splx->package.elements[0].integer.value != 0) {
+-              IWL_ERR(trans, "Unsupported splx structure\n");
++      /* We need at least two elements, one for the revision and one
++       * for the data itself.  Also check that the revision is
++       * supported (currently only revision 0).
++      */
++      if (splc->type != ACPI_TYPE_PACKAGE ||
++          splc->package.count < 2 ||
++          splc->package.elements[0].type != ACPI_TYPE_INTEGER ||
++          splc->package.elements[0].integer.value != 0) {
++              IWL_DEBUG_INFO(trans,
++                             "Unsupported structure returned by the SPLC method.  Ignoring.\n");
+               return 0;
+       }
+-      limits = &splx->package.elements[1];
+-      if (limits->type != ACPI_TYPE_PACKAGE ||
+-          limits->package.count < 2 ||
+-          limits->package.elements[0].type != ACPI_TYPE_INTEGER ||
+-          limits->package.elements[1].type != ACPI_TYPE_INTEGER) {
+-              IWL_ERR(trans, "Invalid limits element\n");
+-              return 0;
++      /* loop through all the packages to find the one for WiFi */
++      for (i = 1; i < splc->package.count; i++) {
++              union acpi_object *domain;
++
++              data_pkg = &splc->package.elements[i];
++
++              /* Skip anything that is not a package with the right
++               * amount of elements (i.e. at least 2 integers).
++               */
++              if (data_pkg->type != ACPI_TYPE_PACKAGE ||
++                  data_pkg->package.count < 2 ||
++                  data_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
++                  data_pkg->package.elements[1].type != ACPI_TYPE_INTEGER)
++                      continue;
++
++              domain = &data_pkg->package.elements[0];
++              if (domain->integer.value == ACPI_SPLC_DOMAIN_WIFI)
++                      break;
++
++              data_pkg = NULL;
+       }
+-      domain_type = &limits->package.elements[0];
+-      power_limit = &limits->package.elements[1];
+-      if (!(domain_type->integer.value & SPL_DOMAINTYPE_WIFI)) {
+-              IWL_DEBUG_INFO(trans, "WiFi power is not limited\n");
++      if (!data_pkg) {
++              IWL_DEBUG_INFO(trans,
++                             "No element for the WiFi domain returned by the SPLC method.\n");
+               return 0;
+       }
+-      return power_limit->integer.value;
++      dflt_pwr_limit = &data_pkg->package.elements[1];
++      return dflt_pwr_limit->integer.value;
+ }
+ static void set_dflt_pwr_limit(struct iwl_trans *trans, struct pci_dev *pdev)
+ {
+       acpi_handle pxsx_handle;
+       acpi_handle handle;
+-      struct acpi_buffer splx = {ACPI_ALLOCATE_BUFFER, NULL};
++      struct acpi_buffer splc = {ACPI_ALLOCATE_BUFFER, NULL};
+       acpi_status status;
+       pxsx_handle = ACPI_HANDLE(&pdev->dev);
+@@ -578,23 +594,24 @@ static void set_dflt_pwr_limit(struct iw
+       }
+       /* Get the method's handle */
+-      status = acpi_get_handle(pxsx_handle, (acpi_string)SPL_METHOD, &handle);
++      status = acpi_get_handle(pxsx_handle, (acpi_string)ACPI_SPLC_METHOD,
++                               &handle);
+       if (ACPI_FAILURE(status)) {
+-              IWL_DEBUG_INFO(trans, "SPL method not found\n");
++              IWL_DEBUG_INFO(trans, "SPLC method not found\n");
+               return;
+       }
+       /* Call SPLC with no arguments */
+-      status = acpi_evaluate_object(handle, NULL, NULL, &splx);
++      status = acpi_evaluate_object(handle, NULL, NULL, &splc);
+       if (ACPI_FAILURE(status)) {
+               IWL_ERR(trans, "SPLC invocation failed (0x%x)\n", status);
+               return;
+       }
+-      trans->dflt_pwr_limit = splx_get_pwr_limit(trans, splx.pointer);
++      trans->dflt_pwr_limit = splc_get_pwr_limit(trans, splc.pointer);
+       IWL_DEBUG_INFO(trans, "Default power limit set to %lld\n",
+                      trans->dflt_pwr_limit);
+-      kfree(splx.pointer);
++      kfree(splc.pointer);
+ }
+ #else /* CONFIG_ACPI */
diff --git a/queue-4.8/iwlwifi-pcie-mark-command-queue-lock-with-separate-lockdep-class.patch b/queue-4.8/iwlwifi-pcie-mark-command-queue-lock-with-separate-lockdep-class.patch
new file mode 100644 (file)
index 0000000..7d193dc
--- /dev/null
@@ -0,0 +1,52 @@
+From faead41cc7213ccef5a58c1bf518ac24816fe8a6 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 22 Sep 2016 10:31:41 +0200
+Subject: iwlwifi: pcie: mark command queue lock with separate lockdep class
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit faead41cc7213ccef5a58c1bf518ac24816fe8a6 upstream.
+
+Emmanuel reports that when CMD_WANT_ASYNC_CALLBACK is used by mvm,
+the callback will be called with the command queue lock held, and
+mvm will try to stop all (other) TX queues, which acquires their
+locks - this caused a false lockdep recursive locking report.
+
+Suppress this report by marking the command queue lock with a new,
+separate, lock class so lockdep can tell the difference between
+the two types of queues.
+
+Fixes: 156f92f2b471 ("iwlwifi: block the queues when we send ADD_STA for uAPSD")
+Reported-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/intel/iwlwifi/pcie/tx.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+@@ -522,6 +522,7 @@ error:
+ static int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq,
+                             int slots_num, u32 txq_id)
+ {
++      struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       int ret;
+       txq->need_update = false;
+@@ -536,6 +537,13 @@ static int iwl_pcie_txq_init(struct iwl_
+               return ret;
+       spin_lock_init(&txq->lock);
++
++      if (txq_id == trans_pcie->cmd_queue) {
++              static struct lock_class_key iwl_pcie_cmd_queue_lock_class;
++
++              lockdep_set_class(&txq->lock, &iwl_pcie_cmd_queue_lock_class);
++      }
++
+       __skb_queue_head_init(&txq->overflow_q);
+       /*
diff --git a/queue-4.8/mfd-core-fix-device-reference-leak-in-mfd_clone_cell.patch b/queue-4.8/mfd-core-fix-device-reference-leak-in-mfd_clone_cell.patch
new file mode 100644 (file)
index 0000000..c8bc200
--- /dev/null
@@ -0,0 +1,32 @@
+From 722f191080de641f023feaa7d5648caf377844f5 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 1 Nov 2016 11:38:18 +0100
+Subject: mfd: core: Fix device reference leak in mfd_clone_cell
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 722f191080de641f023feaa7d5648caf377844f5 upstream.
+
+Make sure to drop the reference taken by bus_find_device_by_name()
+before returning from mfd_clone_cell().
+
+Fixes: a9bbba996302 ("mfd: add platform_device sharing support for mfd")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mfd/mfd-core.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/mfd/mfd-core.c
++++ b/drivers/mfd/mfd-core.c
+@@ -399,6 +399,8 @@ int mfd_clone_cell(const char *cell, con
+                                       clones[i]);
+       }
++      put_device(dev);
++
+       return 0;
+ }
+ EXPORT_SYMBOL(mfd_clone_cell);
diff --git a/queue-4.8/netfilter-nft_dynset-fix-element-timeout-for-hz-1000.patch b/queue-4.8/netfilter-nft_dynset-fix-element-timeout-for-hz-1000.patch
new file mode 100644 (file)
index 0000000..d265918
--- /dev/null
@@ -0,0 +1,48 @@
+From a8b1e36d0d1d6f51490e7adce35367ed6adb10e7 Mon Sep 17 00:00:00 2001
+From: "Anders K. Pedersen" <akp@cohaesio.com>
+Date: Sun, 9 Oct 2016 13:49:02 +0000
+Subject: netfilter: nft_dynset: fix element timeout for HZ != 1000
+
+From: Anders K. Pedersen <akp@cohaesio.com>
+
+commit a8b1e36d0d1d6f51490e7adce35367ed6adb10e7 upstream.
+
+With HZ=100 element timeout in dynamic sets (i.e. flow tables) is 10 times
+higher than configured.
+
+Add proper conversion to/from jiffies, when interacting with userspace.
+
+I tested this on Linux 4.8.1, and it applies cleanly to current nf and
+nf-next trees.
+
+Fixes: 22fe54d5fefc ("netfilter: nf_tables: add support for dynamic set updates")
+Signed-off-by: Anders K. Pedersen <akp@cohaesio.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/nft_dynset.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/net/netfilter/nft_dynset.c
++++ b/net/netfilter/nft_dynset.c
+@@ -143,7 +143,8 @@ static int nft_dynset_init(const struct
+       if (tb[NFTA_DYNSET_TIMEOUT] != NULL) {
+               if (!(set->flags & NFT_SET_TIMEOUT))
+                       return -EINVAL;
+-              timeout = be64_to_cpu(nla_get_be64(tb[NFTA_DYNSET_TIMEOUT]));
++              timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
++                                              tb[NFTA_DYNSET_TIMEOUT])));
+       }
+       priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]);
+@@ -230,7 +231,8 @@ static int nft_dynset_dump(struct sk_buf
+               goto nla_put_failure;
+       if (nla_put_string(skb, NFTA_DYNSET_SET_NAME, priv->set->name))
+               goto nla_put_failure;
+-      if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT, cpu_to_be64(priv->timeout),
++      if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT,
++                       cpu_to_be64(jiffies_to_msecs(priv->timeout)),
+                        NFTA_DYNSET_PAD))
+               goto nla_put_failure;
+       if (priv->expr && nft_expr_dump(skb, NFTA_DYNSET_EXPR, priv->expr))
diff --git a/queue-4.8/perf-hists-fix-column-length-on-hierarchy.patch b/queue-4.8/perf-hists-fix-column-length-on-hierarchy.patch
new file mode 100644 (file)
index 0000000..574b643
--- /dev/null
@@ -0,0 +1,62 @@
+From c72ab446cac1d6c9551fd26c4cfef1b2fc5041fd Mon Sep 17 00:00:00 2001
+From: Namhyung Kim <namhyung@kernel.org>
+Date: Tue, 8 Nov 2016 22:08:33 +0900
+Subject: perf hists: Fix column length on --hierarchy
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+commit c72ab446cac1d6c9551fd26c4cfef1b2fc5041fd upstream.
+
+Markus reported that there's a weird behavior on perf top --hierarchy
+regarding the column length.
+
+Looking at the code, I found a dubious code which affects the symptoms.
+When --hierarchy option is used, the last column length might be
+inaccurate since it skips to update the length on leaf entries.
+
+I cannot remember why it did and looks like a leftover from previous
+version during the development.
+
+Anyway, updating the column length often is not harmful.  So let's move
+the code out.
+
+Reported-and-Tested-by: Markus Trippelsdorf <markus@trippelsdorf.de>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Fixes: 1a3906a7e6b9 ("perf hists: Resort hist entries with hierarchy")
+Link: http://lkml.kernel.org/r/20161108130833.9263-5-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/util/hist.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/tools/perf/util/hist.c
++++ b/tools/perf/util/hist.c
+@@ -1596,18 +1596,18 @@ static void hists__hierarchy_output_reso
+               if (prog)
+                       ui_progress__update(prog, 1);
++              hists->nr_entries++;
++              if (!he->filtered) {
++                      hists->nr_non_filtered_entries++;
++                      hists__calc_col_len(hists, he);
++              }
++
+               if (!he->leaf) {
+                       hists__hierarchy_output_resort(hists, prog,
+                                                      &he->hroot_in,
+                                                      &he->hroot_out,
+                                                      min_callchain_hits,
+                                                      use_callchain);
+-                      hists->nr_entries++;
+-                      if (!he->filtered) {
+-                              hists->nr_non_filtered_entries++;
+-                              hists__calc_col_len(hists, he);
+-                      }
+-
+                       continue;
+               }
diff --git a/queue-4.8/pm-sleep-don-t-suspend-parent-when-async-child-suspend_-noirq-late-fails.patch b/queue-4.8/pm-sleep-don-t-suspend-parent-when-async-child-suspend_-noirq-late-fails.patch
new file mode 100644 (file)
index 0000000..03c4229
--- /dev/null
@@ -0,0 +1,77 @@
+From 6f75c3fd56daf547d684127a7f83c283c3c160d1 Mon Sep 17 00:00:00 2001
+From: Brian Norris <briannorris@chromium.org>
+Date: Wed, 9 Nov 2016 17:21:08 -0800
+Subject: PM / sleep: don't suspend parent when async child suspend_{noirq, late} fails
+
+From: Brian Norris <briannorris@chromium.org>
+
+commit 6f75c3fd56daf547d684127a7f83c283c3c160d1 upstream.
+
+Consider two devices, A and B, where B is a child of A, and B utilizes
+asynchronous suspend (it does not matter whether A is sync or async). If
+B fails to suspend_noirq() or suspend_late(), or is interrupted by a
+wakeup (pm_wakeup_pending()), then it aborts and sets the async_error
+variable. However, device A does not (immediately) check the async_error
+variable; it may continue to run its own suspend_noirq()/suspend_late()
+callback. This is bad.
+
+We can resolve this problem by doing our error and wakeup checking
+(particularly, for the async_error flag) after waiting for children to
+suspend, instead of before. This also helps align the logic for the noirq and
+late suspend cases with the logic in __device_suspend().
+
+It's easy to observe this erroneous behavior by, for example, forcing a
+device to sleep a bit in its suspend_noirq() (to ensure the parent is
+waiting for the child to complete), then return an error, and watch the
+parent suspend_noirq() still get called. (Or similarly, fake a wakeup
+event at the right (or is it wrong?) time.)
+
+Fixes: de377b397272 (PM / sleep: Asynchronous threads for suspend_late)
+Fixes: 28b6fd6e3779 (PM / sleep: Asynchronous threads for suspend_noirq)
+Reported-by: Jeffy Chen <jeffy.chen@rock-chips.com>
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/power/main.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/base/power/main.c
++++ b/drivers/base/power/main.c
+@@ -1027,6 +1027,8 @@ static int __device_suspend_noirq(struct
+       TRACE_DEVICE(dev);
+       TRACE_SUSPEND(0);
++      dpm_wait_for_children(dev, async);
++
+       if (async_error)
+               goto Complete;
+@@ -1038,8 +1040,6 @@ static int __device_suspend_noirq(struct
+       if (dev->power.syscore || dev->power.direct_complete)
+               goto Complete;
+-      dpm_wait_for_children(dev, async);
+-
+       if (dev->pm_domain) {
+               info = "noirq power domain ";
+               callback = pm_noirq_op(&dev->pm_domain->ops, state);
+@@ -1174,6 +1174,8 @@ static int __device_suspend_late(struct
+       __pm_runtime_disable(dev, false);
++      dpm_wait_for_children(dev, async);
++
+       if (async_error)
+               goto Complete;
+@@ -1185,8 +1187,6 @@ static int __device_suspend_late(struct
+       if (dev->power.syscore || dev->power.direct_complete)
+               goto Complete;
+-      dpm_wait_for_children(dev, async);
+-
+       if (dev->pm_domain) {
+               info = "late power domain ";
+               callback = pm_late_early_op(&dev->pm_domain->ops, state);
diff --git a/queue-4.8/pm-sleep-fix-device-reference-leak-in-test_suspend.patch b/queue-4.8/pm-sleep-fix-device-reference-leak-in-test_suspend.patch
new file mode 100644 (file)
index 0000000..d96b53f
--- /dev/null
@@ -0,0 +1,35 @@
+From ceb75787bc75d0a7b88519ab8a68067ac690f55a Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 1 Nov 2016 11:49:56 +0100
+Subject: PM / sleep: fix device reference leak in test_suspend
+
+From: Johan Hovold <johan@kernel.org>
+
+commit ceb75787bc75d0a7b88519ab8a68067ac690f55a upstream.
+
+Make sure to drop the reference taken by class_find_device() after
+opening the RTC device.
+
+Fixes: 77437fd4e61f (pm: boot time suspend selftest)
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/power/suspend_test.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/kernel/power/suspend_test.c
++++ b/kernel/power/suspend_test.c
+@@ -203,8 +203,10 @@ static int __init test_suspend(void)
+       /* RTCs have initialized by now too ... can we use one? */
+       dev = class_find_device(rtc_class, NULL, NULL, has_wakealarm);
+-      if (dev)
++      if (dev) {
+               rtc = rtc_class_open(dev_name(dev));
++              put_device(dev);
++      }
+       if (!rtc) {
+               printk(warn_no_rtc);
+               return 0;
diff --git a/queue-4.8/rtc-omap-fix-selecting-external-osc.patch b/queue-4.8/rtc-omap-fix-selecting-external-osc.patch
new file mode 100644 (file)
index 0000000..367fed2
--- /dev/null
@@ -0,0 +1,67 @@
+From 3984903a2e3906d3def220e688040ce93368200a Mon Sep 17 00:00:00 2001
+From: Lokesh Vutla <lokeshvutla@ti.com>
+Date: Thu, 27 Oct 2016 11:27:25 +0530
+Subject: rtc: omap: Fix selecting external osc
+
+From: Lokesh Vutla <lokeshvutla@ti.com>
+
+commit 3984903a2e3906d3def220e688040ce93368200a upstream.
+
+RTC can be clocked from an external 32KHz oscillator, or from the
+Peripheral PLL. The RTC has an internal oscillator buffer to support
+direct operation with a crystal.
+
+            ----------------------------------------
+            |       Device          ---------       |
+            |                       |       |       |
+            |                       | RTCSS |       |
+            |       ---------       |       |       |
+    OSC     |<------| RTC   |       |       |       |
+            |------>| OSC   |---    |       |       |
+            |       --------   |    |       |       |
+            |                   ----|clk    |       |
+            |       --------   |    |       |       |
+            |       | PRCM  |---    |       |       |
+            |       --------        --------        |
+            ----------------------------------------
+
+The RTC functional clock is sourced by default from the clock derived
+from the Peripheral PLL. In order to select source as external osc clk
+the following changes needs to be done:
+- Enable the RTC OSC (RTC_OSC_REG[4]OSC32K_GZ = 0)
+- Enable the clock mux(RTC_OSC_REG[6]K32CLK_EN = 1)
+- Select the external clock source (RTC_OSC_REG[3]32KCLK_SEL = 1)
+
+Fixes: 399cf0f63f6f2 ("rtc: omap: Add external clock enabling support")
+Signed-off-by: Keerthy <j-keerthy@ti.com>
+Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
+Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/rtc-omap.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/rtc/rtc-omap.c
++++ b/drivers/rtc/rtc-omap.c
+@@ -109,6 +109,7 @@
+ /* OMAP_RTC_OSC_REG bit fields: */
+ #define OMAP_RTC_OSC_32KCLK_EN                BIT(6)
+ #define OMAP_RTC_OSC_SEL_32KCLK_SRC   BIT(3)
++#define OMAP_RTC_OSC_OSC32K_GZ_DISABLE        BIT(4)
+ /* OMAP_RTC_IRQWAKEEN bit fields: */
+ #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN       BIT(1)
+@@ -646,8 +647,9 @@ static int omap_rtc_probe(struct platfor
+        */
+       if (rtc->has_ext_clk) {
+               reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
+-              rtc_write(rtc, OMAP_RTC_OSC_REG,
+-                        reg | OMAP_RTC_OSC_SEL_32KCLK_SRC);
++              reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE;
++              reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC;
++              rtc_writel(rtc, OMAP_RTC_OSC_REG, reg);
+       }
+       rtc->type->lock(rtc);
index da428c3a452e3db44465d6ad9da92ad98d2fec2f..e0dec938ba4684b4205d90490bb15de00433152a 100644 (file)
@@ -32,3 +32,35 @@ drm-amdgpu-attach-exclusive-fence-to-prime-exported-bo-s.-v5.patch
 drm-i915-refresh-that-status-of-mst-capable-connectors-in-detect.patch
 drm-i915-assume-non-dp-port-if-dvo_port-is-hdmi-and-there-s-no-aux-ch-specified-in-the-vbt.patch
 virtio-net-drop-legacy-features-in-virtio-1-mode.patch
+clk-mmp-pxa910-fix-return-value-check-in-pxa910_clk_init.patch
+clk-mmp-pxa168-fix-return-value-check-in-pxa168_clk_init.patch
+clk-mmp-mmp2-fix-return-value-check-in-mmp2_clk_init.patch
+clk-imx-fix-integer-overflow-in-av-pll-round-rate.patch
+rtc-omap-fix-selecting-external-osc.patch
+iwlwifi-pcie-fix-splc-structure-parsing.patch
+iwlwifi-pcie-mark-command-queue-lock-with-separate-lockdep-class.patch
+iwlwifi-mvm-fix-netdetect-starting-stopping-for-unified-images.patch
+iwlwifi-mvm-fix-d3_test-with-unified-d0-d3-images.patch
+iwlwifi-mvm-wake-the-wait-queue-when-the-rx-sync-counter-is-zero.patch
+mfd-core-fix-device-reference-leak-in-mfd_clone_cell.patch
+sunrpc-svc_age_temp_xprts_now-should-not-call-setsockopt-non-tcp-transports.patch
+uwb-fix-device-reference-leaks.patch
+pm-sleep-fix-device-reference-leak-in-test_suspend.patch
+pm-sleep-don-t-suspend-parent-when-async-child-suspend_-noirq-late-fails.patch
+perf-hists-fix-column-length-on-hierarchy.patch
+ib-rxe-update-qp-state-for-user-query.patch
+ib-rxe-fix-kernel-panic-in-udp-tunnel-with-gro-and-rx-checksum.patch
+ib-rxe-fix-handling-of-erroneous-wr.patch
+ib-rxe-clear-queue-buffer-when-modifying-qp-to-reset.patch
+ib-mlx4-check-gid_index-return-value.patch
+ib-mlx4-fix-create-cq-error-flow.patch
+ib-mlx5-validate-requested-rqt-size.patch
+ib-mlx5-use-cache-line-size-to-select-cqe-stride.patch
+ib-mlx5-fix-memory-leak-in-query-device.patch
+ib-mlx5-fix-fatal-error-dispatching.patch
+ib-mlx5-fix-null-pointer-dereference-on-debug-print.patch
+ib-core-avoid-unsigned-int-overflow-in-sg_alloc_table.patch
+ib-hfi1-remove-incorrect-is_err-check.patch
+ib-uverbs-fix-leak-of-xrc-target-qps.patch
+ib-cm-mark-stale-cm-id-s-whenever-the-mad-agent-was-unregistered.patch
+netfilter-nft_dynset-fix-element-timeout-for-hz-1000.patch
diff --git a/queue-4.8/sunrpc-svc_age_temp_xprts_now-should-not-call-setsockopt-non-tcp-transports.patch b/queue-4.8/sunrpc-svc_age_temp_xprts_now-should-not-call-setsockopt-non-tcp-transports.patch
new file mode 100644 (file)
index 0000000..483c035
--- /dev/null
@@ -0,0 +1,205 @@
+From ea08e39230e898844d9de5b60cdbb30067cebfe7 Mon Sep 17 00:00:00 2001
+From: Scott Mayhew <smayhew@redhat.com>
+Date: Fri, 11 Nov 2016 13:16:22 -0500
+Subject: sunrpc: svc_age_temp_xprts_now should not call setsockopt non-tcp transports
+
+From: Scott Mayhew <smayhew@redhat.com>
+
+commit ea08e39230e898844d9de5b60cdbb30067cebfe7 upstream.
+
+This fixes the following panic that can occur with NFSoRDMA.
+
+general protection fault: 0000 [#1] SMP
+Modules linked in: rpcrdma ib_isert iscsi_target_mod ib_iser libiscsi
+scsi_transport_iscsi ib_srpt target_core_mod ib_srp scsi_transport_srp
+scsi_tgt ib_ipoib rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm
+mlx5_ib ib_core intel_powerclamp coretemp kvm_intel kvm sg ioatdma
+ipmi_devintf ipmi_ssif dcdbas iTCO_wdt iTCO_vendor_support pcspkr
+irqbypass sb_edac shpchp dca crc32_pclmul ghash_clmulni_intel edac_core
+lpc_ich aesni_intel lrw gf128mul glue_helper ablk_helper mei_me mei
+ipmi_si cryptd wmi ipmi_msghandler acpi_pad acpi_power_meter nfsd
+auth_rpcgss nfs_acl lockd grace sunrpc ip_tables xfs libcrc32c sd_mod
+crc_t10dif crct10dif_generic mgag200 i2c_algo_bit drm_kms_helper
+syscopyarea sysfillrect sysimgblt ahci fb_sys_fops ttm libahci mlx5_core
+tg3 crct10dif_pclmul drm crct10dif_common
+ptp i2c_core libata crc32c_intel pps_core fjes dm_mirror dm_region_hash
+dm_log dm_mod
+CPU: 1 PID: 120 Comm: kworker/1:1 Not tainted 3.10.0-514.el7.x86_64 #1
+Hardware name: Dell Inc. PowerEdge R320/0KM5PX, BIOS 2.4.2 01/29/2015
+Workqueue: events check_lifetime
+task: ffff88031f506dd0 ti: ffff88031f584000 task.ti: ffff88031f584000
+RIP: 0010:[<ffffffff8168d847>]  [<ffffffff8168d847>]
+_raw_spin_lock_bh+0x17/0x50
+RSP: 0018:ffff88031f587ba8  EFLAGS: 00010206
+RAX: 0000000000020000 RBX: 20041fac02080072 RCX: ffff88031f587fd8
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: 20041fac02080072
+RBP: ffff88031f587bb0 R08: 0000000000000008 R09: ffffffff8155be77
+R10: ffff880322a59b00 R11: ffffea000bf39f00 R12: 20041fac02080072
+R13: 000000000000000d R14: ffff8800c4fbd800 R15: 0000000000000001
+FS:  0000000000000000(0000) GS:ffff880322a40000(0000)
+knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f3c52d4547e CR3: 00000000019ba000 CR4: 00000000001407e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+Stack:
+20041fac02080002 ffff88031f587bd0 ffffffff81557830 20041fac02080002
+ffff88031f587c78 ffff88031f587c40 ffffffff8155ae08 000000010157df32
+0000000800000001 ffff88031f587c20 ffffffff81096acb ffffffff81aa37d0
+Call Trace:
+[<ffffffff81557830>] lock_sock_nested+0x20/0x50
+[<ffffffff8155ae08>] sock_setsockopt+0x78/0x940
+[<ffffffff81096acb>] ? lock_timer_base.isra.33+0x2b/0x50
+[<ffffffff8155397d>] kernel_setsockopt+0x4d/0x50
+[<ffffffffa0386284>] svc_age_temp_xprts_now+0x174/0x1e0 [sunrpc]
+[<ffffffffa03b681d>] nfsd_inetaddr_event+0x9d/0xd0 [nfsd]
+[<ffffffff81691ebc>] notifier_call_chain+0x4c/0x70
+[<ffffffff810b687d>] __blocking_notifier_call_chain+0x4d/0x70
+[<ffffffff810b68b6>] blocking_notifier_call_chain+0x16/0x20
+[<ffffffff815e8538>] __inet_del_ifa+0x168/0x2d0
+[<ffffffff815e8cef>] check_lifetime+0x25f/0x270
+[<ffffffff810a7f3b>] process_one_work+0x17b/0x470
+[<ffffffff810a8d76>] worker_thread+0x126/0x410
+[<ffffffff810a8c50>] ? rescuer_thread+0x460/0x460
+[<ffffffff810b052f>] kthread+0xcf/0xe0
+[<ffffffff810b0460>] ? kthread_create_on_node+0x140/0x140
+[<ffffffff81696418>] ret_from_fork+0x58/0x90
+[<ffffffff810b0460>] ? kthread_create_on_node+0x140/0x140
+Code: ca 75 f1 5d c3 0f 1f 80 00 00 00 00 eb d9 66 0f 1f 44 00 00 0f 1f
+44 00 00 55 48 89 e5 53 48 89 fb e8 7e 04 a0 ff b8 00 00 02 00 <f0> 0f
+c1 03 89 c2 c1 ea 10 66 39 c2 75 03 5b 5d c3 83 e2 fe 0f
+RIP  [<ffffffff8168d847>] _raw_spin_lock_bh+0x17/0x50
+RSP <ffff88031f587ba8>
+
+Signed-off-by: Scott Mayhew <smayhew@redhat.com>
+Fixes: c3d4879e ("sunrpc: Add a function to close temporary transports immediately")
+Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/sunrpc/svc_xprt.h          |    1 +
+ net/sunrpc/svc_xprt.c                    |   11 +----------
+ net/sunrpc/svcsock.c                     |   21 +++++++++++++++++++++
+ net/sunrpc/xprtrdma/svc_rdma_transport.c |    6 ++++++
+ 4 files changed, 29 insertions(+), 10 deletions(-)
+
+--- a/include/linux/sunrpc/svc_xprt.h
++++ b/include/linux/sunrpc/svc_xprt.h
+@@ -25,6 +25,7 @@ struct svc_xprt_ops {
+       void            (*xpo_detach)(struct svc_xprt *);
+       void            (*xpo_free)(struct svc_xprt *);
+       int             (*xpo_secure_port)(struct svc_rqst *);
++      void            (*xpo_kill_temp_xprt)(struct svc_xprt *);
+ };
+ struct svc_xprt_class {
+--- a/net/sunrpc/svc_xprt.c
++++ b/net/sunrpc/svc_xprt.c
+@@ -1002,14 +1002,8 @@ static void svc_age_temp_xprts(unsigned
+ void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr)
+ {
+       struct svc_xprt *xprt;
+-      struct svc_sock *svsk;
+-      struct socket *sock;
+       struct list_head *le, *next;
+       LIST_HEAD(to_be_closed);
+-      struct linger no_linger = {
+-              .l_onoff = 1,
+-              .l_linger = 0,
+-      };
+       spin_lock_bh(&serv->sv_lock);
+       list_for_each_safe(le, next, &serv->sv_tempsocks) {
+@@ -1027,10 +1021,7 @@ void svc_age_temp_xprts_now(struct svc_s
+               list_del_init(le);
+               xprt = list_entry(le, struct svc_xprt, xpt_list);
+               dprintk("svc_age_temp_xprts_now: closing %p\n", xprt);
+-              svsk = container_of(xprt, struct svc_sock, sk_xprt);
+-              sock = svsk->sk_sock;
+-              kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
+-                                (char *)&no_linger, sizeof(no_linger));
++              xprt->xpt_ops->xpo_kill_temp_xprt(xprt);
+               svc_close_xprt(xprt);
+       }
+ }
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -438,6 +438,21 @@ static int svc_tcp_has_wspace(struct svc
+       return !test_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
+ }
++static void svc_tcp_kill_temp_xprt(struct svc_xprt *xprt)
++{
++      struct svc_sock *svsk;
++      struct socket *sock;
++      struct linger no_linger = {
++              .l_onoff = 1,
++              .l_linger = 0,
++      };
++
++      svsk = container_of(xprt, struct svc_sock, sk_xprt);
++      sock = svsk->sk_sock;
++      kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
++                        (char *)&no_linger, sizeof(no_linger));
++}
++
+ /*
+  * See net/ipv6/ip_sockglue.c : ip_cmsg_recv_pktinfo
+  */
+@@ -648,6 +663,10 @@ static struct svc_xprt *svc_udp_accept(s
+       return NULL;
+ }
++static void svc_udp_kill_temp_xprt(struct svc_xprt *xprt)
++{
++}
++
+ static struct svc_xprt *svc_udp_create(struct svc_serv *serv,
+                                      struct net *net,
+                                      struct sockaddr *sa, int salen,
+@@ -667,6 +686,7 @@ static struct svc_xprt_ops svc_udp_ops =
+       .xpo_has_wspace = svc_udp_has_wspace,
+       .xpo_accept = svc_udp_accept,
+       .xpo_secure_port = svc_sock_secure_port,
++      .xpo_kill_temp_xprt = svc_udp_kill_temp_xprt,
+ };
+ static struct svc_xprt_class svc_udp_class = {
+@@ -1242,6 +1262,7 @@ static struct svc_xprt_ops svc_tcp_ops =
+       .xpo_has_wspace = svc_tcp_has_wspace,
+       .xpo_accept = svc_tcp_accept,
+       .xpo_secure_port = svc_sock_secure_port,
++      .xpo_kill_temp_xprt = svc_tcp_kill_temp_xprt,
+ };
+ static struct svc_xprt_class svc_tcp_class = {
+--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
++++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
+@@ -67,6 +67,7 @@ static void svc_rdma_detach(struct svc_x
+ static void svc_rdma_free(struct svc_xprt *xprt);
+ static int svc_rdma_has_wspace(struct svc_xprt *xprt);
+ static int svc_rdma_secure_port(struct svc_rqst *);
++static void svc_rdma_kill_temp_xprt(struct svc_xprt *);
+ static struct svc_xprt_ops svc_rdma_ops = {
+       .xpo_create = svc_rdma_create,
+@@ -79,6 +80,7 @@ static struct svc_xprt_ops svc_rdma_ops
+       .xpo_has_wspace = svc_rdma_has_wspace,
+       .xpo_accept = svc_rdma_accept,
+       .xpo_secure_port = svc_rdma_secure_port,
++      .xpo_kill_temp_xprt = svc_rdma_kill_temp_xprt,
+ };
+ struct svc_xprt_class svc_rdma_class = {
+@@ -1285,6 +1287,10 @@ static int svc_rdma_secure_port(struct s
+       return 1;
+ }
++static void svc_rdma_kill_temp_xprt(struct svc_xprt *xprt)
++{
++}
++
+ int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr)
+ {
+       struct ib_send_wr *bad_wr, *n_wr;
diff --git a/queue-4.8/uwb-fix-device-reference-leaks.patch b/queue-4.8/uwb-fix-device-reference-leaks.patch
new file mode 100644 (file)
index 0000000..55b137c
--- /dev/null
@@ -0,0 +1,86 @@
+From d6124b409ca33c100170ffde51cd8dff761454a1 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 1 Nov 2016 12:13:31 +0100
+Subject: uwb: fix device reference leaks
+
+From: Johan Hovold <johan@kernel.org>
+
+commit d6124b409ca33c100170ffde51cd8dff761454a1 upstream.
+
+This subsystem consistently fails to drop the device reference taken by
+class_find_device().
+
+Note that some of these lookup functions already take a reference to the
+returned data, while others claim no reference is needed (or does not
+seem need one).
+
+Fixes: 183b9b592a62 ("uwb: add the UWB stack (core files)")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/uwb/lc-rc.c |   16 +++++++++++++---
+ drivers/uwb/pal.c   |    2 ++
+ 2 files changed, 15 insertions(+), 3 deletions(-)
+
+--- a/drivers/uwb/lc-rc.c
++++ b/drivers/uwb/lc-rc.c
+@@ -56,8 +56,11 @@ static struct uwb_rc *uwb_rc_find_by_ind
+       struct uwb_rc *rc = NULL;
+       dev = class_find_device(&uwb_rc_class, NULL, &index, uwb_rc_index_match);
+-      if (dev)
++      if (dev) {
+               rc = dev_get_drvdata(dev);
++              put_device(dev);
++      }
++
+       return rc;
+ }
+@@ -467,7 +470,9 @@ struct uwb_rc *__uwb_rc_try_get(struct u
+       if (dev) {
+               rc = dev_get_drvdata(dev);
+               __uwb_rc_get(rc);
++              put_device(dev);
+       }
++
+       return rc;
+ }
+ EXPORT_SYMBOL_GPL(__uwb_rc_try_get);
+@@ -520,8 +525,11 @@ struct uwb_rc *uwb_rc_get_by_grandpa(con
+       dev = class_find_device(&uwb_rc_class, NULL, grandpa_dev,
+                               find_rc_grandpa);
+-      if (dev)
++      if (dev) {
+               rc = dev_get_drvdata(dev);
++              put_device(dev);
++      }
++
+       return rc;
+ }
+ EXPORT_SYMBOL_GPL(uwb_rc_get_by_grandpa);
+@@ -553,8 +561,10 @@ struct uwb_rc *uwb_rc_get_by_dev(const s
+       struct uwb_rc *rc = NULL;
+       dev = class_find_device(&uwb_rc_class, NULL, addr, find_rc_dev);
+-      if (dev)
++      if (dev) {
+               rc = dev_get_drvdata(dev);
++              put_device(dev);
++      }
+       return rc;
+ }
+--- a/drivers/uwb/pal.c
++++ b/drivers/uwb/pal.c
+@@ -97,6 +97,8 @@ static bool uwb_rc_class_device_exists(s
+       dev = class_find_device(&uwb_rc_class, NULL, target_rc, find_rc);
++      put_device(dev);
++
+       return (dev != NULL);
+ }