Home Home > GIT Browse > SLE12-SP5-AZURE
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlaf Hering <ohering@suse.de>2018-11-06 11:07:40 +0100
committerOlaf Hering <ohering@suse.de>2018-11-06 11:07:40 +0100
commit39fd780f6c1d94c79ec64ba899880fcbdeb065ae (patch)
tree313103389e157b254e90ddb292f6fdf0a25e3fef
parentba6543f8922ab4ece22c167807a45a8841473997 (diff)
hv_netvsc: Fix a deadlock by getting rtnl lock earlier inrpm-4.12.14-6.3--sle12-sp4-updatesrpm-4.12.14-6.3
netvsc_probe() (bsc#1109772).
-rw-r--r--patches.suse/msft-hv-1752-hv_netvsc-Fix-a-deadlock-by-getting-rtnl-lock-earlie.patch130
-rw-r--r--series.conf1
2 files changed, 131 insertions, 0 deletions
diff --git a/patches.suse/msft-hv-1752-hv_netvsc-Fix-a-deadlock-by-getting-rtnl-lock-earlie.patch b/patches.suse/msft-hv-1752-hv_netvsc-Fix-a-deadlock-by-getting-rtnl-lock-earlie.patch
new file mode 100644
index 0000000000..0424c2681a
--- /dev/null
+++ b/patches.suse/msft-hv-1752-hv_netvsc-Fix-a-deadlock-by-getting-rtnl-lock-earlie.patch
@@ -0,0 +1,130 @@
+From: Dexuan Cui <decui@microsoft.com>
+Date: Thu, 30 Aug 2018 05:42:13 +0000
+Patch-mainline: v4.19-rc3
+Subject: hv_netvsc: Fix a deadlock by getting rtnl lock earlier in netvsc_probe()
+Git-commit: e04e7a7bbd4bbabef4e1a58367e5fc9b2edc3b10
+References: bsc#1109772
+
+This patch fixes the race between netvsc_probe() and
+rndis_set_subchannel(), which can cause a deadlock.
+
+These are the related 3 paths which show the deadlock:
+
+path #1:
+ Workqueue: hv_vmbus_con vmbus_onmessage_work [hv_vmbus]
+ Call Trace:
+ schedule
+ schedule_preempt_disabled
+ __mutex_lock
+ __device_attach
+ bus_probe_device
+ device_add
+ vmbus_device_register
+ vmbus_onoffer
+ vmbus_onmessage_work
+ process_one_work
+ worker_thread
+ kthread
+ ret_from_fork
+
+path #2:
+ schedule
+ schedule_preempt_disabled
+ __mutex_lock
+ netvsc_probe
+ vmbus_probe
+ really_probe
+ __driver_attach
+ bus_for_each_dev
+ driver_attach_async
+ async_run_entry_fn
+ process_one_work
+ worker_thread
+ kthread
+ ret_from_fork
+
+path #3:
+ Workqueue: events netvsc_subchan_work [hv_netvsc]
+ Call Trace:
+ schedule
+ rndis_set_subchannel
+ netvsc_subchan_work
+ process_one_work
+ worker_thread
+ kthread
+ ret_from_fork
+
+Before path #1 finishes, path #2 can start to run, because just before
+the "bus_probe_device(dev);" in device_add() in path #1, there is a line
+"object_uevent(&dev->kobj, KOBJ_ADD);", so systemd-udevd can
+immediately try to load hv_netvsc and hence path #2 can start to run.
+
+Next, path #2 offloads the subchannal's initialization to a workqueue,
+i.e. path #3, so we can end up in a deadlock situation like this:
+
+Path #2 gets the device lock, and is trying to get the rtnl lock;
+Path #3 gets the rtnl lock and is waiting for all the subchannel messages
+to be processed;
+Path #1 is trying to get the device lock, but since #2 is not releasing
+the device lock, path #1 has to sleep; since the VMBus messages are
+processed one by one, this means the sub-channel messages can't be
+procedded, so #3 has to sleep with the rtnl lock held, and finally #2
+has to sleep... Now all the 3 paths are sleeping and we hit the deadlock.
+
+With the patch, we can make sure #2 gets both the device lock and the
+rtnl lock together, gets its job done, and releases the locks, so #1
+and #3 will not be blocked for ever.
+
+Fixes: 8195b1396ec8 ("hv_netvsc: fix deadlock on hotplug")
+Signed-off-by: Dexuan Cui <decui@microsoft.com>
+Cc: Stephen Hemminger <sthemmin@microsoft.com>
+Cc: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Olaf Hering <ohering@suse.de>
+---
+Contains parts of 7bf7bb37f1 ("hv_netvsc: fix network namespace issues with VF support")
+---
+ drivers/net/hyperv/netvsc_drv.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -2076,6 +2076,16 @@ static int netvsc_probe(struct hv_device *dev,
+
+ memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
+
++ /* We must get rtnl lock before scheduling nvdev->subchan_work,
++ * otherwise netvsc_subchan_work() can get rtnl lock first and wait
++ * all subchannels to show up, but that may not happen because
++ * netvsc_probe() can't get rtnl lock and as a result vmbus_onoffer()
++ * -> ... -> device_add() -> ... -> __device_attach() can't get
++ * the device lock, so all the subchannels can't be processed --
++ * finally netvsc_subchan_work() hangs for ever.
++ */
++ rtnl_lock();
++
+ if (nvdev->num_chn > 1)
+ schedule_work(&nvdev->subchan_work);
+
+@@ -2094,15 +2104,17 @@ static int netvsc_probe(struct hv_device *dev,
+ else
+ net->max_mtu = ETH_DATA_LEN;
+
+- ret = register_netdev(net);
++ ret = register_netdevice(net);
+ if (ret != 0) {
+ pr_err("Unable to register netdev.\n");
+ goto register_failed;
+ }
+
+- return ret;
++ rtnl_unlock();
++ return 0;
+
+ register_failed:
++ rtnl_unlock();
+ rndis_filter_device_remove(dev, nvdev);
+ rndis_failed:
+ free_percpu(net_device_ctx->vf_stats);
diff --git a/series.conf b/series.conf
index 854d13f384..f92af146b7 100644
--- a/series.conf
+++ b/series.conf
@@ -18183,6 +18183,7 @@
patches.fixes/vti6-remove-skb-ignore_df-check-from-vti6_xmit.patch
patches.drivers/net-hns-add-the-code-for-cleaning-pkt-in-chip.patch
patches.drivers/net-hns-add-netif_carrier_off-before-change-speed-an.patch
+ patches.suse/msft-hv-1752-hv_netvsc-Fix-a-deadlock-by-getting-rtnl-lock-earlie.patch
patches.drivers/ibmvnic-Include-missing-return-code-checks-in-reset-.patch
patches.drivers/r8169-add-support-for-NCube-8168-network-card.patch
patches.drivers/bnxt_en-Clean-up-unused-functions.patch