From patchwork Fri Aug 11 18:39:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Henrique Cerri X-Patchwork-Id: 800723 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical-com.20150623.gappssmtp.com header.i=@canonical-com.20150623.gappssmtp.com header.b="QoAWWK89"; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 3xTYh95sGLz9t2K; Sat, 12 Aug 2017 04:39:37 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1dgEqM-0006I9-KE; Fri, 11 Aug 2017 18:39:34 +0000 Received: from mail-qt0-f172.google.com ([209.85.216.172]) by huckleberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1dgEqE-0006FP-UT for kernel-team@lists.ubuntu.com; Fri, 11 Aug 2017 18:39:27 +0000 Received: by mail-qt0-f172.google.com with SMTP id s6so25926311qtc.1 for ; Fri, 11 Aug 2017 11:39:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=szLe9Mfl2D/K2r48uqxrkT9pIHnRTep8CQgkOdlgrX0=; b=QoAWWK89DYtlPlBN39P4nwqhDvLyaN7M4MnQLRXaH6/JjinT+HcCYHYNv41Izx7vOZ jqNzPJBGqfZspGbhLr3wFtcTRk7vEGJly7JlQ662Rx9IDQ1wrGxVhPh9juC3QVS3dXmn 2+6zy8MZP7AmqRUFOTpgXNij9Zh5HF3DqNtPJ+UwHPcWY7v03TKdavhkedU8NP/S84Ja 9zWyq+II2DPix+twPc4kx05KEpqJn65xfRsqa57bCRYX8183rjzbJljEEKs5CUBSP0rj htV4nM0jA7qMAYdD3AQbkTPo2iX8yZpHYl6kSV1CL6FEwVOssHmj+MnxohcTgmJsL7Xp V2AQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=szLe9Mfl2D/K2r48uqxrkT9pIHnRTep8CQgkOdlgrX0=; b=me7yXHLQeNrw1IL5EBvQDgv0VtHZD97thoVuMZPrkQYqEHSURKlyCT5IYoqklJ2X2K iH1Wu0FbiDflf/5u43tjYWMy/mLXHO2WW2eQi+rpz7nUMiKq+gHNlK0E5GCNNsOLnxSz rnYAG52hQ7c9fNQcafUQ2hKzvqtea4vSL8wyRt8/lK6YLYeKCREMxv/2X7iesDtkQ1u/ Nh8oUiBUBufQXrHR7tdAWtaP4C6v3rSO1SgsNd9+ZzxQPEf0n3czIlzw/X32FNevakUX p4rl8T/kfQyk/bMgh397ychyoSy+6OoDQenvfsP4JsuJq9PkoaSFnJTNmI+ZR2hrVPcx yo3A== X-Gm-Message-State: AHYfb5ibNo0DNDgUBKhibDBf6FnoNFHEM4BI5FJYQKD4RGepHCxe+46d csJ957PRdPHDspsNbdI= X-Received: by 10.237.62.14 with SMTP id l14mr24917954qtf.52.1502476765565; Fri, 11 Aug 2017 11:39:25 -0700 (PDT) Received: from localhost.localdomain ([187.56.59.179]) by smtp.gmail.com with ESMTPSA id b16sm988275qtb.82.2017.08.11.11.39.24 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 11 Aug 2017 11:39:24 -0700 (PDT) From: Marcelo Henrique Cerri To: kernel-team@lists.ubuntu.com Subject: [azure][PATCH] UBUNTU: SAUCE: netvsc: make sure and unregister datapath Date: Fri, 11 Aug 2017 15:39:17 -0300 Message-Id: <1502476757-6554-2-git-send-email-marcelo.cerri@canonical.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1502476757-6554-1-git-send-email-marcelo.cerri@canonical.com> References: <1502476757-6554-1-git-send-email-marcelo.cerri@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: stephen hemminger BugLink: http://bugs.launchpad.net/bugs/1708469 Go back to switching datapath directly in the notifier callback. Otherwise datapath might not get switched on unregister. No need for calling the NOTIFY_PEERS notifier since that is only for a gratitious ARP/ND packet; but that is not required with Hyper-V because both VF and synthetic NIC have the same MAC address. Reported-by: Vitaly Kuznetsov Fixes: 0c195567a8f6 ("netvsc: transparent VF management") Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller (cherry picked from net-next commit 7b83f52047e8a3d551a9495b0267df5d0754c5bf) Signed-off-by: Marcelo Henrique Cerri --- drivers/net/hyperv/hyperv_net.h | 3 -- drivers/net/hyperv/netvsc.c | 2 -- drivers/net/hyperv/netvsc_drv.c | 71 ++++++++++++++++------------------------- 3 files changed, 28 insertions(+), 48 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index b252aa384fa0..cc8951f50df3 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -728,14 +728,11 @@ struct net_device_context { struct net_device __rcu *vf_netdev; struct netvsc_vf_pcpu_stats __percpu *vf_stats; struct work_struct vf_takeover; - struct work_struct vf_notify; /* 1: allocated, serial number is valid. 0: not allocated */ u32 vf_alloc; /* Serial number of the VF to team with */ u32 vf_serial; - - bool datapath; /* 0 - synthetic, 1 - VF nic */ }; /* Per channel data */ diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index ca7d07f8e4f1..795f9afe3381 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -60,8 +60,6 @@ void netvsc_switch_datapath(struct net_device *ndev, bool vf) sizeof(struct nvsp_message), (unsigned long)init_pkt, VM_PKT_DATA_INBAND, 0); - - net_device_ctx->datapath = vf; } static struct netvsc_device *alloc_net_device(void) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index cd755d8ee67b..1ebb34c38273 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -1671,55 +1671,35 @@ static int netvsc_register_vf(struct net_device *vf_netdev) return NOTIFY_OK; } -/* Change datapath */ -static void netvsc_vf_update(struct work_struct *w) +static int netvsc_vf_up(struct net_device *vf_netdev) { - struct net_device_context *ndev_ctx - = container_of(w, struct net_device_context, vf_notify); - struct net_device *ndev = hv_get_drvdata(ndev_ctx->device_ctx); + struct net_device_context *net_device_ctx; struct netvsc_device *netvsc_dev; - struct net_device *vf_netdev; - bool vf_is_up; - - if (!rtnl_trylock()) { - schedule_work(w); - return; - } + struct net_device *ndev; - vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev); - if (!vf_netdev) - goto unlock; + ndev = get_netvsc_byref(vf_netdev); + if (!ndev) + return NOTIFY_DONE; - netvsc_dev = rtnl_dereference(ndev_ctx->nvdev); + net_device_ctx = netdev_priv(ndev); + netvsc_dev = rtnl_dereference(net_device_ctx->nvdev); if (!netvsc_dev) - goto unlock; - - vf_is_up = netif_running(vf_netdev); - if (vf_is_up != ndev_ctx->datapath) { - if (vf_is_up) { - netdev_info(ndev, "VF up: %s\n", vf_netdev->name); - rndis_filter_open(netvsc_dev); - netvsc_switch_datapath(ndev, true); - netdev_info(ndev, "Data path switched to VF: %s\n", - vf_netdev->name); - } else { - netdev_info(ndev, "VF down: %s\n", vf_netdev->name); - netvsc_switch_datapath(ndev, false); - rndis_filter_close(netvsc_dev); - netdev_info(ndev, "Data path switched from VF: %s\n", - vf_netdev->name); - } + return NOTIFY_DONE; - /* Now notify peers through VF device. */ - call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, ndev); - } -unlock: - rtnl_unlock(); + /* Bump refcount when datapath is acvive - Why? */ + rndis_filter_open(netvsc_dev); + + /* notify the host to switch the data path. */ + netvsc_switch_datapath(ndev, true); + netdev_info(ndev, "Data path switched to VF: %s\n", vf_netdev->name); + + return NOTIFY_OK; } -static int netvsc_vf_notify(struct net_device *vf_netdev) +static int netvsc_vf_down(struct net_device *vf_netdev) { struct net_device_context *net_device_ctx; + struct netvsc_device *netvsc_dev; struct net_device *ndev; ndev = get_netvsc_byref(vf_netdev); @@ -1727,7 +1707,13 @@ static int netvsc_vf_notify(struct net_device *vf_netdev) return NOTIFY_DONE; net_device_ctx = netdev_priv(ndev); - schedule_work(&net_device_ctx->vf_notify); + netvsc_dev = rtnl_dereference(net_device_ctx->nvdev); + if (!netvsc_dev) + return NOTIFY_DONE; + + netvsc_switch_datapath(ndev, false); + netdev_info(ndev, "Data path switched from VF: %s\n", vf_netdev->name); + rndis_filter_close(netvsc_dev); return NOTIFY_OK; } @@ -1743,7 +1729,6 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev) net_device_ctx = netdev_priv(ndev); cancel_work_sync(&net_device_ctx->vf_takeover); - cancel_work_sync(&net_device_ctx->vf_notify); netdev_info(ndev, "VF unregistering: %s\n", vf_netdev->name); @@ -1786,7 +1771,6 @@ static int netvsc_probe(struct hv_device *dev, spin_lock_init(&net_device_ctx->lock); INIT_LIST_HEAD(&net_device_ctx->reconfig_events); INIT_WORK(&net_device_ctx->vf_takeover, netvsc_vf_setup); - INIT_WORK(&net_device_ctx->vf_notify, netvsc_vf_update); net_device_ctx->vf_stats = netdev_alloc_pcpu_stats(struct netvsc_vf_pcpu_stats); @@ -1939,8 +1923,9 @@ static int netvsc_netdev_event(struct notifier_block *this, case NETDEV_UNREGISTER: return netvsc_unregister_vf(event_dev); case NETDEV_UP: + return netvsc_vf_up(event_dev); case NETDEV_DOWN: - return netvsc_vf_notify(event_dev); + return netvsc_vf_down(event_dev); default: return NOTIFY_DONE; }