Skip to content

Commit

Permalink
nfp: add mutex protection for the port list
Browse files Browse the repository at this point in the history
We will want to unregister netdevs after their port got reconfigured.
For that we need to make sure manipulations of port list from the
port reconfiguration flow will not race with driver's .remove()
callback.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jakub Kicinski authored and David S. Miller committed Apr 5, 2017
1 parent b9de007 commit d12537d
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 4 deletions.
3 changes: 1 addition & 2 deletions drivers/net/ethernet/netronome/nfp/nfp_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,7 @@ static void nfp_pci_remove(struct pci_dev *pdev)
{
struct nfp_pf *pf = pci_get_drvdata(pdev);

if (!list_empty(&pf->ports))
nfp_net_pci_remove(pf);
nfp_net_pci_remove(pf);

nfp_pcie_sriov_disable(pdev);

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/netronome/nfp/nfp_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <linux/list.h>
#include <linux/types.h>
#include <linux/msi.h>
#include <linux/mutex.h>
#include <linux/pci.h>

struct dentry;
Expand All @@ -67,6 +68,7 @@ struct nfp_eth_table;
* @num_ports: Number of adapter ports app firmware supports
* @num_netdevs: Number of netdevs spawned
* @ports: Linked list of port structures (struct nfp_net)
* @port_lock: Protects @ports, @num_ports, @num_netdevs
*/
struct nfp_pf {
struct pci_dev *pdev;
Expand All @@ -92,6 +94,7 @@ struct nfp_pf {
unsigned int num_netdevs;

struct list_head ports;
struct mutex port_lock;
};

extern struct pci_driver nfp_netvf_pci_driver;
Expand Down
19 changes: 17 additions & 2 deletions drivers/net/ethernet/netronome/nfp/nfp_net_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,17 +481,22 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
int stride;
int err;

mutex_init(&pf->port_lock);

/* Verify that the board has completed initialization */
if (!nfp_is_ready(pf->cpp)) {
nfp_err(pf->cpp, "NFP is not ready for NIC operation.\n");
return -EINVAL;
}

mutex_lock(&pf->port_lock);
pf->num_ports = nfp_net_pf_get_num_ports(pf);

ctrl_bar = nfp_net_pf_map_ctrl_bar(pf);
if (!ctrl_bar)
return pf->fw_loaded ? -EINVAL : -EPROBE_DEFER;
if (!ctrl_bar) {
err = pf->fw_loaded ? -EINVAL : -EPROBE_DEFER;
goto err_unlock;
}

nfp_net_get_fw_version(&fw_ver, ctrl_bar);
if (fw_ver.resv || fw_ver.class != NFP_NET_CFG_VERSION_CLASS_GENERIC) {
Expand Down Expand Up @@ -565,6 +570,8 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
if (err)
goto err_clean_ddir;

mutex_unlock(&pf->port_lock);

return 0;

err_clean_ddir:
Expand All @@ -574,13 +581,19 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
nfp_cpp_area_release_free(pf->tx_area);
err_ctrl_unmap:
nfp_cpp_area_release_free(pf->ctrl_area);
err_unlock:
mutex_unlock(&pf->port_lock);
return err;
}

void nfp_net_pci_remove(struct nfp_pf *pf)
{
struct nfp_net *nn;

mutex_lock(&pf->port_lock);
if (list_empty(&pf->ports))
goto out;

list_for_each_entry(nn, &pf->ports, port_list) {
nfp_net_debugfs_dir_clean(&nn->debugfs_dir);

Expand All @@ -597,4 +610,6 @@ void nfp_net_pci_remove(struct nfp_pf *pf)
nfp_cpp_area_release_free(pf->rx_area);
nfp_cpp_area_release_free(pf->tx_area);
nfp_cpp_area_release_free(pf->ctrl_area);
out:
mutex_unlock(&pf->port_lock);
}

0 comments on commit d12537d

Please sign in to comment.