]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
patches for 4.20
authorSasha Levin <sashal@kernel.org>
Mon, 28 Jan 2019 22:25:40 +0000 (17:25 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 28 Jan 2019 22:25:40 +0000 (17:25 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.20/drivers-hv-vmbus-remove-the-useless-api-vmbus_get_ou.patch [new file with mode: 0644]
queue-4.20/series
queue-4.20/vmbus-fix-subchannel-removal.patch [new file with mode: 0644]

diff --git a/queue-4.20/drivers-hv-vmbus-remove-the-useless-api-vmbus_get_ou.patch b/queue-4.20/drivers-hv-vmbus-remove-the-useless-api-vmbus_get_ou.patch
new file mode 100644 (file)
index 0000000..e08ba3c
--- /dev/null
@@ -0,0 +1,146 @@
+From 0d624f5633d44b91de03f9e1187bec2216ad1695 Mon Sep 17 00:00:00 2001
+From: Dexuan Cui <decui@microsoft.com>
+Date: Mon, 26 Nov 2018 02:17:56 +0000
+Subject: Drivers: hv: vmbus: Remove the useless API
+ vmbus_get_outgoing_channel()
+
+[ Upstream commit 4d3c5c69191f98c7f7e699ff08d2fd96d7070ddb ]
+
+Commit d86adf482b84 ("scsi: storvsc: Enable multi-queue support") removed
+the usage of the API in Jan 2017, and the API is not used since then.
+
+netvsc and storvsc have their own algorithms to determine the outgoing
+channel, so this API is useless.
+
+And the API is potentially unsafe, because it reads primary->num_sc without
+any lock held. This can be risky considering the RESCIND-OFFER message.
+
+Let's remove the API.
+
+Cc: Long Li <longli@microsoft.com>
+Cc: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/channel.c      |  1 -
+ drivers/hv/channel_mgmt.c | 44 ---------------------------------------
+ include/linux/hyperv.h    | 17 ---------------
+ 3 files changed, 62 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index fe00b12e4417..ce0ba2062723 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -711,7 +711,6 @@ int vmbus_disconnect_ring(struct vmbus_channel *channel)
+       /* Snapshot the list of subchannels */
+       spin_lock_irqsave(&channel->lock, flags);
+       list_splice_init(&channel->sc_list, &list);
+-      channel->num_sc = 0;
+       spin_unlock_irqrestore(&channel->lock, flags);
+       list_for_each_entry_safe(cur_channel, tmp, &list, sc_list) {
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index edd34c167a9b..d01689079e9b 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -405,7 +405,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel)
+               primary_channel = channel->primary_channel;
+               spin_lock_irqsave(&primary_channel->lock, flags);
+               list_del(&channel->sc_list);
+-              primary_channel->num_sc--;
+               spin_unlock_irqrestore(&primary_channel->lock, flags);
+       }
+@@ -1302,49 +1301,6 @@ int vmbus_request_offers(void)
+       return ret;
+ }
+-/*
+- * Retrieve the (sub) channel on which to send an outgoing request.
+- * When a primary channel has multiple sub-channels, we try to
+- * distribute the load equally amongst all available channels.
+- */
+-struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
+-{
+-      struct list_head *cur, *tmp;
+-      int cur_cpu;
+-      struct vmbus_channel *cur_channel;
+-      struct vmbus_channel *outgoing_channel = primary;
+-      int next_channel;
+-      int i = 1;
+-
+-      if (list_empty(&primary->sc_list))
+-              return outgoing_channel;
+-
+-      next_channel = primary->next_oc++;
+-
+-      if (next_channel > (primary->num_sc)) {
+-              primary->next_oc = 0;
+-              return outgoing_channel;
+-      }
+-
+-      cur_cpu = hv_cpu_number_to_vp_number(smp_processor_id());
+-      list_for_each_safe(cur, tmp, &primary->sc_list) {
+-              cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
+-              if (cur_channel->state != CHANNEL_OPENED_STATE)
+-                      continue;
+-
+-              if (cur_channel->target_vp == cur_cpu)
+-                      return cur_channel;
+-
+-              if (i == next_channel)
+-                      return cur_channel;
+-
+-              i++;
+-      }
+-
+-      return outgoing_channel;
+-}
+-EXPORT_SYMBOL_GPL(vmbus_get_outgoing_channel);
+-
+ static void invoke_sc_cb(struct vmbus_channel *primary_channel)
+ {
+       struct list_head *cur, *tmp;
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index ed74888087f1..dcb6977afce9 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -830,15 +830,6 @@ struct vmbus_channel {
+        * All Sub-channels of a primary channel are linked here.
+        */
+       struct list_head sc_list;
+-      /*
+-       * Current number of sub-channels.
+-       */
+-      int num_sc;
+-      /*
+-       * Number of a sub-channel (position within sc_list) which is supposed
+-       * to be used as the next outgoing channel.
+-       */
+-      int next_oc;
+       /*
+        * The primary channel this sub-channel belongs to.
+        * This will be NULL for the primary channel.
+@@ -972,14 +963,6 @@ void vmbus_set_sc_create_callback(struct vmbus_channel *primary_channel,
+ void vmbus_set_chn_rescind_callback(struct vmbus_channel *channel,
+               void (*chn_rescind_cb)(struct vmbus_channel *));
+-/*
+- * Retrieve the (sub) channel on which to send an outgoing request.
+- * When a primary channel has multiple sub-channels, we choose a
+- * channel whose VCPU binding is closest to the VCPU on which
+- * this call is being made.
+- */
+-struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary);
+-
+ /*
+  * Check if sub-channels have already been offerred. This API will be useful
+  * when the driver is unloaded after establishing sub-channels. In this case,
+-- 
+2.19.1
+
index bfe57ce0bfd4e9701d861ff64a51216f7e47447f..91d430be240c4b1fc6e1600da9a85f31ee4bab62 100644 (file)
@@ -101,3 +101,5 @@ bpf-fix-check_map_access-smin_value-test-when-pointe.patch
 bpf-prevent-out-of-bounds-speculation-on-pointer-ari.patch
 bpf-fix-sanitation-of-alu-op-with-pointer-scalar-typ.patch
 bpf-fix-inner-map-masking-to-prevent-oob-under-specu.patch
+drivers-hv-vmbus-remove-the-useless-api-vmbus_get_ou.patch
+vmbus-fix-subchannel-removal.patch
diff --git a/queue-4.20/vmbus-fix-subchannel-removal.patch b/queue-4.20/vmbus-fix-subchannel-removal.patch
new file mode 100644 (file)
index 0000000..bba936f
--- /dev/null
@@ -0,0 +1,61 @@
+From a7479cb9ea0010f77493ba17c63fffc0dcaf0f89 Mon Sep 17 00:00:00 2001
+From: Dexuan Cui <decui@microsoft.com>
+Date: Wed, 9 Jan 2019 20:56:06 +0000
+Subject: vmbus: fix subchannel removal
+
+[ Upstream commit b5679cebf780c6f1c2451a73bf1842a4409840e7 ]
+
+The changes to split ring allocation from open/close, broke
+the cleanup of subchannels. This resulted in problems using
+uio on network devices because the subchannel was left behind
+when the network device was unbound.
+
+The cause was in the disconnect logic which used list splice
+to move the subchannel list into a local variable. This won't
+work because the subchannel list is needed later during the
+process of the rescind messages (relid2channel).
+
+The fix is to just leave the subchannel list in place
+which is what the original code did. The list is cleaned
+up later when the host rescind is processed.
+
+Without the fix, we have a lot of "hang" issues in netvsc when we
+try to change the NIC's MTU, set the number of channels, etc.
+
+Fixes: ae6935ed7d42 ("vmbus: split ring buffer allocation from open")
+Cc: stable@vger.kernel.org
+Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/channel.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index ce0ba2062723..bea4c9850247 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -701,19 +701,12 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
+ int vmbus_disconnect_ring(struct vmbus_channel *channel)
+ {
+       struct vmbus_channel *cur_channel, *tmp;
+-      unsigned long flags;
+-      LIST_HEAD(list);
+       int ret;
+       if (channel->primary_channel != NULL)
+               return -EINVAL;
+-      /* Snapshot the list of subchannels */
+-      spin_lock_irqsave(&channel->lock, flags);
+-      list_splice_init(&channel->sc_list, &list);
+-      spin_unlock_irqrestore(&channel->lock, flags);
+-
+-      list_for_each_entry_safe(cur_channel, tmp, &list, sc_list) {
++      list_for_each_entry_safe(cur_channel, tmp, &channel->sc_list, sc_list) {
+               if (cur_channel->rescind)
+                       wait_for_completion(&cur_channel->rescind_event);
+-- 
+2.19.1
+