From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760161AbcCDV3g (ORCPT ); Fri, 4 Mar 2016 16:29:36 -0500 Received: from p3plsmtps2ded02.prod.phx3.secureserver.net ([208.109.80.59]:43341 "EHLO p3plsmtps2ded02.prod.phx3.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758765AbcCDV3e (ORCPT ); Fri, 4 Mar 2016 16:29:34 -0500 x-originating-ip: 72.167.245.219 From: Haiyang Zhang To: davem@davemloft.net, netdev@vger.kernel.org Cc: haiyangz@microsoft.com, kys@microsoft.com, olaf@aepfle.de, vkuznets@redhat.com, linux-kernel@vger.kernel.org, driverdev-devel@linuxdriverproject.org Subject: [PATCH net-next] hv_netvsc: Move subchannel waiting to rndis_filter_device_remove() Date: Fri, 4 Mar 2016 15:07:43 -0800 Message-Id: <1457132863-7262-1-git-send-email-haiyangz@microsoft.com> X-Mailer: git-send-email 1.7.4.1 X-CMAE-Envelope: MS4wfPLAtItE14X0Pugt/+O9Oq6c4Yq5Lx1aJP/Osl94eeROFz9rWKaK734p2pF07UrwntFieq4KxUrZX7CjqBkuELhMxQXqdEQVP4i/KRBP43FxxRw3HUtF QfzwGZLnvuYSzznKMg1csw+T2ra3FIaJ3D12LOUoLYtfzgMvUfLcD370jnyxMNjgDzvqhzh1zbrj/gz56f+ohgnnxP/xebdxi8DvK7plN425j+0HoGRPMu0t /dHj2/sHwpD7dFcw7fM7Tn31WGdiznU72XaXfE8yX0GIarY4erQbIOdIslNaPGofM4gfHWQYf+IdrOlSuwCazk3wdriVdEz65beqVfzaM1lEK7RFbRpLwgPb UxBLbJxk7jwXHrBfmIzUvb3JQVR5hEbsOKUb7Yilys0ap0KwOzFUKVrm0hbQLrfvnoGbJlxnr15WgOiyPKnOvRvAzMtL9g== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org During hot add, vmbus_device_register() is called from vmbus_onoffer(), on the same workqueue as the subchannel offer message work-queue, so subchannel offer won't be processed until the vmbus_device_register()/... /netvsc_probe() is done. Also, vmbus_device_register() is called with channel_mutex locked, which prevents subchannel processing too. So the "waiting for sub-channel processing" will not success in hot add case. But, in usual module loading, the netvsc_probe() is called from different code path, and doesn't fail. This patch resolves the deadlock during NIC hot-add, and speeds up NIC loading time. Signed-off-by: Haiyang Zhang Reviewed-by: K. Y. Srinivasan --- drivers/net/hyperv/rndis_filter.c | 19 +++++++++++++------ 1 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index a37bbda..47d07c5 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -1175,22 +1175,18 @@ int rndis_filter_device_add(struct hv_device *dev, ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn); /* - * Wait for the host to send us the sub-channel offers. + * Set the number of sub-channels to be received. */ spin_lock_irqsave(&net_device->sc_lock, flags); sc_delta = num_rss_qs - (net_device->num_chn - 1); net_device->num_sc_offered -= sc_delta; spin_unlock_irqrestore(&net_device->sc_lock, flags); - while (net_device->num_sc_offered != 0) { - t = wait_for_completion_timeout(&net_device->channel_init_wait, 10*HZ); - if (t == 0) - WARN(1, "Netvsc: Waiting for sub-channel processing"); - } out: if (ret) { net_device->max_chn = 1; net_device->num_chn = 1; + net_device->num_sc_offered = 0; } return 0; /* return 0 because primary channel can be used alone */ @@ -1204,6 +1200,17 @@ void rndis_filter_device_remove(struct hv_device *dev) { struct netvsc_device *net_dev = hv_get_drvdata(dev); struct rndis_device *rndis_dev = net_dev->extension; + unsigned long t; + + /* If not all subchannel offers are complete, wait for them until + * completion to avoid race. + */ + while (net_dev->num_sc_offered > 0) { + t = wait_for_completion_timeout(&net_dev->channel_init_wait, + 10 * HZ); + if (t == 0) + WARN(1, "Netvsc: Waiting for sub-channel processing"); + } /* Halt and release the rndis device */ rndis_filter_halt_device(rndis_dev); -- 1.7.4.1