Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/2224247/?format=api
{ "id": 2224247, "url": "http://patchwork.ozlabs.org/api/1.2/patches/2224247/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20260417072828.3887753-1-vinschen@redhat.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/1.2/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260417072828.3887753-1-vinschen@redhat.com>", "list_archive_url": null, "date": "2026-04-17T07:28:28", "name": "[net,v2] ixgbe: only access vfinfo and mv_list under RCU lock", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "eea6d785533bcf85e6133e046a74d2cc0d64df49", "submitter": { "id": 7921, "url": "http://patchwork.ozlabs.org/api/1.2/people/7921/?format=api", "name": "Corinna Vinschen", "email": "vinschen@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20260417072828.3887753-1-vinschen@redhat.com/mbox/", "series": [ { "id": 500250, "url": "http://patchwork.ozlabs.org/api/1.2/series/500250/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=500250", "date": "2026-04-17T07:28:28", "name": "[net,v2] ixgbe: only access vfinfo and mv_list under RCU lock", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/500250/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2224247/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2224247/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=osuosl.org header.i=@osuosl.org header.a=rsa-sha256\n header.s=default header.b=MvNIMRj8;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=osuosl.org\n (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org;\n envelope-from=intel-wired-lan-bounces@osuosl.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fxmhd3FvSz1yGt\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 17 Apr 2026 17:28:47 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id 36FC560BF7;\n\tFri, 17 Apr 2026 07:28:45 +0000 (UTC)", "from smtp3.osuosl.org ([127.0.0.1])\n by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id 0rPf3fbZtfsD; Fri, 17 Apr 2026 07:28:43 +0000 (UTC)", "from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142])\n\tby smtp3.osuosl.org (Postfix) with ESMTP id DD82E60C19;\n\tFri, 17 Apr 2026 07:28:42 +0000 (UTC)", "from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138])\n by lists1.osuosl.org (Postfix) with ESMTP id 9A825270\n for <intel-wired-lan@lists.osuosl.org>; Fri, 17 Apr 2026 07:28:41 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n by smtp1.osuosl.org (Postfix) with ESMTP id 802D581370\n for <intel-wired-lan@lists.osuosl.org>; Fri, 17 Apr 2026 07:28:41 +0000 (UTC)", "from smtp1.osuosl.org ([127.0.0.1])\n by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id fFF7X2VOKv89 for <intel-wired-lan@lists.osuosl.org>;\n Fri, 17 Apr 2026 07:28:39 +0000 (UTC)", "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by smtp1.osuosl.org (Postfix) with ESMTPS id 0F3FD81371\n for <intel-wired-lan@lists.osuosl.org>; Fri, 17 Apr 2026 07:28:38 +0000 (UTC)", "from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-653-Ub0hwcvKOvS83yiZJ461_A-1; Fri,\n 17 Apr 2026 03:28:32 -0400", "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 043F91956065; Fri, 17 Apr 2026 07:28:32 +0000 (UTC)", "from calimero.vinschen.de (unknown [10.44.32.30])\n by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with\n ESMTPS\n id 11E77195608E; Fri, 17 Apr 2026 07:28:30 +0000 (UTC)", "by calimero.vinschen.de (Postfix, from userid 500)\n id 60F6EA80BB2; Fri, 17 Apr 2026 09:28:28 +0200 (CEST)" ], "X-Virus-Scanned": [ "amavis at osuosl.org", "amavis at osuosl.org" ], "X-Comment": "SPF check N/A for local connections - client-ip=140.211.166.142;\n helo=lists1.osuosl.org; envelope-from=intel-wired-lan-bounces@osuosl.org;\n receiver=<UNKNOWN> ", "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 smtp3.osuosl.org DD82E60C19", "OpenDKIM Filter v2.11.0 smtp1.osuosl.org 0F3FD81371" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=osuosl.org;\n\ts=default; t=1776410922;\n\tbh=UH64DPASRw8jk/QcHcjADgonOznMzsmIz5Hin1gOnmw=;\n\th=From:To:Cc:Date:In-Reply-To:References:Subject:List-Id:\n\t List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe:\n\t From;\n\tb=MvNIMRj8WYuAistFg7Dhqe3Cew8tGq7fB48Vh/u7TDcVEdib76wNzvyTm18fCwzqP\n\t Ff6jUqEcs67Q81PoywX3JC/GwwhfdBQ14wa9su/hZdtWPi+DIAS12oTGsq3ti9AKBl\n\t elkLeMg4ultJucMYmyoBX8Yg77EfAYde9YNWis3NT1iIbfA58fzav9CwhiAKrhbCRu\n\t R/zEdPKNlIqIj7BFaQ1C15EFWjoEeYzLyII3ZUI9zthSGOZQ6mGPWEGDPiL8bdGQg7\n\t sEwEWKsI8Gxz+AhX/pWh/LJkQyF16obDBP4ib8ffjBlEhFlFR61bUT/RCPy3jQcu+V\n\t v06Ow7f4omipw==", "Received-SPF": "Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124;\n helo=us-smtp-delivery-124.mimecast.com; envelope-from=vinschen@redhat.com;\n receiver=<UNKNOWN>", "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp1.osuosl.org 0F3FD81371", "X-MC-Unique": "Ub0hwcvKOvS83yiZJ461_A-1", "X-Mimecast-MFC-AGG-ID": "Ub0hwcvKOvS83yiZJ461_A_1776410912", "From": "Corinna Vinschen <vinschen@redhat.com>", "To": "intel-wired-lan@lists.osuosl.org,\n\tnetdev@vger.kernel.org", "Cc": "Corinna Vinschen <vinschen@redhat.com>", "Date": "Fri, 17 Apr 2026 09:28:28 +0200", "Message-ID": "<20260417072828.3887753-1-vinschen@redhat.com>", "In-Reply-To": "<20260416084227.3787828-1-vinschen@redhat.com>", "References": "<20260416084227.3787828-1-vinschen@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17", "X-Mimecast-MFC-PROC-ID": "bq5MfFsEyyOw_BdEaeWT7uGZW21rq9TmAVCrFFkYtAQ_1776410912", "X-Mimecast-Originator": "redhat.com", "Content-Transfer-Encoding": "8bit", "content-type": "text/plain; charset=\"US-ASCII\"; x-default=true", "X-Mailman-Original-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=redhat.com;\n s=mimecast20190719; t=1776410917;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=UH64DPASRw8jk/QcHcjADgonOznMzsmIz5Hin1gOnmw=;\n b=YRtxm2ikTsHU2TZHDsbAp2rgSkfwNF0xQRShkxdV+9TSXKSD2yelvz6uqzwSu5WfWBYdz5\n 5bxz7FHT2SM+ajwJ1Ar0tMFnWHCGpRwjRFpVH54U3KVW/QgO3TEn6UIoA9CyhJLc5kcJ1b\n 5NKrhomb1pbCAgT4cSvDTrwz7ytJ9pA=", "X-Mailman-Original-Authentication-Results": [ "smtp1.osuosl.org;\n dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com", "smtp1.osuosl.org;\n dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com\n header.a=rsa-sha256 header.s=mimecast20190719 header.b=YRtxm2ik" ], "Subject": "[Intel-wired-lan] [PATCH net v2] ixgbe: only access vfinfo and\n mv_list under RCU lock", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n <intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>,\n <mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>,\n <mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "Commit 1e53834ce541d (\"ixgbe: Add locking to prevent panic when setting\nsriov_numvfs to zero\") added a spinlock to the adapter info. The reason\nat the time was an observed crash when ixgbe_disable_sriov() freed the\nadapter->vfinfo array while the interrupt driven function ixgbe_msg_task()\nwas handling VF messages.\n\nRecent stability testing turned up another crash, which is very easily\nreproducible:\n\n while true\n do\n for numvfs in 5 0\n do\n echo $numvfs > /sys/class/net/eth0/device/sriov_numvfs\n done\n done\n\nThis crashed almost always within the first two hundred runs with\na NULL pointer deref while running the ixgbe_service_task() workqueue:\n\n[ 5052.036491] BUG: kernel NULL pointer dereference, address: 0000000000000258\n[ 5052.043454] #PF: supervisor read access in kernel mode\n[ 5052.048594] #PF: error_code(0x0000) - not-present page\n[ 5052.053734] PGD 0 P4D 0\n[ 5052.056272] Oops: Oops: 0000 #1 SMP NOPTI\n[ 5052.060459] CPU: 2 UID: 0 PID: 132253 Comm: kworker/u96:0 Kdump: loaded Not tainted 6.12.0-180.el10.x86_64 #1 PREEMPT(voluntary)\n[ 5052.072100] Hardware name: Dell Inc. PowerEdge R740/0DY2X0, BIOS 2.12.2 07/09/2021\n[ 5052.079664] Workqueue: ixgbe ixgbe_service_task [ixgbe]\n[ 5052.084907] RIP: 0010:ixgbe_update_stats+0x8b1/0xb40 [ixgbe]\n[ 5052.090585] Code: 21 56 50 49 8b b6 18 26 00 00 4c 01 fe 48 09 46 50 42 8d 34 a5 00 83 00 00 e8 cb 7a ff ff 49 8b b6 18 26 00 00 89 c0 4c 01 fe <48> 3b 86 88 00 00 00 73 18 48 b9 00 00 00 00 01 00 00 00 48 01 4e\n[ 5052.109331] RSP: 0018:ffffd5f1e8a6bd88 EFLAGS: 00010202\n[ 5052.114558] RAX: 0000000000000000 RBX: ffff8f49b22b14a0 RCX: 000000000000023c\n[ 5052.121689] RDX: ffffffff00000000 RSI: 00000000000001d0 RDI: ffff8f49b22b14a0\n[ 5052.128823] RBP: 000000000000109c R08: 0000000000000000 R09: 0000000000000000\n[ 5052.135955] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000002\n[ 5052.143086] R13: 0000000000008410 R14: ffff8f49b22b01a0 R15: 00000000000001d0\n[ 5052.150221] FS: 0000000000000000(0000) GS:ffff8f58bfc80000(0000) knlGS:0000000000000000\n[ 5052.158307] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033\n[ 5052.164054] CR2: 0000000000000258 CR3: 0000000bf2624006 CR4: 00000000007726f0\n[ 5052.171187] PKRU: 55555554\n[ 5052.173898] Call Trace:\n[ 5052.176351] <TASK>\n[ 5052.178457] ? show_trace_log_lvl+0x1b0/0x2f0\n[ 5052.182816] ? show_trace_log_lvl+0x1b0/0x2f0\n[ 5052.187177] ? ixgbe_watchdog_subtask+0x1a1/0x230 [ixgbe]\n[ 5052.192591] ? __die_body.cold+0x8/0x12\n[ 5052.196433] ? page_fault_oops+0x148/0x160\n[ 5052.200532] ? exc_page_fault+0x7f/0x150\n[ 5052.204458] ? asm_exc_page_fault+0x26/0x30\n[ 5052.208643] ? ixgbe_update_stats+0x8b1/0xb40 [ixgbe]\n[ 5052.213714] ? ixgbe_update_stats+0x8a5/0xb40 [ixgbe]\n[ 5052.218784] ixgbe_watchdog_subtask+0x1a1/0x230 [ixgbe]\n[ 5052.224026] ixgbe_service_task+0x15a/0x3f0 [ixgbe]\n[ 5052.228916] process_one_work+0x177/0x330\n[ 5052.232928] worker_thread+0x256/0x3a0\n[ 5052.236681] ? __pfx_worker_thread+0x10/0x10\n[ 5052.240952] kthread+0xfa/0x240\n[ 5052.244099] ? __pfx_kthread+0x10/0x10\n[ 5052.247852] ret_from_fork+0x34/0x50\n[ 5052.251429] ? __pfx_kthread+0x10/0x10\n[ 5052.255185] ret_from_fork_asm+0x1a/0x30\n[ 5052.259112] </TASK>\n\nThe first simple patch, just adding spinlocking to ixgbe_update_stats()\nwhile reading from adapter->vfinfo, did not fix the problem, it just\nmoved it elsewhere: I could now reproduce the same kind of crash in\nixgbe_restore_vf_multicasts().\n\nBut adding more spinlocking doesn't really cut it. One reason is that\nixgbe_restore_vf_multicasts() is called from within ixgbe_msg_task()\nwith active spinlock, as well as from outside without locking.\n\nAdditionally, given that ixgbe_disable_sriov() is the only call changing\nadapter->vfinfo, and given ixgbe_disable_sriov() is called very\nseldom compared to other actions in the driver, just adding more\nspinlocks would unnecessarily occupy the driver with spinning when\nmultiple functions accessing adapter->vfinfo are running in parallel.\n\nSo this patch drops the spinlock in favor of RCU and uses it throughout\nthe driver.\n\nWhile changing this, it seems prudent to do the same for the\nadapter->mv_list array, which is allocated and freed at the same time as\nadapter->vfinfo, albeit there was no crash observed.\n\nFixes: 1e53834ce541d (\"ixgbe: Add locking to prevent panic when setting sriov_numvfs to zero\")\nSigned-off-by: Corinna Vinschen <vinschen@redhat.com>\n---\nv2: always return 0 from ixgbe_ndo_get_vf_stats so as not to break\n 'ip link show dev'\n\nInterdiff against v1:\n diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n index 6ee8c2a140c2..e0a986f1c96a 100644\n --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n @@ -9797,7 +9797,7 @@ static int ixgbe_ndo_get_vf_stats(struct net_device *netdev, int vf,\n \t}\n \trcu_read_unlock();\n \n -\treturn vfinfo ? 0 : -EINVAL;\n +\treturn 0;\n }\n \n #ifdef CONFIG_IXGBE_DCB\n\n drivers/net/ethernet/intel/ixgbe/ixgbe.h | 7 +-\n .../net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c | 36 +-\n .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 44 +-\n .../net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 17 +-\n drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 227 +++++---\n .../net/ethernet/intel/ixgbe/ixgbe_sriov.c | 547 ++++++++++++------\n 6 files changed, 592 insertions(+), 286 deletions(-)", "diff": "diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h\nindex 9b8217523fd2..8849b9f42bf6 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h\n@@ -210,6 +210,7 @@ struct vf_stats {\n };\n \n struct vf_data_storage {\n+\tstruct rcu_head rcu_head;\n \tstruct pci_dev *vfdev;\n \tunsigned char vf_mac_addresses[ETH_ALEN];\n \tu16 vf_mc_hashes[IXGBE_MAX_VF_MC_ENTRIES];\n@@ -240,6 +241,7 @@ enum ixgbevf_xcast_modes {\n };\n \n struct vf_macvlans {\n+\tstruct rcu_head rcu_head;\n \tstruct list_head l;\n \tint vf;\n \tbool free;\n@@ -808,10 +810,10 @@ struct ixgbe_adapter {\n \t/* SR-IOV */\n \tDECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS);\n \tunsigned int num_vfs;\n-\tstruct vf_data_storage *vfinfo;\n+\tstruct vf_data_storage __rcu *vfinfo;\n \tint vf_rate_link_speed;\n \tstruct vf_macvlans vf_mvs;\n-\tstruct vf_macvlans *mv_list;\n+\tstruct vf_macvlans __rcu *mv_list;\n \n \tu32 timer_event_accumulator;\n \tu32 vferr_refcount;\n@@ -844,7 +846,6 @@ struct ixgbe_adapter {\n #ifdef CONFIG_IXGBE_IPSEC\n \tstruct ixgbe_ipsec *ipsec;\n #endif /* CONFIG_IXGBE_IPSEC */\n-\tspinlock_t vfs_lock;\n };\n \n struct ixgbe_netdevice_priv {\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c\nindex 382d097e4b11..9a84cfc09120 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c\n@@ -640,17 +640,21 @@ static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,\n \t/* VF devices should use default UP when available */\n \tif (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&\n \t app->protocol == 0) {\n+\t\tstruct vf_data_storage *vfinfo;\n \t\tint vf;\n \n \t\tadapter->default_up = app->priority;\n \n-\t\tfor (vf = 0; vf < adapter->num_vfs; vf++) {\n-\t\t\tstruct vf_data_storage *vfinfo = &adapter->vfinfo[vf];\n-\n-\t\t\tif (!vfinfo->pf_qos)\n-\t\t\t\tixgbe_set_vmvir(adapter, vfinfo->pf_vlan,\n-\t\t\t\t\t\tapp->priority, vf);\n-\t\t}\n+\t\trcu_read_lock();\n+\t\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\t\tif (vfinfo)\n+\t\t\tfor (vf = 0; vf < adapter->num_vfs; vf++) {\n+\t\t\t\tif (!vfinfo[vf].pf_qos)\n+\t\t\t\t\tixgbe_set_vmvir(adapter,\n+\t\t\t\t\t\t\tvfinfo[vf].pf_vlan,\n+\t\t\t\t\t\t\tapp->priority, vf);\n+\t\t\t}\n+\t\trcu_read_unlock();\n \t}\n \n \treturn 0;\n@@ -683,19 +687,23 @@ static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev,\n \t/* IF default priority is being removed clear VF default UP */\n \tif (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&\n \t app->protocol == 0 && adapter->default_up == app->priority) {\n+\t\tstruct vf_data_storage *vfinfo;\n \t\tint vf;\n \t\tlong unsigned int app_mask = dcb_ieee_getapp_mask(dev, app);\n \t\tint qos = app_mask ? find_first_bit(&app_mask, 8) : 0;\n \n \t\tadapter->default_up = qos;\n \n-\t\tfor (vf = 0; vf < adapter->num_vfs; vf++) {\n-\t\t\tstruct vf_data_storage *vfinfo = &adapter->vfinfo[vf];\n-\n-\t\t\tif (!vfinfo->pf_qos)\n-\t\t\t\tixgbe_set_vmvir(adapter, vfinfo->pf_vlan,\n-\t\t\t\t\t\tqos, vf);\n-\t\t}\n+\t\trcu_read_lock();\n+\t\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\t\tif (vfinfo)\n+\t\t\tfor (vf = 0; vf < adapter->num_vfs; vf++) {\n+\t\t\t\tif (!vfinfo[vf].pf_qos)\n+\t\t\t\t\tixgbe_set_vmvir(adapter,\n+\t\t\t\t\t\t\tvfinfo[vf].pf_vlan,\n+\t\t\t\t\t\t\tqos, vf);\n+\t\t\t}\n+\t\trcu_read_unlock();\n \t}\n \n \treturn err;\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c\nindex ba049b3a9609..b77317476af4 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c\n@@ -2265,21 +2265,28 @@ static void ixgbe_diag_test(struct net_device *netdev,\n \t\tstruct ixgbe_hw *hw = &adapter->hw;\n \n \t\tif (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {\n+\t\t\tstruct vf_data_storage *vfinfo;\n \t\t\tint i;\n-\t\t\tfor (i = 0; i < adapter->num_vfs; i++) {\n-\t\t\t\tif (adapter->vfinfo[i].clear_to_send) {\n-\t\t\t\t\tnetdev_warn(netdev, \"offline diagnostic is not supported when VFs are present\\n\");\n-\t\t\t\t\tdata[0] = 1;\n-\t\t\t\t\tdata[1] = 1;\n-\t\t\t\t\tdata[2] = 1;\n-\t\t\t\t\tdata[3] = 1;\n-\t\t\t\t\tdata[4] = 1;\n-\t\t\t\t\teth_test->flags |= ETH_TEST_FL_FAILED;\n-\t\t\t\t\tclear_bit(__IXGBE_TESTING,\n-\t\t\t\t\t\t &adapter->state);\n-\t\t\t\t\treturn;\n+\n+\t\t\trcu_read_lock();\n+\t\t\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\t\t\tif (vfinfo)\n+\t\t\t\tfor (i = 0; i < adapter->num_vfs; i++) {\n+\t\t\t\t\tif (vfinfo[i].clear_to_send) {\n+\t\t\t\t\t\tnetdev_warn(netdev, \"offline diagnostic is not supported when VFs are present\\n\");\n+\t\t\t\t\t\tdata[0] = 1;\n+\t\t\t\t\t\tdata[1] = 1;\n+\t\t\t\t\t\tdata[2] = 1;\n+\t\t\t\t\t\tdata[3] = 1;\n+\t\t\t\t\t\tdata[4] = 1;\n+\t\t\t\t\t\teth_test->flags |= ETH_TEST_FL_FAILED;\n+\t\t\t\t\t\tclear_bit(__IXGBE_TESTING,\n+\t\t\t\t\t\t\t &adapter->state);\n+\t\t\t\t\t\trcu_read_unlock();\n+\t\t\t\t\t\treturn;\n+\t\t\t\t\t}\n \t\t\t\t}\n-\t\t\t}\n+\t\t\trcu_read_unlock();\n \t\t}\n \n \t\t/* Offline tests */\n@@ -3700,9 +3707,14 @@ static int ixgbe_set_priv_flags(struct net_device *netdev, u32 priv_flags)\n \tif (priv_flags & IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF) {\n \t\tif (adapter->hw.mac.type == ixgbe_mac_82599EB) {\n \t\t\t/* Reset primary abort counter */\n-\t\t\tfor (i = 0; i < adapter->num_vfs; i++)\n-\t\t\t\tadapter->vfinfo[i].primary_abort_count = 0;\n-\n+\t\t\tstruct vf_data_storage *vfinfo;\n+\n+\t\t\trcu_read_lock();\n+\t\t\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\t\t\tif (vfinfo)\n+\t\t\t\tfor (i = 0; i < adapter->num_vfs; i++)\n+\t\t\t\t\tvfinfo[i].primary_abort_count = 0;\n+\t\t\trcu_read_unlock();\n \t\t\tflags2 |= IXGBE_FLAG2_AUTO_DISABLE_VF;\n \t\t} else {\n \t\t\te_info(probe,\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c\nindex bd397b3d7dea..b524a3a61eb6 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c\n@@ -874,6 +874,7 @@ void ixgbe_ipsec_vf_clear(struct ixgbe_adapter *adapter, u32 vf)\n int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)\n {\n \tstruct ixgbe_ipsec *ipsec = adapter->ipsec;\n+\tstruct vf_data_storage *vfinfo;\n \tstruct xfrm_algo_desc *algo;\n \tstruct sa_mbx_msg *sam;\n \tstruct xfrm_state *xs;\n@@ -883,7 +884,13 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)\n \tint err;\n \n \tsam = (struct sa_mbx_msg *)(&msgbuf[1]);\n-\tif (!adapter->vfinfo[vf].trusted ||\n+\n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n+\tif (!vfinfo[vf].trusted ||\n \t !(adapter->flags2 & IXGBE_FLAG2_VF_IPSEC_ENABLED)) {\n \t\te_warn(drv, \"VF %d attempted to add an IPsec SA\\n\", vf);\n \t\terr = -EACCES;\n@@ -984,11 +991,17 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)\n int ixgbe_ipsec_vf_del_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)\n {\n \tstruct ixgbe_ipsec *ipsec = adapter->ipsec;\n+\tstruct vf_data_storage *vfinfo;\n \tstruct xfrm_state *xs;\n \tu32 pfsa = msgbuf[1];\n \tu16 sa_idx;\n \n-\tif (!adapter->vfinfo[vf].trusted) {\n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n+\tif (!vfinfo[vf].trusted) {\n \t\te_err(drv, \"vf %d attempted to delete an SA\\n\", vf);\n \t\treturn -EPERM;\n \t}\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\nindex 2646ee6f295f..e0a986f1c96a 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n@@ -1240,20 +1240,26 @@ static void ixgbe_pf_handle_tx_hang(struct ixgbe_ring *tx_ring,\n static void ixgbe_vf_handle_tx_hang(struct ixgbe_adapter *adapter, u16 vf)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct vf_data_storage *vfinfo;\n \n \tif (adapter->hw.mac.type != ixgbe_mac_e610)\n \t\treturn;\n \n-\te_warn(drv,\n-\t \"Malicious Driver Detection tx hang detected on PF %d VF %d MAC: %pM\",\n-\t hw->bus.func, vf, adapter->vfinfo[vf].vf_mac_addresses);\n-\n-\tadapter->tx_hang_count[vf]++;\n-\tif (adapter->tx_hang_count[vf] == IXGBE_MAX_TX_VF_HANGS) {\n-\t\tixgbe_set_vf_link_state(adapter, vf,\n-\t\t\t\t\tIFLA_VF_LINK_STATE_DISABLE);\n-\t\tadapter->tx_hang_count[vf] = 0;\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo) {\n+\t\te_warn(drv,\n+\t\t \"Malicious Driver Detection tx hang detected on PF %d VF %d MAC: %pM\",\n+\t\t hw->bus.func, vf, vfinfo[vf].vf_mac_addresses);\n+\n+\t\tadapter->tx_hang_count[vf]++;\n+\t\tif (adapter->tx_hang_count[vf] == IXGBE_MAX_TX_VF_HANGS) {\n+\t\t\tixgbe_set_vf_link_state(adapter, vf,\n+\t\t\t\t\t\tIFLA_VF_LINK_STATE_DISABLE);\n+\t\t\tadapter->tx_hang_count[vf] = 0;\n+\t\t}\n \t}\n+\trcu_read_unlock();\n }\n \n static u32 ixgbe_poll_tx_icache(struct ixgbe_hw *hw, u16 queue, u16 idx)\n@@ -4625,6 +4631,7 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)\n \tstruct ixgbe_hw *hw = &adapter->hw;\n \tu16 pool = adapter->num_rx_pools;\n \tu32 reg_offset, vf_shift, vmolr;\n+\tstruct vf_data_storage *vfinfo;\n \tu32 gcr_ext, vmdctl;\n \tint i;\n \n@@ -4680,15 +4687,19 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)\n \n \tIXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);\n \n-\tfor (i = 0; i < adapter->num_vfs; i++) {\n-\t\t/* configure spoof checking */\n-\t\tixgbe_ndo_set_vf_spoofchk(adapter->netdev, i,\n-\t\t\t\t\t adapter->vfinfo[i].spoofchk_enabled);\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo)\n+\t\tfor (i = 0; i < adapter->num_vfs; i++) {\n+\t\t\t/* configure spoof checking */\n+\t\t\tixgbe_ndo_set_vf_spoofchk(adapter->netdev, i,\n+\t\t\t\t\t\t vfinfo[i].spoofchk_enabled);\n \n-\t\t/* Enable/Disable RSS query feature */\n-\t\tixgbe_ndo_set_vf_rss_query_en(adapter->netdev, i,\n-\t\t\t\t\t adapter->vfinfo[i].rss_query_enabled);\n-\t}\n+\t\t\t/* Enable/Disable RSS query feature */\n+\t\t\tixgbe_ndo_set_vf_rss_query_en(adapter->netdev, i,\n+\t\t\t\t\t\t vfinfo[i].rss_query_enabled);\n+\t\t}\n+\trcu_read_unlock();\n }\n \n static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter)\n@@ -6093,35 +6104,40 @@ static void ixgbe_check_media_subtask(struct ixgbe_adapter *adapter)\n static void ixgbe_clear_vf_stats_counters(struct ixgbe_adapter *adapter)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct vf_data_storage *vfinfo;\n \tint i;\n \n-\tfor (i = 0; i < adapter->num_vfs; i++) {\n-\t\tadapter->vfinfo[i].last_vfstats.gprc =\n-\t\t\tIXGBE_READ_REG(hw, IXGBE_PVFGPRC(i));\n-\t\tadapter->vfinfo[i].saved_rst_vfstats.gprc +=\n-\t\t\tadapter->vfinfo[i].vfstats.gprc;\n-\t\tadapter->vfinfo[i].vfstats.gprc = 0;\n-\t\tadapter->vfinfo[i].last_vfstats.gptc =\n-\t\t\tIXGBE_READ_REG(hw, IXGBE_PVFGPTC(i));\n-\t\tadapter->vfinfo[i].saved_rst_vfstats.gptc +=\n-\t\t\tadapter->vfinfo[i].vfstats.gptc;\n-\t\tadapter->vfinfo[i].vfstats.gptc = 0;\n-\t\tadapter->vfinfo[i].last_vfstats.gorc =\n-\t\t\tIXGBE_READ_REG(hw, IXGBE_PVFGORC_LSB(i));\n-\t\tadapter->vfinfo[i].saved_rst_vfstats.gorc +=\n-\t\t\tadapter->vfinfo[i].vfstats.gorc;\n-\t\tadapter->vfinfo[i].vfstats.gorc = 0;\n-\t\tadapter->vfinfo[i].last_vfstats.gotc =\n-\t\t\tIXGBE_READ_REG(hw, IXGBE_PVFGOTC_LSB(i));\n-\t\tadapter->vfinfo[i].saved_rst_vfstats.gotc +=\n-\t\t\tadapter->vfinfo[i].vfstats.gotc;\n-\t\tadapter->vfinfo[i].vfstats.gotc = 0;\n-\t\tadapter->vfinfo[i].last_vfstats.mprc =\n-\t\t\tIXGBE_READ_REG(hw, IXGBE_PVFMPRC(i));\n-\t\tadapter->vfinfo[i].saved_rst_vfstats.mprc +=\n-\t\t\tadapter->vfinfo[i].vfstats.mprc;\n-\t\tadapter->vfinfo[i].vfstats.mprc = 0;\n-\t}\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo)\n+\t\tfor (i = 0; i < adapter->num_vfs; i++) {\n+\t\t\tvfinfo[i].last_vfstats.gprc =\n+\t\t\t\tIXGBE_READ_REG(hw, IXGBE_PVFGPRC(i));\n+\t\t\tvfinfo[i].saved_rst_vfstats.gprc +=\n+\t\t\t\tvfinfo[i].vfstats.gprc;\n+\t\t\tvfinfo[i].vfstats.gprc = 0;\n+\t\t\tvfinfo[i].last_vfstats.gptc =\n+\t\t\t\tIXGBE_READ_REG(hw, IXGBE_PVFGPTC(i));\n+\t\t\tvfinfo[i].saved_rst_vfstats.gptc +=\n+\t\t\t\tvfinfo[i].vfstats.gptc;\n+\t\t\tvfinfo[i].vfstats.gptc = 0;\n+\t\t\tvfinfo[i].last_vfstats.gorc =\n+\t\t\t\tIXGBE_READ_REG(hw, IXGBE_PVFGORC_LSB(i));\n+\t\t\tvfinfo[i].saved_rst_vfstats.gorc +=\n+\t\t\t\tvfinfo[i].vfstats.gorc;\n+\t\t\tvfinfo[i].vfstats.gorc = 0;\n+\t\t\tvfinfo[i].last_vfstats.gotc =\n+\t\t\t\tIXGBE_READ_REG(hw, IXGBE_PVFGOTC_LSB(i));\n+\t\t\tvfinfo[i].saved_rst_vfstats.gotc +=\n+\t\t\t\tvfinfo[i].vfstats.gotc;\n+\t\t\tvfinfo[i].vfstats.gotc = 0;\n+\t\t\tvfinfo[i].last_vfstats.mprc =\n+\t\t\t\tIXGBE_READ_REG(hw, IXGBE_PVFMPRC(i));\n+\t\t\tvfinfo[i].saved_rst_vfstats.mprc +=\n+\t\t\t\tvfinfo[i].vfstats.mprc;\n+\t\t\tvfinfo[i].vfstats.mprc = 0;\n+\t\t}\n+\trcu_read_unlock();\n }\n \n static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter)\n@@ -6729,15 +6745,22 @@ void ixgbe_down(struct ixgbe_adapter *adapter)\n \ttimer_delete_sync(&adapter->service_timer);\n \n \tif (adapter->num_vfs) {\n+\t\tstruct vf_data_storage *vfinfo;\n+\n \t\t/* Clear EITR Select mapping */\n \t\tIXGBE_WRITE_REG(&adapter->hw, IXGBE_EITRSEL, 0);\n \n+\t\trcu_read_lock();\n+\t\tvfinfo = rcu_dereference(adapter->vfinfo);\n \t\t/* Mark all the VFs as inactive */\n-\t\tfor (i = 0 ; i < adapter->num_vfs; i++)\n-\t\t\tadapter->vfinfo[i].clear_to_send = false;\n+\t\tif (vfinfo) {\n+\t\t\tfor (i = 0 ; i < adapter->num_vfs; i++)\n+\t\t\t\tvfinfo[i].clear_to_send = false;\n \n-\t\t/* update setting rx tx for all active vfs */\n-\t\tixgbe_set_all_vfs(adapter);\n+\t\t\t/* update setting rx tx for all active vfs */\n+\t\t\tixgbe_set_all_vfs(adapter);\n+\t\t}\n+\t\trcu_read_unlock();\n \t}\n \n \t/* disable transmits in the hardware now that interrupts are off */\n@@ -7001,9 +7024,6 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,\n \t/* n-tuple support exists, always init our spinlock */\n \tspin_lock_init(&adapter->fdir_perfect_lock);\n \n-\t/* init spinlock to avoid concurrency of VF resources */\n-\tspin_lock_init(&adapter->vfs_lock);\n-\n #ifdef CONFIG_IXGBE_DCB\n \tixgbe_init_dcb(adapter);\n #endif\n@@ -7905,25 +7925,31 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)\n \t * crazy values.\n \t */\n \tif (!test_bit(__IXGBE_RESETTING, &adapter->state)) {\n-\t\tfor (i = 0; i < adapter->num_vfs; i++) {\n-\t\t\tUPDATE_VF_COUNTER_32bit(IXGBE_PVFGPRC(i),\n-\t\t\t\t\t\tadapter->vfinfo[i].last_vfstats.gprc,\n-\t\t\t\t\t\tadapter->vfinfo[i].vfstats.gprc);\n-\t\t\tUPDATE_VF_COUNTER_32bit(IXGBE_PVFGPTC(i),\n-\t\t\t\t\t\tadapter->vfinfo[i].last_vfstats.gptc,\n-\t\t\t\t\t\tadapter->vfinfo[i].vfstats.gptc);\n-\t\t\tUPDATE_VF_COUNTER_36bit(IXGBE_PVFGORC_LSB(i),\n-\t\t\t\t\t\tIXGBE_PVFGORC_MSB(i),\n-\t\t\t\t\t\tadapter->vfinfo[i].last_vfstats.gorc,\n-\t\t\t\t\t\tadapter->vfinfo[i].vfstats.gorc);\n-\t\t\tUPDATE_VF_COUNTER_36bit(IXGBE_PVFGOTC_LSB(i),\n-\t\t\t\t\t\tIXGBE_PVFGOTC_MSB(i),\n-\t\t\t\t\t\tadapter->vfinfo[i].last_vfstats.gotc,\n-\t\t\t\t\t\tadapter->vfinfo[i].vfstats.gotc);\n-\t\t\tUPDATE_VF_COUNTER_32bit(IXGBE_PVFMPRC(i),\n-\t\t\t\t\t\tadapter->vfinfo[i].last_vfstats.mprc,\n-\t\t\t\t\t\tadapter->vfinfo[i].vfstats.mprc);\n-\t\t}\n+\t\tstruct vf_data_storage *vfinfo;\n+\n+\t\trcu_read_lock();\n+\t\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\t\tif (vfinfo)\n+\t\t\tfor (i = 0; i < adapter->num_vfs; i++) {\n+\t\t\t\tUPDATE_VF_COUNTER_32bit(IXGBE_PVFGPRC(i),\n+\t\t\t\t\t\t\tvfinfo[i].last_vfstats.gprc,\n+\t\t\t\t\t\t\tvfinfo[i].vfstats.gprc);\n+\t\t\t\tUPDATE_VF_COUNTER_32bit(IXGBE_PVFGPTC(i),\n+\t\t\t\t\t\t\tvfinfo[i].last_vfstats.gptc,\n+\t\t\t\t\t\t\tvfinfo[i].vfstats.gptc);\n+\t\t\t\tUPDATE_VF_COUNTER_36bit(IXGBE_PVFGORC_LSB(i),\n+\t\t\t\t\t\t\tIXGBE_PVFGORC_MSB(i),\n+\t\t\t\t\t\t\tvfinfo[i].last_vfstats.gorc,\n+\t\t\t\t\t\t\tvfinfo[i].vfstats.gorc);\n+\t\t\t\tUPDATE_VF_COUNTER_36bit(IXGBE_PVFGOTC_LSB(i),\n+\t\t\t\t\t\t\tIXGBE_PVFGOTC_MSB(i),\n+\t\t\t\t\t\t\tvfinfo[i].last_vfstats.gotc,\n+\t\t\t\t\t\t\tvfinfo[i].vfstats.gotc);\n+\t\t\t\tUPDATE_VF_COUNTER_32bit(IXGBE_PVFMPRC(i),\n+\t\t\t\t\t\t\tvfinfo[i].last_vfstats.mprc,\n+\t\t\t\t\t\t\tvfinfo[i].vfstats.mprc);\n+\t\t\t}\n+\t\trcu_read_unlock();\n \t}\n }\n \n@@ -8267,22 +8293,27 @@ static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter)\n static void ixgbe_bad_vf_abort(struct ixgbe_adapter *adapter, u32 vf)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct vf_data_storage *vfinfo;\n \n-\tif (adapter->hw.mac.type == ixgbe_mac_82599EB &&\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo &&\n+\t adapter->hw.mac.type == ixgbe_mac_82599EB &&\n \t adapter->flags2 & IXGBE_FLAG2_AUTO_DISABLE_VF) {\n-\t\tadapter->vfinfo[vf].primary_abort_count++;\n-\t\tif (adapter->vfinfo[vf].primary_abort_count ==\n+\t\tvfinfo[vf].primary_abort_count++;\n+\t\tif (vfinfo[vf].primary_abort_count ==\n \t\t IXGBE_PRIMARY_ABORT_LIMIT) {\n \t\t\tixgbe_set_vf_link_state(adapter, vf,\n \t\t\t\t\t\tIFLA_VF_LINK_STATE_DISABLE);\n-\t\t\tadapter->vfinfo[vf].primary_abort_count = 0;\n+\t\t\tvfinfo[vf].primary_abort_count = 0;\n \n \t\t\te_info(drv,\n \t\t\t \"Malicious Driver Detection event detected on PF %d VF %d MAC: %pM mdd-disable-vf=on\",\n \t\t\t hw->bus.func, vf,\n-\t\t\t adapter->vfinfo[vf].vf_mac_addresses);\n+\t\t\t vfinfo[vf].vf_mac_addresses);\n \t\t}\n \t}\n+\trcu_read_unlock();\n }\n \n static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)\n@@ -8309,9 +8340,15 @@ static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)\n \n \t/* check status reg for all VFs owned by this PF */\n \tfor (vf = 0; vf < adapter->num_vfs; ++vf) {\n-\t\tstruct pci_dev *vfdev = adapter->vfinfo[vf].vfdev;\n+\t\tstruct vf_data_storage *vfinfo;\n+\t\tstruct pci_dev *vfdev = NULL;\n \t\tu16 status_reg;\n \n+\t\trcu_read_lock();\n+\t\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\t\tif (vfinfo)\n+\t\t\tvfdev = vfinfo[vf].vfdev;\n+\t\trcu_read_unlock();\n \t\tif (!vfdev)\n \t\t\tcontinue;\n \t\tpci_read_config_word(vfdev, PCI_STATUS, &status_reg);\n@@ -9744,15 +9781,21 @@ static int ixgbe_ndo_get_vf_stats(struct net_device *netdev, int vf,\n \t\t\t\t struct ifla_vf_stats *vf_stats)\n {\n \tstruct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);\n+\tstruct vf_data_storage *vfinfo;\n \n \tif (vf < 0 || vf >= adapter->num_vfs)\n \t\treturn -EINVAL;\n \n-\tvf_stats->rx_packets = adapter->vfinfo[vf].vfstats.gprc;\n-\tvf_stats->rx_bytes = adapter->vfinfo[vf].vfstats.gorc;\n-\tvf_stats->tx_packets = adapter->vfinfo[vf].vfstats.gptc;\n-\tvf_stats->tx_bytes = adapter->vfinfo[vf].vfstats.gotc;\n-\tvf_stats->multicast = adapter->vfinfo[vf].vfstats.mprc;\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo) {\n+\t\tvf_stats->rx_packets = vfinfo[vf].vfstats.gprc;\n+\t\tvf_stats->rx_bytes = vfinfo[vf].vfstats.gorc;\n+\t\tvf_stats->tx_packets = vfinfo[vf].vfstats.gptc;\n+\t\tvf_stats->tx_bytes = vfinfo[vf].vfstats.gotc;\n+\t\tvf_stats->multicast = vfinfo[vf].vfstats.mprc;\n+\t}\n+\trcu_read_unlock();\n \n \treturn 0;\n }\n@@ -10071,20 +10114,26 @@ static int handle_redirect_action(struct ixgbe_adapter *adapter, int ifindex,\n {\n \tstruct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];\n \tunsigned int num_vfs = adapter->num_vfs, vf;\n+\tstruct vf_data_storage *vfinfo;\n \tstruct netdev_nested_priv priv;\n \tstruct upper_walk_data data;\n \tstruct net_device *upper;\n \n \t/* redirect to a SRIOV VF */\n-\tfor (vf = 0; vf < num_vfs; ++vf) {\n-\t\tupper = pci_get_drvdata(adapter->vfinfo[vf].vfdev);\n-\t\tif (upper->ifindex == ifindex) {\n-\t\t\t*queue = vf * __ALIGN_MASK(1, ~vmdq->mask);\n-\t\t\t*action = vf + 1;\n-\t\t\t*action <<= ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF;\n-\t\t\treturn 0;\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo)\n+\t\tfor (vf = 0; vf < num_vfs; ++vf) {\n+\t\t\tupper = pci_get_drvdata(vfinfo[vf].vfdev);\n+\t\t\tif (upper->ifindex == ifindex) {\n+\t\t\t\t*queue = vf * __ALIGN_MASK(1, ~vmdq->mask);\n+\t\t\t\t*action = vf + 1;\n+\t\t\t\t*action <<= ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF;\n+\t\t\t\trcu_read_unlock();\n+\t\t\t\treturn 0;\n+\t\t\t}\n \t\t}\n-\t}\n+\trcu_read_unlock();\n \n \t/* redirect to a offloaded macvlan netdev */\n \tdata.adapter = adapter;\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c\nindex 431d77da15a5..80f22a8e7af4 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c\n@@ -44,7 +44,7 @@ static inline void ixgbe_alloc_vf_macvlans(struct ixgbe_adapter *adapter,\n \t\t\tmv_list[i].free = true;\n \t\t\tlist_add(&mv_list[i].l, &adapter->vf_mvs.l);\n \t\t}\n-\t\tadapter->mv_list = mv_list;\n+\t\trcu_assign_pointer(adapter->mv_list, mv_list);\n \t}\n }\n \n@@ -52,6 +52,7 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter,\n \t\t\t\tunsigned int num_vfs)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct vf_data_storage *vfinfo;\n \tint i;\n \n \tif (adapter->xdp_prog) {\n@@ -64,14 +65,11 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter,\n \t\t\t IXGBE_FLAG_VMDQ_ENABLED;\n \n \t/* Allocate memory for per VF control structures */\n-\tadapter->vfinfo = kzalloc_objs(struct vf_data_storage, num_vfs);\n-\tif (!adapter->vfinfo)\n+\tvfinfo = kzalloc_objs(struct vf_data_storage, num_vfs);\n+\tif (!vfinfo)\n \t\treturn -ENOMEM;\n \n-\tadapter->num_vfs = num_vfs;\n-\n \tixgbe_alloc_vf_macvlans(adapter, num_vfs);\n-\tadapter->ring_feature[RING_F_VMDQ].offset = num_vfs;\n \n \t/* Initialize default switching mode VEB */\n \tIXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);\n@@ -95,23 +93,27 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter,\n \n \tfor (i = 0; i < num_vfs; i++) {\n \t\t/* enable spoof checking for all VFs */\n-\t\tadapter->vfinfo[i].spoofchk_enabled = true;\n-\t\tadapter->vfinfo[i].link_enable = true;\n+\t\tvfinfo[i].spoofchk_enabled = true;\n+\t\tvfinfo[i].link_enable = true;\n \n \t\t/* We support VF RSS querying only for 82599 and x540\n \t\t * devices at the moment. These devices share RSS\n \t\t * indirection table and RSS hash key with PF therefore\n \t\t * we want to disable the querying by default.\n \t\t */\n-\t\tadapter->vfinfo[i].rss_query_enabled = false;\n+\t\tvfinfo[i].rss_query_enabled = false;\n \n \t\t/* Untrust all VFs */\n-\t\tadapter->vfinfo[i].trusted = false;\n+\t\tvfinfo[i].trusted = false;\n \n \t\t/* set the default xcast mode */\n-\t\tadapter->vfinfo[i].xcast_mode = IXGBEVF_XCAST_MODE_NONE;\n+\t\tvfinfo[i].xcast_mode = IXGBEVF_XCAST_MODE_NONE;\n \t}\n \n+\trcu_assign_pointer(adapter->vfinfo, vfinfo);\n+\tadapter->num_vfs = num_vfs;\n+\tadapter->ring_feature[RING_F_VMDQ].offset = num_vfs;\n+\n \te_info(probe, \"SR-IOV enabled with %d VFs\\n\", num_vfs);\n \treturn 0;\n }\n@@ -123,6 +125,7 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter,\n static void ixgbe_get_vfs(struct ixgbe_adapter *adapter)\n {\n \tstruct pci_dev *pdev = adapter->pdev;\n+\tstruct vf_data_storage *vfinfo;\n \tu16 vendor = pdev->vendor;\n \tstruct pci_dev *vfdev;\n \tint vf = 0;\n@@ -134,18 +137,23 @@ static void ixgbe_get_vfs(struct ixgbe_adapter *adapter)\n \t\treturn;\n \tpci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id);\n \n-\tvfdev = pci_get_device(vendor, vf_id, NULL);\n-\tfor (; vfdev; vfdev = pci_get_device(vendor, vf_id, vfdev)) {\n-\t\tif (!vfdev->is_virtfn)\n-\t\t\tcontinue;\n-\t\tif (vfdev->physfn != pdev)\n-\t\t\tcontinue;\n-\t\tif (vf >= adapter->num_vfs)\n-\t\t\tcontinue;\n-\t\tpci_dev_get(vfdev);\n-\t\tadapter->vfinfo[vf].vfdev = vfdev;\n-\t\t++vf;\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo) {\n+\t\tvfdev = pci_get_device(vendor, vf_id, NULL);\n+\t\tfor (; vfdev; vfdev = pci_get_device(vendor, vf_id, vfdev)) {\n+\t\t\tif (!vfdev->is_virtfn)\n+\t\t\t\tcontinue;\n+\t\t\tif (vfdev->physfn != pdev)\n+\t\t\t\tcontinue;\n+\t\t\tif (vf >= adapter->num_vfs)\n+\t\t\t\tcontinue;\n+\t\t\tpci_dev_get(vfdev);\n+\t\t\tvfinfo[vf].vfdev = vfdev;\n+\t\t\t++vf;\n+\t\t}\n \t}\n+\trcu_read_unlock();\n }\n \n /* Note this function is called when the user wants to enable SR-IOV\n@@ -206,31 +214,28 @@ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)\n {\n \tunsigned int num_vfs = adapter->num_vfs, vf;\n \tstruct ixgbe_hw *hw = &adapter->hw;\n-\tunsigned long flags;\n+\tstruct vf_data_storage *vfinfo;\n+\tstruct vf_macvlans *mv_list;\n \tint rss;\n \n-\tspin_lock_irqsave(&adapter->vfs_lock, flags);\n-\t/* set num VFs to 0 to prevent access to vfinfo */\n+\t/* set num VFs to 0 so readers bail out early */\n \tadapter->num_vfs = 0;\n-\tspin_unlock_irqrestore(&adapter->vfs_lock, flags);\n+\n+\tvfinfo = rcu_replace_pointer(adapter->vfinfo, NULL, 1);\n+\tmv_list = rcu_replace_pointer(adapter->mv_list, NULL, 1);\n \n \t/* put the reference to all of the vf devices */\n \tfor (vf = 0; vf < num_vfs; ++vf) {\n-\t\tstruct pci_dev *vfdev = adapter->vfinfo[vf].vfdev;\n+\t\tstruct pci_dev *vfdev = vfinfo[vf].vfdev;\n \n \t\tif (!vfdev)\n \t\t\tcontinue;\n-\t\tadapter->vfinfo[vf].vfdev = NULL;\n+\t\tvfinfo[vf].vfdev = NULL;\n \t\tpci_dev_put(vfdev);\n \t}\n \n-\t/* free VF control structures */\n-\tkfree(adapter->vfinfo);\n-\tadapter->vfinfo = NULL;\n-\n-\t/* free macvlan list */\n-\tkfree(adapter->mv_list);\n-\tadapter->mv_list = NULL;\n+\tkfree_rcu(vfinfo, rcu_head);\n+\tkfree_rcu(mv_list, rcu_head);\n \n \t/* if SR-IOV is already disabled then there is nothing to do */\n \tif (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))\n@@ -368,8 +373,8 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,\n {\n \tint entries = FIELD_GET(IXGBE_VT_MSGINFO_MASK, msgbuf[0]);\n \tu16 *hash_list = (u16 *)&msgbuf[1];\n-\tstruct vf_data_storage *vfinfo = &adapter->vfinfo[vf];\n \tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct vf_data_storage *vfinfo;\n \tint i;\n \tu32 vector_bit;\n \tu32 vector_reg;\n@@ -379,28 +384,34 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,\n \t/* only so many hash values supported */\n \tentries = min(entries, IXGBE_MAX_VF_MC_ENTRIES);\n \n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n \t/*\n \t * salt away the number of multi cast addresses assigned\n \t * to this VF for later use to restore when the PF multi cast\n \t * list changes\n \t */\n-\tvfinfo->num_vf_mc_hashes = entries;\n+\tvfinfo[vf].num_vf_mc_hashes = entries;\n \n \t/*\n \t * VFs are limited to using the MTA hash table for their multicast\n \t * addresses\n \t */\n \tfor (i = 0; i < entries; i++) {\n-\t\tvfinfo->vf_mc_hashes[i] = hash_list[i];\n+\t\tvfinfo[vf].vf_mc_hashes[i] = hash_list[i];\n \t}\n \n-\tfor (i = 0; i < vfinfo->num_vf_mc_hashes; i++) {\n-\t\tvector_reg = (vfinfo->vf_mc_hashes[i] >> 5) & 0x7F;\n-\t\tvector_bit = vfinfo->vf_mc_hashes[i] & 0x1F;\n+\tfor (i = 0; i < vfinfo[vf].num_vf_mc_hashes; i++) {\n+\t\tvector_reg = (vfinfo[vf].vf_mc_hashes[i] >> 5) & 0x7F;\n+\t\tvector_bit = vfinfo[vf].vf_mc_hashes[i] & 0x1F;\n \t\tmta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg));\n \t\tmta_reg |= BIT(vector_bit);\n \t\tIXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);\n \t}\n+\n \tvmolr |= IXGBE_VMOLR_ROMPE;\n \tIXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);\n \n@@ -410,32 +421,39 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,\n #ifdef CONFIG_PCI_IOV\n void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)\n {\n-\tstruct ixgbe_hw *hw = &adapter->hw;\n \tstruct vf_data_storage *vfinfo;\n+\tstruct ixgbe_hw *hw = &adapter->hw;\n \tint i, j;\n \tu32 vector_bit;\n \tu32 vector_reg;\n \tu32 mta_reg;\n \n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\tgoto no_vfs;\n+\n \tfor (i = 0; i < adapter->num_vfs; i++) {\n \t\tu32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(i));\n-\t\tvfinfo = &adapter->vfinfo[i];\n-\t\tfor (j = 0; j < vfinfo->num_vf_mc_hashes; j++) {\n+\t\tfor (j = 0; j < vfinfo[i].num_vf_mc_hashes; j++) {\n \t\t\thw->addr_ctrl.mta_in_use++;\n-\t\t\tvector_reg = (vfinfo->vf_mc_hashes[j] >> 5) & 0x7F;\n-\t\t\tvector_bit = vfinfo->vf_mc_hashes[j] & 0x1F;\n+\t\t\tvector_reg = (vfinfo[i].vf_mc_hashes[j] >> 5) & 0x7F;\n+\t\t\tvector_bit = vfinfo[i].vf_mc_hashes[j] & 0x1F;\n \t\t\tmta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg));\n \t\t\tmta_reg |= BIT(vector_bit);\n \t\t\tIXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);\n \t\t}\n \n-\t\tif (vfinfo->num_vf_mc_hashes)\n+\t\tif (vfinfo[i].num_vf_mc_hashes)\n \t\t\tvmolr |= IXGBE_VMOLR_ROMPE;\n \t\telse\n \t\t\tvmolr &= ~IXGBE_VMOLR_ROMPE;\n \t\tIXGBE_WRITE_REG(hw, IXGBE_VMOLR(i), vmolr);\n \t}\n \n+no_vfs:\n+\trcu_read_unlock();\n+\n \t/* Restore any VF macvlans */\n \tixgbe_full_sync_mac_table(adapter);\n }\n@@ -493,7 +511,9 @@ static int ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 max_frame, u32 vf\n \t */\n \tif (adapter->hw.mac.type == ixgbe_mac_82599EB) {\n \t\tstruct net_device *dev = adapter->netdev;\n+\t\tunsigned int vf_api = ixgbe_mbox_api_10;\n \t\tint pf_max_frame = dev->mtu + ETH_HLEN;\n+\t\tstruct vf_data_storage *vfinfo;\n \t\tu32 reg_offset, vf_shift, vfre;\n \t\tint err = 0;\n \n@@ -503,7 +523,12 @@ static int ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 max_frame, u32 vf\n \t\t\t\t\t IXGBE_FCOE_JUMBO_FRAME_SIZE);\n \n #endif /* CONFIG_FCOE */\n-\t\tswitch (adapter->vfinfo[vf].vf_api) {\n+\t\tlockdep_assert_in_rcu_read_lock();\n+\t\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\t\tif (vfinfo)\n+\t\t\tvf_api = vfinfo[vf].vf_api;\n+\n+\t\tswitch (vf_api) {\n \t\tcase ixgbe_mbox_api_11:\n \t\tcase ixgbe_mbox_api_12:\n \t\tcase ixgbe_mbox_api_13:\n@@ -643,10 +668,16 @@ static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)\n static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,\n \t\t\t\tint vf, int index, unsigned char *mac_addr)\n {\n-\tstruct vf_macvlans *entry;\n+\tstruct vf_macvlans *mv_list, *entry;\n \tbool found = false;\n \tint retval = 0;\n \n+\tlockdep_assert_in_rcu_read_lock();\n+\t/* vf_mvs entries point into the mv_list array */\n+\tmv_list = rcu_dereference(adapter->mv_list);\n+\tif (!mv_list)\n+\t\treturn 0;\n+\n \tif (index <= 1) {\n \t\tlist_for_each_entry(entry, &adapter->vf_mvs.l, l) {\n \t\t\tif (entry->vf == vf) {\n@@ -700,7 +731,7 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n \tstruct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];\n-\tstruct vf_data_storage *vfinfo = &adapter->vfinfo[vf];\n+\tstruct vf_data_storage *vfinfo;\n \tu32 q_per_pool = __ALIGN_MASK(1, ~vmdq->mask);\n \tu8 num_tcs = adapter->hw_tcs;\n \tu32 reg_val;\n@@ -709,31 +740,36 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)\n \t/* remove VLAN filters belonging to this VF */\n \tixgbe_clear_vf_vlans(adapter, vf);\n \n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn;\n+\n \t/* add back PF assigned VLAN or VLAN 0 */\n-\tixgbe_set_vf_vlan(adapter, true, vfinfo->pf_vlan, vf);\n+\tixgbe_set_vf_vlan(adapter, true, vfinfo[vf].pf_vlan, vf);\n \n \t/* reset offloads to defaults */\n-\tixgbe_set_vmolr(hw, vf, !vfinfo->pf_vlan);\n+\tixgbe_set_vmolr(hw, vf, !vfinfo[vf].pf_vlan);\n \n \t/* set outgoing tags for VFs */\n-\tif (!vfinfo->pf_vlan && !vfinfo->pf_qos && !num_tcs) {\n+\tif (!vfinfo[vf].pf_vlan && !vfinfo[vf].pf_qos && !num_tcs) {\n \t\tixgbe_clear_vmvir(adapter, vf);\n \t} else {\n-\t\tif (vfinfo->pf_qos || !num_tcs)\n-\t\t\tixgbe_set_vmvir(adapter, vfinfo->pf_vlan,\n-\t\t\t\t\tvfinfo->pf_qos, vf);\n+\t\tif (vfinfo[vf].pf_qos || !num_tcs)\n+\t\t\tixgbe_set_vmvir(adapter, vfinfo[vf].pf_vlan,\n+\t\t\t\t\tvfinfo[vf].pf_qos, vf);\n \t\telse\n-\t\t\tixgbe_set_vmvir(adapter, vfinfo->pf_vlan,\n+\t\t\tixgbe_set_vmvir(adapter, vfinfo[vf].pf_vlan,\n \t\t\t\t\tadapter->default_up, vf);\n \n-\t\tif (vfinfo->spoofchk_enabled) {\n+\t\tif (vfinfo[vf].spoofchk_enabled) {\n \t\t\thw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);\n \t\t\thw->mac.ops.set_mac_anti_spoofing(hw, true, vf);\n \t\t}\n \t}\n \n \t/* reset multicast table array for vf */\n-\tadapter->vfinfo[vf].num_vf_mc_hashes = 0;\n+\tvfinfo[vf].num_vf_mc_hashes = 0;\n \n \t/* clear any ipsec table info */\n \tixgbe_ipsec_vf_clear(adapter, vf);\n@@ -741,11 +777,11 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)\n \t/* Flush and reset the mta with the new values */\n \tixgbe_set_rx_mode(adapter->netdev);\n \n-\tixgbe_del_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf);\n+\tixgbe_del_mac_filter(adapter, vfinfo[vf].vf_mac_addresses, vf);\n \tixgbe_set_vf_macvlan(adapter, vf, 0, NULL);\n \n \t/* reset VF api back to unknown */\n-\tadapter->vfinfo[vf].vf_api = ixgbe_mbox_api_10;\n+\tvfinfo[vf].vf_api = ixgbe_mbox_api_10;\n \n \t/* Restart each queue for given VF */\n \tfor (queue = 0; queue < q_per_pool; queue++) {\n@@ -780,16 +816,25 @@ static void ixgbe_vf_clear_mbx(struct ixgbe_adapter *adapter, u32 vf)\n static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,\n \t\t\t int vf, unsigned char *mac_addr)\n {\n+\tstruct vf_data_storage *vfinfo;\n \tint retval;\n \n-\tixgbe_del_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf);\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo) {\n+\t\trcu_read_unlock();\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tixgbe_del_mac_filter(adapter, vfinfo[vf].vf_mac_addresses, vf);\n \tretval = ixgbe_add_mac_filter(adapter, mac_addr, vf);\n \tif (retval >= 0)\n-\t\tmemcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr,\n+\t\tmemcpy(vfinfo[vf].vf_mac_addresses, mac_addr,\n \t\t ETH_ALEN);\n \telse\n-\t\teth_zero_addr(adapter->vfinfo[vf].vf_mac_addresses);\n+\t\teth_zero_addr(vfinfo[vf].vf_mac_addresses);\n \n+\trcu_read_unlock();\n \treturn retval;\n }\n \n@@ -797,12 +842,17 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)\n {\n \tstruct ixgbe_adapter *adapter = pci_get_drvdata(pdev);\n \tunsigned int vfn = (event_mask & 0x3f);\n+\tstruct vf_data_storage *vfinfo;\n \n \tbool enable = ((event_mask & 0x10000000U) != 0);\n \n-\tif (enable)\n-\t\teth_zero_addr(adapter->vfinfo[vfn].vf_mac_addresses);\n-\n+\tif (enable) {\n+\t\trcu_read_lock();\n+\t\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\t\tif (vfinfo)\n+\t\t\teth_zero_addr(vfinfo[vfn].vf_mac_addresses);\n+\t\trcu_read_unlock();\n+\t}\n \treturn 0;\n }\n \n@@ -838,6 +888,7 @@ static void ixgbe_set_vf_rx_tx(struct ixgbe_adapter *adapter, int vf)\n {\n \tu32 reg_cur_tx, reg_cur_rx, reg_req_tx, reg_req_rx;\n \tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct vf_data_storage *vfinfo;\n \tu32 reg_offset, vf_shift;\n \n \tvf_shift = vf % 32;\n@@ -846,7 +897,9 @@ static void ixgbe_set_vf_rx_tx(struct ixgbe_adapter *adapter, int vf)\n \treg_cur_tx = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset));\n \treg_cur_rx = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset));\n \n-\tif (adapter->vfinfo[vf].link_enable) {\n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo && vfinfo[vf].link_enable) {\n \t\treg_req_tx = reg_cur_tx | 1 << vf_shift;\n \t\treg_req_rx = reg_cur_rx | 1 << vf_shift;\n \t} else {\n@@ -882,11 +935,12 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)\n {\n \tstruct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];\n \tstruct ixgbe_hw *hw = &adapter->hw;\n-\tunsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses;\n+\tstruct vf_data_storage *vfinfo;\n \tu32 reg, reg_offset, vf_shift;\n \tu32 msgbuf[4] = {0, 0, 0, 0};\n \tu8 *addr = (u8 *)(&msgbuf[1]);\n \tu32 q_per_pool = __ALIGN_MASK(1, ~vmdq->mask);\n+\tunsigned char *vf_mac;\n \tint i;\n \n \te_info(probe, \"VF Reset msg received from vf %d\\n\", vf);\n@@ -896,6 +950,13 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)\n \n \tixgbe_vf_clear_mbx(adapter, vf);\n \n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n+\tvf_mac = vfinfo[vf].vf_mac_addresses;\n+\n \t/* set vf mac address */\n \tif (!is_zero_ether_addr(vf_mac))\n \t\tixgbe_set_vf_mac(adapter, vf, vf_mac);\n@@ -905,7 +966,7 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)\n \n \t/* force drop enable for all VF Rx queues */\n \treg = IXGBE_QDE_ENABLE;\n-\tif (adapter->vfinfo[vf].pf_vlan)\n+\tif (vfinfo[vf].pf_vlan)\n \t\treg |= IXGBE_QDE_HIDE_VLAN;\n \n \tixgbe_write_qde(adapter, vf, reg);\n@@ -913,7 +974,7 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)\n \tixgbe_set_vf_rx_tx(adapter, vf);\n \n \t/* enable VF mailbox for further messages */\n-\tadapter->vfinfo[vf].clear_to_send = true;\n+\tvfinfo[vf].clear_to_send = true;\n \n \t/* Enable counting of spoofed packets in the SSVPC register */\n \treg = IXGBE_READ_REG(hw, IXGBE_VMECM(reg_offset));\n@@ -931,7 +992,7 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)\n \n \t/* reply to reset with ack and vf mac address */\n \tmsgbuf[0] = IXGBE_VF_RESET;\n-\tif (!is_zero_ether_addr(vf_mac) && adapter->vfinfo[vf].pf_set_mac) {\n+\tif (!is_zero_ether_addr(vf_mac) && vfinfo[vf].pf_set_mac) {\n \t\tmsgbuf[0] |= IXGBE_VT_MSGTYPE_ACK;\n \t\tmemcpy(addr, vf_mac, ETH_ALEN);\n \t} else {\n@@ -952,14 +1013,20 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter,\n \t\t\t\t u32 *msgbuf, u32 vf)\n {\n \tu8 *new_mac = ((u8 *)(&msgbuf[1]));\n+\tstruct vf_data_storage *vfinfo;\n \n \tif (!is_valid_ether_addr(new_mac)) {\n \t\te_warn(drv, \"VF %d attempted to set invalid mac\\n\", vf);\n \t\treturn -1;\n \t}\n \n-\tif (adapter->vfinfo[vf].pf_set_mac && !adapter->vfinfo[vf].trusted &&\n-\t !ether_addr_equal(adapter->vfinfo[vf].vf_mac_addresses, new_mac)) {\n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n+\tif (vfinfo[vf].pf_set_mac && !vfinfo[vf].trusted &&\n+\t !ether_addr_equal(vfinfo[vf].vf_mac_addresses, new_mac)) {\n \t\te_warn(drv,\n \t\t \"VF %d attempted to override administratively set MAC address\\n\"\n \t\t \"Reload the VF driver to resume operations\\n\",\n@@ -975,9 +1042,15 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,\n {\n \tu32 add = FIELD_GET(IXGBE_VT_MSGINFO_MASK, msgbuf[0]);\n \tu32 vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK);\n+\tstruct vf_data_storage *vfinfo;\n \tu8 tcs = adapter->hw_tcs;\n \n-\tif (adapter->vfinfo[vf].pf_vlan || tcs) {\n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n+\tif (vfinfo[vf].pf_vlan || tcs) {\n \t\te_warn(drv,\n \t\t \"VF %d attempted to override administratively set VLAN configuration\\n\"\n \t\t \"Reload the VF driver to resume operations\\n\",\n@@ -997,9 +1070,15 @@ static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,\n {\n \tu8 *new_mac = ((u8 *)(&msgbuf[1]));\n \tint index = FIELD_GET(IXGBE_VT_MSGINFO_MASK, msgbuf[0]);\n+\tstruct vf_data_storage *vfinfo;\n \tint err;\n \n-\tif (adapter->vfinfo[vf].pf_set_mac && !adapter->vfinfo[vf].trusted &&\n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n+\tif (vfinfo[vf].pf_set_mac && !vfinfo[vf].trusted &&\n \t index > 0) {\n \t\te_warn(drv,\n \t\t \"VF %d requested MACVLAN filter but is administratively denied\\n\",\n@@ -1018,7 +1097,7 @@ static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,\n \t\t * If the VF is allowed to set MAC filters then turn off\n \t\t * anti-spoofing to avoid false positives.\n \t\t */\n-\t\tif (adapter->vfinfo[vf].spoofchk_enabled) {\n+\t\tif (vfinfo[vf].spoofchk_enabled) {\n \t\t\tstruct ixgbe_hw *hw = &adapter->hw;\n \n \t\t\thw->mac.ops.set_mac_anti_spoofing(hw, false, vf);\n@@ -1038,6 +1117,7 @@ static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,\n static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter,\n \t\t\t\t u32 *msgbuf, u32 vf)\n {\n+\tstruct vf_data_storage *vfinfo;\n \tint api = msgbuf[1];\n \n \tswitch (api) {\n@@ -1048,7 +1128,10 @@ static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter,\n \tcase ixgbe_mbox_api_14:\n \tcase ixgbe_mbox_api_16:\n \tcase ixgbe_mbox_api_17:\n-\t\tadapter->vfinfo[vf].vf_api = api;\n+\t\tlockdep_assert_in_rcu_read_lock();\n+\t\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\t\tif (vfinfo)\n+\t\t\tvfinfo[vf].vf_api = api;\n \t\treturn 0;\n \tdefault:\n \t\tbreak;\n@@ -1064,11 +1147,17 @@ static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter,\n {\n \tstruct net_device *dev = adapter->netdev;\n \tstruct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];\n+\tstruct vf_data_storage *vfinfo;\n \tunsigned int default_tc = 0;\n \tu8 num_tcs = adapter->hw_tcs;\n \n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n \t/* verify the PF is supporting the correct APIs */\n-\tswitch (adapter->vfinfo[vf].vf_api) {\n+\tswitch (vfinfo[vf].vf_api) {\n \tcase ixgbe_mbox_api_20:\n \tcase ixgbe_mbox_api_11:\n \tcase ixgbe_mbox_api_12:\n@@ -1092,7 +1181,7 @@ static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter,\n \t/* notify VF of need for VLAN tag stripping, and correct queue */\n \tif (num_tcs)\n \t\tmsgbuf[IXGBE_VF_TRANS_VLAN] = num_tcs;\n-\telse if (adapter->vfinfo[vf].pf_vlan || adapter->vfinfo[vf].pf_qos)\n+\telse if (vfinfo[vf].pf_vlan || vfinfo[vf].pf_qos)\n \t\tmsgbuf[IXGBE_VF_TRANS_VLAN] = 1;\n \telse\n \t\tmsgbuf[IXGBE_VF_TRANS_VLAN] = 0;\n@@ -1105,17 +1194,23 @@ static int ixgbe_get_vf_queues(struct ixgbe_adapter *adapter,\n \n static int ixgbe_get_vf_reta(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)\n {\n-\tu32 i, j;\n-\tu32 *out_buf = &msgbuf[1];\n-\tconst u8 *reta = adapter->rss_indir_tbl;\n \tu32 reta_size = ixgbe_rss_indir_tbl_entries(adapter);\n+\tconst u8 *reta = adapter->rss_indir_tbl;\n+\tstruct vf_data_storage *vfinfo;\n+\tu32 *out_buf = &msgbuf[1];\n+\tu32 i, j;\n+\n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n \n \t/* Check if operation is permitted */\n-\tif (!adapter->vfinfo[vf].rss_query_enabled)\n+\tif (!vfinfo[vf].rss_query_enabled)\n \t\treturn -EPERM;\n \n \t/* verify the PF is supporting the correct API */\n-\tswitch (adapter->vfinfo[vf].vf_api) {\n+\tswitch (vfinfo[vf].vf_api) {\n \tcase ixgbe_mbox_api_17:\n \tcase ixgbe_mbox_api_16:\n \tcase ixgbe_mbox_api_14:\n@@ -1143,14 +1238,20 @@ static int ixgbe_get_vf_reta(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)\n static int ixgbe_get_vf_rss_key(struct ixgbe_adapter *adapter,\n \t\t\t\tu32 *msgbuf, u32 vf)\n {\n+\tstruct vf_data_storage *vfinfo;\n \tu32 *rss_key = &msgbuf[1];\n \n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n \t/* Check if the operation is permitted */\n-\tif (!adapter->vfinfo[vf].rss_query_enabled)\n+\tif (!vfinfo[vf].rss_query_enabled)\n \t\treturn -EPERM;\n \n \t/* verify the PF is supporting the correct API */\n-\tswitch (adapter->vfinfo[vf].vf_api) {\n+\tswitch (vfinfo[vf].vf_api) {\n \tcase ixgbe_mbox_api_17:\n \tcase ixgbe_mbox_api_16:\n \tcase ixgbe_mbox_api_14:\n@@ -1170,11 +1271,17 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,\n \t\t\t\t u32 *msgbuf, u32 vf)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct vf_data_storage *vfinfo;\n \tint xcast_mode = msgbuf[1];\n \tu32 vmolr, fctrl, disable, enable;\n \n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n \t/* verify the PF is supporting the correct APIs */\n-\tswitch (adapter->vfinfo[vf].vf_api) {\n+\tswitch (vfinfo[vf].vf_api) {\n \tcase ixgbe_mbox_api_12:\n \t\t/* promisc introduced in 1.3 version */\n \t\tif (xcast_mode == IXGBEVF_XCAST_MODE_PROMISC)\n@@ -1190,11 +1297,11 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,\n \t}\n \n \tif (xcast_mode > IXGBEVF_XCAST_MODE_MULTI &&\n-\t !adapter->vfinfo[vf].trusted) {\n+\t !vfinfo[vf].trusted) {\n \t\txcast_mode = IXGBEVF_XCAST_MODE_MULTI;\n \t}\n \n-\tif (adapter->vfinfo[vf].xcast_mode == xcast_mode)\n+\tif (vfinfo[vf].xcast_mode == xcast_mode)\n \t\tgoto out;\n \n \tswitch (xcast_mode) {\n@@ -1236,7 +1343,7 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,\n \tvmolr |= enable;\n \tIXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);\n \n-\tadapter->vfinfo[vf].xcast_mode = xcast_mode;\n+\tvfinfo[vf].xcast_mode = xcast_mode;\n \n out:\n \tmsgbuf[1] = xcast_mode;\n@@ -1247,10 +1354,16 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,\n static int ixgbe_get_vf_link_state(struct ixgbe_adapter *adapter,\n \t\t\t\t u32 *msgbuf, u32 vf)\n {\n+\tstruct vf_data_storage *vfinfo;\n \tu32 *link_state = &msgbuf[1];\n \n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n \t/* verify the PF is supporting the correct API */\n-\tswitch (adapter->vfinfo[vf].vf_api) {\n+\tswitch (vfinfo[vf].vf_api) {\n \tcase ixgbe_mbox_api_12:\n \tcase ixgbe_mbox_api_13:\n \tcase ixgbe_mbox_api_14:\n@@ -1261,7 +1374,7 @@ static int ixgbe_get_vf_link_state(struct ixgbe_adapter *adapter,\n \t\treturn -EOPNOTSUPP;\n \t}\n \n-\t*link_state = adapter->vfinfo[vf].link_enable;\n+\t*link_state = vfinfo[vf].link_enable;\n \n \treturn 0;\n }\n@@ -1280,8 +1393,14 @@ static int ixgbe_send_vf_link_status(struct ixgbe_adapter *adapter,\n \t\t\t\t u32 *msgbuf, u32 vf)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct vf_data_storage *vfinfo;\n+\n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n \n-\tswitch (adapter->vfinfo[vf].vf_api) {\n+\tswitch (vfinfo[vf].vf_api) {\n \tcase ixgbe_mbox_api_16:\n \tcase ixgbe_mbox_api_17:\n \t\tif (hw->mac.type != ixgbe_mac_e610)\n@@ -1310,9 +1429,15 @@ static int ixgbe_send_vf_link_status(struct ixgbe_adapter *adapter,\n static int ixgbe_negotiate_vf_features(struct ixgbe_adapter *adapter,\n \t\t\t\t u32 *msgbuf, u32 vf)\n {\n+\tstruct vf_data_storage *vfinfo;\n \tu32 features = msgbuf[1];\n \n-\tswitch (adapter->vfinfo[vf].vf_api) {\n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n+\tswitch (vfinfo[vf].vf_api) {\n \tcase ixgbe_mbox_api_17:\n \t\tbreak;\n \tdefault:\n@@ -1330,6 +1455,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)\n \tu32 mbx_size = IXGBE_VFMAILBOX_SIZE;\n \tu32 msgbuf[IXGBE_VFMAILBOX_SIZE];\n \tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct vf_data_storage *vfinfo;\n \tint retval;\n \n \tretval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);\n@@ -1349,11 +1475,16 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)\n \tif (msgbuf[0] == IXGBE_VF_RESET)\n \t\treturn ixgbe_vf_reset_msg(adapter, vf);\n \n+\tlockdep_assert_in_rcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\treturn 0;\n+\n \t/*\n \t * until the vf completes a virtual function reset it should not be\n \t * allowed to start any configuration.\n \t */\n-\tif (!adapter->vfinfo[vf].clear_to_send) {\n+\tif (!vfinfo[vf].clear_to_send) {\n \t\tmsgbuf[0] |= IXGBE_VT_MSGTYPE_NACK;\n \t\tixgbe_write_mbx(hw, msgbuf, 1, vf);\n \t\treturn 0;\n@@ -1426,11 +1557,12 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)\n \n static void ixgbe_rcv_ack_from_vf(struct ixgbe_adapter *adapter, u32 vf)\n {\n+\tstruct vf_data_storage *vfinfo = rcu_dereference(adapter->vfinfo);\n \tstruct ixgbe_hw *hw = &adapter->hw;\n \tu32 msg = IXGBE_VT_MSGTYPE_NACK;\n \n \t/* if device isn't clear to send it shouldn't be reading either */\n-\tif (!adapter->vfinfo[vf].clear_to_send)\n+\tif (vfinfo && !vfinfo[vf].clear_to_send)\n \t\tixgbe_write_mbx(hw, &msg, 1, vf);\n }\n \n@@ -1462,15 +1594,21 @@ bool ixgbe_check_mdd_event(struct ixgbe_adapter *adapter)\n \t\t\t IXGBE_READ_REG(hw, IXGBE_LVMMC_RX));\n \n \t\tif (hw->mac.ops.restore_mdd_vf) {\n+\t\t\tstruct vf_data_storage *vfinfo;\n \t\t\tu32 ping;\n \n \t\t\thw->mac.ops.restore_mdd_vf(hw, i);\n \n \t\t\t/* get the VF to rebuild its queues */\n-\t\t\tadapter->vfinfo[i].clear_to_send = 0;\n-\t\t\tping = IXGBE_PF_CONTROL_MSG |\n-\t\t\t IXGBE_VT_MSGTYPE_CTS;\n-\t\t\tixgbe_write_mbx(hw, &ping, 1, i);\n+\t\t\trcu_read_lock();\n+\t\t\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\t\t\tif (vfinfo) {\n+\t\t\t\tvfinfo[i].clear_to_send = false;\n+\t\t\t\tping = IXGBE_PF_CONTROL_MSG |\n+\t\t\t\t IXGBE_VT_MSGTYPE_CTS;\n+\t\t\t\tixgbe_write_mbx(hw, &ping, 1, i);\n+\t\t\t}\n+\t\t\trcu_read_unlock();\n \t\t}\n \n \t\tret = true;\n@@ -1482,12 +1620,11 @@ bool ixgbe_check_mdd_event(struct ixgbe_adapter *adapter)\n void ixgbe_msg_task(struct ixgbe_adapter *adapter)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n-\tunsigned long flags;\n \tu32 vf;\n \n \tixgbe_check_mdd_event(adapter);\n \n-\tspin_lock_irqsave(&adapter->vfs_lock, flags);\n+\trcu_read_lock();\n \tfor (vf = 0; vf < adapter->num_vfs; vf++) {\n \t\t/* process any reset requests */\n \t\tif (!ixgbe_check_for_rst(hw, vf))\n@@ -1501,7 +1638,7 @@ void ixgbe_msg_task(struct ixgbe_adapter *adapter)\n \t\tif (!ixgbe_check_for_ack(hw, vf))\n \t\t\tixgbe_rcv_ack_from_vf(adapter, vf);\n \t}\n-\tspin_unlock_irqrestore(&adapter->vfs_lock, flags);\n+\trcu_read_unlock();\n }\n \n static inline void ixgbe_ping_vf(struct ixgbe_adapter *adapter, int vf)\n@@ -1510,23 +1647,26 @@ static inline void ixgbe_ping_vf(struct ixgbe_adapter *adapter, int vf)\n \tu32 ping;\n \n \tping = IXGBE_PF_CONTROL_MSG;\n-\tif (adapter->vfinfo[vf].clear_to_send)\n-\t\tping |= IXGBE_VT_MSGTYPE_CTS;\n \tixgbe_write_mbx(hw, &ping, 1, vf);\n }\n \n void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct vf_data_storage *vfinfo;\n \tu32 ping;\n \tint i;\n \n-\tfor (i = 0 ; i < adapter->num_vfs; i++) {\n-\t\tping = IXGBE_PF_CONTROL_MSG;\n-\t\tif (adapter->vfinfo[i].clear_to_send)\n-\t\t\tping |= IXGBE_VT_MSGTYPE_CTS;\n-\t\tixgbe_write_mbx(hw, &ping, 1, i);\n-\t}\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo)\n+\t\tfor (i = 0 ; i < adapter->num_vfs; i++) {\n+\t\t\tping = IXGBE_PF_CONTROL_MSG;\n+\t\t\tif (vfinfo[i].clear_to_send)\n+\t\t\t\tping |= IXGBE_VT_MSGTYPE_CTS;\n+\t\t\tixgbe_write_mbx(hw, &ping, 1, i);\n+\t\t}\n+\trcu_read_unlock();\n }\n \n /**\n@@ -1537,21 +1677,34 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter)\n **/\n void ixgbe_set_all_vfs(struct ixgbe_adapter *adapter)\n {\n+\tstruct vf_data_storage *vfinfo;\n \tint i;\n \n-\tfor (i = 0 ; i < adapter->num_vfs; i++)\n-\t\tixgbe_set_vf_link_state(adapter, i,\n-\t\t\t\t\tadapter->vfinfo[i].link_state);\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo)\n+\t\tfor (i = 0 ; i < adapter->num_vfs; i++)\n+\t\t\tixgbe_set_vf_link_state(adapter, i,\n+\t\t\t\t\t\tvfinfo[i].link_state);\n+\trcu_read_unlock();\n }\n \n int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)\n {\n \tstruct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);\n+\tstruct vf_data_storage *vfinfo;\n \tint retval;\n \n \tif (vf >= adapter->num_vfs)\n \t\treturn -EINVAL;\n \n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo) {\n+\t\trcu_read_unlock();\n+\t\treturn 0;\n+\t}\n+\n \tif (is_valid_ether_addr(mac)) {\n \t\tdev_info(&adapter->pdev->dev, \"setting MAC %pM on VF %d\\n\",\n \t\t\t mac, vf);\n@@ -1559,7 +1712,7 @@ int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)\n \n \t\tretval = ixgbe_set_vf_mac(adapter, vf, mac);\n \t\tif (retval >= 0) {\n-\t\t\tadapter->vfinfo[vf].pf_set_mac = true;\n+\t\t\tvfinfo[vf].pf_set_mac = true;\n \n \t\t\tif (test_bit(__IXGBE_DOWN, &adapter->state)) {\n \t\t\t\tdev_warn(&adapter->pdev->dev, \"The VF MAC address has been set, but the PF device is not up.\\n\");\n@@ -1569,18 +1722,19 @@ int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)\n \t\t\tdev_warn(&adapter->pdev->dev, \"The VF MAC address was NOT set due to invalid or duplicate MAC address.\\n\");\n \t\t}\n \t} else if (is_zero_ether_addr(mac)) {\n-\t\tunsigned char *vf_mac_addr =\n-\t\t\t\t\t adapter->vfinfo[vf].vf_mac_addresses;\n+\t\tunsigned char *vf_mac_addr = vfinfo[vf].vf_mac_addresses;\n \n \t\t/* nothing to do */\n-\t\tif (is_zero_ether_addr(vf_mac_addr))\n+\t\tif (is_zero_ether_addr(vf_mac_addr)) {\n+\t\t\trcu_read_unlock();\n \t\t\treturn 0;\n+\t\t}\n \n \t\tdev_info(&adapter->pdev->dev, \"removing MAC on VF %d\\n\", vf);\n \n \t\tretval = ixgbe_del_mac_filter(adapter, vf_mac_addr, vf);\n \t\tif (retval >= 0) {\n-\t\t\tadapter->vfinfo[vf].pf_set_mac = false;\n+\t\t\tvfinfo[vf].pf_set_mac = false;\n \t\t\tmemcpy(vf_mac_addr, mac, ETH_ALEN);\n \t\t} else {\n \t\t\tdev_warn(&adapter->pdev->dev, \"Could NOT remove the VF MAC address.\\n\");\n@@ -1589,10 +1743,12 @@ int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)\n \t\tretval = -EINVAL;\n \t}\n \n+\trcu_read_unlock();\n \treturn retval;\n }\n \n static int ixgbe_enable_port_vlan(struct ixgbe_adapter *adapter, int vf,\n+\t\t\t\t struct vf_data_storage *vfinfo,\n \t\t\t\t u16 vlan, u8 qos)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n@@ -1613,8 +1769,8 @@ static int ixgbe_enable_port_vlan(struct ixgbe_adapter *adapter, int vf,\n \t\tixgbe_write_qde(adapter, vf, IXGBE_QDE_ENABLE |\n \t\t\t\tIXGBE_QDE_HIDE_VLAN);\n \n-\tadapter->vfinfo[vf].pf_vlan = vlan;\n-\tadapter->vfinfo[vf].pf_qos = qos;\n+\tvfinfo[vf].pf_vlan = vlan;\n+\tvfinfo[vf].pf_qos = qos;\n \tdev_info(&adapter->pdev->dev,\n \t\t \"Setting VLAN %d, QOS 0x%x on VF %d\\n\", vlan, qos, vf);\n \tif (test_bit(__IXGBE_DOWN, &adapter->state)) {\n@@ -1628,13 +1784,14 @@ static int ixgbe_enable_port_vlan(struct ixgbe_adapter *adapter, int vf,\n \treturn err;\n }\n \n-static int ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf)\n+static int ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf,\n+\t\t\t\t struct vf_data_storage *vfinfo)\n {\n \tstruct ixgbe_hw *hw = &adapter->hw;\n \tint err;\n \n \terr = ixgbe_set_vf_vlan(adapter, false,\n-\t\t\t\tadapter->vfinfo[vf].pf_vlan, vf);\n+\t\t\t\tvfinfo[vf].pf_vlan, vf);\n \t/* Restore tagless access via VLAN 0 */\n \tixgbe_set_vf_vlan(adapter, true, 0, vf);\n \tixgbe_clear_vmvir(adapter, vf);\n@@ -1644,8 +1801,8 @@ static int ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf)\n \tif (hw->mac.type >= ixgbe_mac_X550)\n \t\tixgbe_write_qde(adapter, vf, IXGBE_QDE_ENABLE);\n \n-\tadapter->vfinfo[vf].pf_vlan = 0;\n-\tadapter->vfinfo[vf].pf_qos = 0;\n+\tvfinfo[vf].pf_vlan = 0;\n+\tvfinfo[vf].pf_qos = 0;\n \n \treturn err;\n }\n@@ -1653,13 +1810,20 @@ static int ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf)\n int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan,\n \t\t\t u8 qos, __be16 vlan_proto)\n {\n-\tint err = 0;\n \tstruct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);\n+\tstruct vf_data_storage *vfinfo;\n+\tint err = 0;\n \n \tif ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7))\n \t\treturn -EINVAL;\n \tif (vlan_proto != htons(ETH_P_8021Q))\n \t\treturn -EPROTONOSUPPORT;\n+\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo)\n+\t\tgoto out;\n+\n \tif (vlan || qos) {\n \t\t/* Check if there is already a port VLAN set, if so\n \t\t * we have to delete the old one first before we\n@@ -1668,16 +1832,17 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan,\n \t\t * old port VLAN before setting a new one but this\n \t\t * is not necessarily the case.\n \t\t */\n-\t\tif (adapter->vfinfo[vf].pf_vlan)\n-\t\t\terr = ixgbe_disable_port_vlan(adapter, vf);\n+\t\tif (vfinfo[vf].pf_vlan)\n+\t\t\terr = ixgbe_disable_port_vlan(adapter, vf, vfinfo);\n \t\tif (err)\n \t\t\tgoto out;\n-\t\terr = ixgbe_enable_port_vlan(adapter, vf, vlan, qos);\n+\t\terr = ixgbe_enable_port_vlan(adapter, vf, vfinfo, vlan, qos);\n \t} else {\n-\t\terr = ixgbe_disable_port_vlan(adapter, vf);\n+\t\terr = ixgbe_disable_port_vlan(adapter, vf, vfinfo);\n \t}\n \n out:\n+\trcu_read_unlock();\n \treturn err;\n }\n \n@@ -1695,13 +1860,13 @@ int ixgbe_link_mbps(struct ixgbe_adapter *adapter)\n \t}\n }\n \n-static void ixgbe_set_vf_rate_limit(struct ixgbe_adapter *adapter, int vf)\n+static void ixgbe_set_vf_rate_limit(struct ixgbe_adapter *adapter, int vf,\n+\t\t\t\t u16 tx_rate)\n {\n \tstruct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];\n \tstruct ixgbe_hw *hw = &adapter->hw;\n \tu32 bcnrc_val = 0;\n \tu16 queue, queues_per_pool;\n-\tu16 tx_rate = adapter->vfinfo[vf].tx_rate;\n \n \tif (tx_rate) {\n \t\t/* start with base link speed value */\n@@ -1749,6 +1914,7 @@ static void ixgbe_set_vf_rate_limit(struct ixgbe_adapter *adapter, int vf)\n \n void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter)\n {\n+\tstruct vf_data_storage *vfinfo;\n \tint i;\n \n \t/* VF Tx rate limit was not set */\n@@ -1761,18 +1927,23 @@ void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter)\n \t\t\t \"Link speed has been changed. VF Transmit rate is disabled\\n\");\n \t}\n \n-\tfor (i = 0; i < adapter->num_vfs; i++) {\n-\t\tif (!adapter->vf_rate_link_speed)\n-\t\t\tadapter->vfinfo[i].tx_rate = 0;\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo)\n+\t\tfor (i = 0; i < adapter->num_vfs; i++) {\n+\t\t\tif (!adapter->vf_rate_link_speed)\n+\t\t\t\tvfinfo[i].tx_rate = 0;\n \n-\t\tixgbe_set_vf_rate_limit(adapter, i);\n-\t}\n+\t\t\tixgbe_set_vf_rate_limit(adapter, i, vfinfo[i].tx_rate);\n+\t\t}\n+\trcu_read_unlock();\n }\n \n int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,\n \t\t\tint max_tx_rate)\n {\n \tstruct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);\n+\tstruct vf_data_storage *vfinfo;\n \tint link_speed;\n \n \t/* verify VF is active */\n@@ -1795,12 +1966,17 @@ int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,\n \tif (max_tx_rate && ((max_tx_rate <= 10) || (max_tx_rate > link_speed)))\n \t\treturn -EINVAL;\n \n-\t/* store values */\n-\tadapter->vf_rate_link_speed = link_speed;\n-\tadapter->vfinfo[vf].tx_rate = max_tx_rate;\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo) {\n+\t\t/* store values */\n+\t\tadapter->vf_rate_link_speed = link_speed;\n+\t\tvfinfo[vf].tx_rate = max_tx_rate;\n \n-\t/* update hardware configuration */\n-\tixgbe_set_vf_rate_limit(adapter, vf);\n+\t\t/* update hardware configuration */\n+\t\tixgbe_set_vf_rate_limit(adapter, vf, vfinfo[vf].tx_rate);\n+\t}\n+\trcu_read_unlock();\n \n \treturn 0;\n }\n@@ -1809,11 +1985,18 @@ int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting)\n {\n \tstruct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);\n \tstruct ixgbe_hw *hw = &adapter->hw;\n+\tstruct vf_data_storage *vfinfo;\n \n \tif (vf >= adapter->num_vfs)\n \t\treturn -EINVAL;\n \n-\tadapter->vfinfo[vf].spoofchk_enabled = setting;\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo)\n+\t\tvfinfo[vf].spoofchk_enabled = setting;\n+\trcu_read_unlock();\n+\tif (!vfinfo)\n+\t\treturn 0;\n \n \t/* configure MAC spoofing */\n \thw->mac.ops.set_mac_anti_spoofing(hw, setting, vf);\n@@ -1851,28 +2034,37 @@ int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting)\n **/\n void ixgbe_set_vf_link_state(struct ixgbe_adapter *adapter, int vf, int state)\n {\n-\tadapter->vfinfo[vf].link_state = state;\n+\tstruct vf_data_storage *vfinfo;\n+\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo) {\n+\t\trcu_read_unlock();\n+\t\treturn;\n+\t}\n+\tvfinfo[vf].link_state = state;\n \n \tswitch (state) {\n \tcase IFLA_VF_LINK_STATE_AUTO:\n \t\tif (test_bit(__IXGBE_DOWN, &adapter->state))\n-\t\t\tadapter->vfinfo[vf].link_enable = false;\n+\t\t\tvfinfo[vf].link_enable = false;\n \t\telse\n-\t\t\tadapter->vfinfo[vf].link_enable = true;\n+\t\t\tvfinfo[vf].link_enable = true;\n \t\tbreak;\n \tcase IFLA_VF_LINK_STATE_ENABLE:\n-\t\tadapter->vfinfo[vf].link_enable = true;\n+\t\tvfinfo[vf].link_enable = true;\n \t\tbreak;\n \tcase IFLA_VF_LINK_STATE_DISABLE:\n-\t\tadapter->vfinfo[vf].link_enable = false;\n+\t\tvfinfo[vf].link_enable = false;\n \t\tbreak;\n \t}\n \n \tixgbe_set_vf_rx_tx(adapter, vf);\n \n \t/* restart the VF */\n-\tadapter->vfinfo[vf].clear_to_send = false;\n+\tvfinfo[vf].clear_to_send = false;\n \tixgbe_ping_vf(adapter, vf);\n+\trcu_read_unlock();\n }\n \n /**\n@@ -1923,6 +2115,7 @@ int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf,\n \t\t\t\t bool setting)\n {\n \tstruct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);\n+\tstruct vf_data_storage *vfinfo;\n \n \t/* This operation is currently supported only for 82599 and x540\n \t * devices.\n@@ -1934,7 +2127,11 @@ int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf,\n \tif (vf >= adapter->num_vfs)\n \t\treturn -EINVAL;\n \n-\tadapter->vfinfo[vf].rss_query_enabled = setting;\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (vfinfo)\n+\t\tvfinfo[vf].rss_query_enabled = setting;\n+\trcu_read_unlock();\n \n \treturn 0;\n }\n@@ -1942,18 +2139,31 @@ int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf,\n int ixgbe_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting)\n {\n \tstruct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);\n+\tstruct vf_data_storage *vfinfo;\n \n \tif (vf >= adapter->num_vfs)\n \t\treturn -EINVAL;\n \n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo) {\n+\t\trcu_read_unlock();\n+\t\treturn 0;\n+\t}\n+\n \t/* nothing to do */\n-\tif (adapter->vfinfo[vf].trusted == setting)\n+\tif (vfinfo[vf].trusted == setting) {\n+\t\trcu_read_unlock();\n \t\treturn 0;\n+\t}\n \n-\tadapter->vfinfo[vf].trusted = setting;\n+\tvfinfo[vf].trusted = setting;\n \n \t/* reset VF to reconfigure features */\n-\tadapter->vfinfo[vf].clear_to_send = false;\n+\tvfinfo[vf].clear_to_send = false;\n+\n+\trcu_read_unlock();\n+\n \tixgbe_ping_vf(adapter, vf);\n \n \te_info(drv, \"VF %u is %strusted\\n\", vf, setting ? \"\" : \"not \");\n@@ -1965,17 +2175,30 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev,\n \t\t\t int vf, struct ifla_vf_info *ivi)\n {\n \tstruct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);\n+\tstruct vf_data_storage *vfinfo;\n+\n \tif (vf >= adapter->num_vfs)\n \t\treturn -EINVAL;\n \tivi->vf = vf;\n-\tmemcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN);\n-\tivi->max_tx_rate = adapter->vfinfo[vf].tx_rate;\n+\n+\trcu_read_lock();\n+\tvfinfo = rcu_dereference(adapter->vfinfo);\n+\tif (!vfinfo) {\n+\t\trcu_read_unlock();\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tmemcpy(&ivi->mac, vfinfo[vf].vf_mac_addresses, ETH_ALEN);\n+\tivi->max_tx_rate = vfinfo[vf].tx_rate;\n \tivi->min_tx_rate = 0;\n-\tivi->vlan = adapter->vfinfo[vf].pf_vlan;\n-\tivi->qos = adapter->vfinfo[vf].pf_qos;\n-\tivi->spoofchk = adapter->vfinfo[vf].spoofchk_enabled;\n-\tivi->rss_query_en = adapter->vfinfo[vf].rss_query_enabled;\n-\tivi->trusted = adapter->vfinfo[vf].trusted;\n-\tivi->linkstate = adapter->vfinfo[vf].link_state;\n+\tivi->vlan = vfinfo[vf].pf_vlan;\n+\tivi->qos = vfinfo[vf].pf_qos;\n+\tivi->spoofchk = vfinfo[vf].spoofchk_enabled;\n+\tivi->rss_query_en = vfinfo[vf].rss_query_enabled;\n+\tivi->trusted = vfinfo[vf].trusted;\n+\tivi->linkstate = vfinfo[vf].link_state;\n+\n+\trcu_read_unlock();\n+\n \treturn 0;\n }\n", "prefixes": [ "net", "v2" ] }