summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDirk van der Merwe2017-11-04 16:48:57 +0100
committerDavid S. Miller2017-11-05 15:23:26 +0100
commit5fa27d59af2a36c32156e56b6370387f60b67052 (patch)
tree95872ea4d3b135d0375613138f2ccdbab0431875
parentnfp: refactor nfp_app_reprs_set (diff)
downloadkernel-qcow2-linux-5fa27d59af2a36c32156e56b6370387f60b67052.tar.gz
kernel-qcow2-linux-5fa27d59af2a36c32156e56b6370387f60b67052.tar.xz
kernel-qcow2-linux-5fa27d59af2a36c32156e56b6370387f60b67052.zip
nfp: resync repr state when port table sync
If the NSP port table has been refreshed, resync the representor state with the new port information. At the moment, this only entails looking for invalid ports and killing off representors associated with them. The repr instance becomes NULL which is safe since the app accessor function for reprs returns NULL when it cannot access a repr. Signed-off-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com> Signed-off-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_main.c6
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_repr.c47
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_repr.h1
3 files changed, 54 insertions, 0 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
index 0beb9b21557b..c505014121c4 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c
@@ -611,6 +611,7 @@ int nfp_net_refresh_port_table_sync(struct nfp_pf *pf)
struct nfp_eth_table *eth_table;
struct nfp_net *nn, *next;
struct nfp_port *port;
+ int err;
lockdep_assert_held(&pf->lock);
@@ -640,6 +641,11 @@ int nfp_net_refresh_port_table_sync(struct nfp_pf *pf)
kfree(eth_table);
+ /* Resync repr state. This may cause reprs to be removed. */
+ err = nfp_reprs_resync_phys_ports(pf->app);
+ if (err)
+ return err;
+
/* Shoot off the ports which became invalid */
list_for_each_entry_safe(nn, next, &pf->vnics, vnic_list) {
if (!nn->port || nn->port->type != NFP_PORT_INVALID)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
index d540a9dc77b3..1bce8c131bb9 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
@@ -390,3 +390,50 @@ struct nfp_reprs *nfp_reprs_alloc(unsigned int num_reprs)
return reprs;
}
+
+int nfp_reprs_resync_phys_ports(struct nfp_app *app)
+{
+ struct nfp_reprs *reprs, *old_reprs;
+ struct nfp_repr *repr;
+ int i;
+
+ old_reprs =
+ rcu_dereference_protected(app->reprs[NFP_REPR_TYPE_PHYS_PORT],
+ lockdep_is_held(&app->pf->lock));
+ if (!old_reprs)
+ return 0;
+
+ reprs = nfp_reprs_alloc(old_reprs->num_reprs);
+ if (!reprs)
+ return -ENOMEM;
+
+ for (i = 0; i < old_reprs->num_reprs; i++) {
+ if (!old_reprs->reprs[i])
+ continue;
+
+ repr = netdev_priv(old_reprs->reprs[i]);
+ if (repr->port->type == NFP_PORT_INVALID)
+ continue;
+
+ reprs->reprs[i] = old_reprs->reprs[i];
+ }
+
+ old_reprs = nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, reprs);
+ synchronize_rcu();
+
+ /* Now we free up removed representors */
+ for (i = 0; i < old_reprs->num_reprs; i++) {
+ if (!old_reprs->reprs[i])
+ continue;
+
+ repr = netdev_priv(old_reprs->reprs[i]);
+ if (repr->port->type != NFP_PORT_INVALID)
+ continue;
+
+ nfp_app_repr_stop(app, repr);
+ nfp_repr_clean(repr);
+ }
+
+ kfree(old_reprs);
+ return 0;
+}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h
index 32179cad062a..5d4d897bc9c6 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h
@@ -124,5 +124,6 @@ void
nfp_reprs_clean_and_free_by_type(struct nfp_app *app,
enum nfp_repr_type type);
struct nfp_reprs *nfp_reprs_alloc(unsigned int num_reprs);
+int nfp_reprs_resync_phys_ports(struct nfp_app *app);
#endif /* NFP_NET_REPR_H */