From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
To: davem@davemloft.net
Cc: Jacob Keller <jacob.e.keller@intel.com>,
netdev@vger.kernel.org, nhorman@redhat.com, sassmann@redhat.com,
jogreene@redhat.com, Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Subject: [net-next 07/15] i40e: don't hold spinlock while resetting VF
Date: Mon, 2 Oct 2017 12:48:44 -0700 [thread overview]
Message-ID: <20171002194852.71970-8-jeffrey.t.kirsher@intel.com> (raw)
In-Reply-To: <20171002194852.71970-1-jeffrey.t.kirsher@intel.com>
From: Jacob Keller <jacob.e.keller@intel.com>
When we refactored handling of the PVID in commit 9af52f60b2d9
("i40e: use (add|rm)_vlan_all_mac helper functions when changing PVID")
we introduced a scheduling while atomic regression.
This occurred because we now held the spinlock across a call to
i40e_reset_vf(), which results in a usleep_range() call that triggers
a scheduling while atomic bug. This was rare as it only occurred if the
user configured a VLAN on a VF and also attempted to reconfigure the VF
from the host system with a port VLAN.
We do need to hold the lock while calling i40e_is_vsi_in_vlan(), but we
should not be holding it while we reset the VF.
We'll fix this by introducing a separate helper function
i40e_vsi_has_vlans which checks whether we have a PVID and whether the
VSI has configured VLANs. This helper function will manage its own need
for the mac_filter_hash_lock.
Then, we can move the acquiring of the spinlock until after we reset the
VF, which ensures that we do not sleep while holding the lock.
Using a separate function like this makes the code more clear and is
easier to read than attempting to release and re-acquire the spinlock
when we reset the VF.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 36 +++++++++++++++++++---
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 9e3667fc7f6a..53ead127b293 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -2925,6 +2925,34 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
return ret;
}
+/**
+ * i40e_vsi_has_vlans - True if VSI has configured VLANs
+ * @vsi: pointer to the vsi
+ *
+ * Check if a VSI has configured any VLANs. False if we have a port VLAN or if
+ * we have no configured VLANs. Do not call while holding the
+ * mac_filter_hash_lock.
+ */
+static bool i40e_vsi_has_vlans(struct i40e_vsi *vsi)
+{
+ bool have_vlans;
+
+ /* If we have a port VLAN, then the VSI cannot have any VLANs
+ * configured, as all MAC/VLAN filters will be assigned to the PVID.
+ */
+ if (vsi->info.pvid)
+ return false;
+
+ /* Since we don't have a PVID, we know that if the device is in VLAN
+ * mode it must be because of a VLAN filter configured on this VSI.
+ */
+ spin_lock_bh(&vsi->mac_filter_hash_lock);
+ have_vlans = i40e_is_vsi_in_vlan(vsi);
+ spin_unlock_bh(&vsi->mac_filter_hash_lock);
+
+ return have_vlans;
+}
+
/**
* i40e_ndo_set_vf_port_vlan
* @netdev: network interface device structure
@@ -2977,10 +3005,7 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,
/* duplicate request, so just return success */
goto error_pvid;
- /* Locked once because multiple functions below iterate list */
- spin_lock_bh(&vsi->mac_filter_hash_lock);
-
- if (le16_to_cpu(vsi->info.pvid) == 0 && i40e_is_vsi_in_vlan(vsi)) {
+ if (i40e_vsi_has_vlans(vsi)) {
dev_err(&pf->pdev->dev,
"VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n",
vf_id);
@@ -2993,6 +3018,9 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,
vsi = pf->vsi[vf->lan_vsi_idx];
}
+ /* Locked once because multiple functions below iterate list */
+ spin_lock_bh(&vsi->mac_filter_hash_lock);
+
/* Check for condition where there was already a port VLAN ID
* filter set and now it is being deleted by setting it to zero.
* Additionally check for the condition where there was a port
--
2.14.2
next prev parent reply other threads:[~2017-10-02 19:49 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-02 19:48 [net-next 00/15][pull request] 40GbE Intel Wired LAN Driver Updates 2017-10-02 Jeff Kirsher
2017-10-02 19:48 ` [net-next 01/15] i40e: limit lan queue count in large CPU count machine Jeff Kirsher
2017-10-02 19:48 ` [net-next 02/15] i40e: remove logically dead code Jeff Kirsher
2017-10-02 19:48 ` [net-next 03/15] i40e: Fix a potential NULL pointer dereference Jeff Kirsher
2017-10-02 19:48 ` [net-next 04/15] i40e: Fix reporting of supported link modes Jeff Kirsher
2017-10-02 19:48 ` [net-next 05/15] i40e: Add support for 'ethtool -m' Jeff Kirsher
2017-10-02 19:48 ` [net-next 06/15] i40e: use admin queue for setting LEDs behavior Jeff Kirsher
2017-10-02 19:48 ` Jeff Kirsher [this message]
2017-10-02 19:48 ` [net-next 08/15] i40e: drop i40e_pf *pf from i40e_vc_disable_vf() Jeff Kirsher
2017-10-02 19:48 ` [net-next 09/15] i40e: make use of i40e_vc_disable_vf Jeff Kirsher
2017-10-02 19:48 ` [net-next 10/15] i40e: ensure reset occurs when disabling VF Jeff Kirsher
2017-10-02 19:48 ` [net-next 11/15] i40evf: Enable VF to request an alternate queue allocation Jeff Kirsher
2017-10-02 20:50 ` Yuval Mintz
2017-10-02 21:35 ` Brady, Alan
2017-10-02 19:48 ` [net-next 12/15] i40e: make i40evf_map_rings_to_vectors void Jeff Kirsher
2017-10-02 19:48 ` [net-next 13/15] i40e: fix handling of vf_states variable Jeff Kirsher
2017-10-02 19:48 ` [net-next 14/15] i40e: fix client notify of VF reset Jeff Kirsher
2017-10-02 19:48 ` [net-next 15/15] i40e: Stop dropping 802.1ad tags - eth proto 0x88a8 Jeff Kirsher
2017-10-02 22:17 ` [net-next 00/15][pull request] 40GbE Intel Wired LAN Driver Updates 2017-10-02 David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171002194852.71970-8-jeffrey.t.kirsher@intel.com \
--to=jeffrey.t.kirsher@intel.com \
--cc=davem@davemloft.net \
--cc=jacob.e.keller@intel.com \
--cc=jogreene@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=nhorman@redhat.com \
--cc=sassmann@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox