Browse Source

Merge branch 'nfp-refactor-app-init-and-minor-flower-fixes'

Jakub Kicinski says:

====================
nfp: refactor app init, and minor flower fixes

This series is a part 2 to what went into net as a simpler fix.
In net we simply moved when existing callbacks are invoked to
ensure flower app does not still use representors when lower
netdev has already been destroyed.  In this series we add a
callback to notify apps when vNIC netdevs are fully initialized
and they are about to be destroyed.  This allows flower to spawn
representors at the right time, while keeping the start/stop
callbacks for what they are intended to be used - FW initialization
over control channel.

Patch 4 improves drop monitor interaction and patch 5 changes
the default Kconfig selection of flower offload.  Patch 6 fixes
locking around representor updates which got lost in net-next.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
David S. Miller 8 years ago
parent
commit
3cf2e08f5a

+ 1 - 0
drivers/net/ethernet/netronome/Kconfig

@@ -29,6 +29,7 @@ config NFP_APP_FLOWER
 	bool "NFP4000/NFP6000 TC Flower offload support"
 	bool "NFP4000/NFP6000 TC Flower offload support"
 	depends on NFP
 	depends on NFP
 	depends on NET_SWITCHDEV
 	depends on NET_SWITCHDEV
+	default y
 	---help---
 	---help---
 	  Enable driver support for TC Flower offload on NFP4000 and NFP6000.
 	  Enable driver support for TC Flower offload on NFP4000 and NFP6000.
 	  Say Y, if you are planning to make use of TC Flower offload
 	  Say Y, if you are planning to make use of TC Flower offload

+ 5 - 5
drivers/net/ethernet/netronome/nfp/bpf/main.c

@@ -84,7 +84,7 @@ static const char *nfp_bpf_extra_cap(struct nfp_app *app, struct nfp_net *nn)
 }
 }
 
 
 static int
 static int
-nfp_bpf_vnic_init(struct nfp_app *app, struct nfp_net *nn, unsigned int id)
+nfp_bpf_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id)
 {
 {
 	struct nfp_net_bpf_priv *priv;
 	struct nfp_net_bpf_priv *priv;
 	int ret;
 	int ret;
@@ -106,14 +106,14 @@ nfp_bpf_vnic_init(struct nfp_app *app, struct nfp_net *nn, unsigned int id)
 	setup_timer(&priv->rx_filter_stats_timer,
 	setup_timer(&priv->rx_filter_stats_timer,
 		    nfp_net_filter_stats_timer, (unsigned long)nn);
 		    nfp_net_filter_stats_timer, (unsigned long)nn);
 
 
-	ret = nfp_app_nic_vnic_init(app, nn, id);
+	ret = nfp_app_nic_vnic_alloc(app, nn, id);
 	if (ret)
 	if (ret)
 		kfree(priv);
 		kfree(priv);
 
 
 	return ret;
 	return ret;
 }
 }
 
 
-static void nfp_bpf_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
+static void nfp_bpf_vnic_free(struct nfp_app *app, struct nfp_net *nn)
 {
 {
 	if (nn->dp.bpf_offload_xdp)
 	if (nn->dp.bpf_offload_xdp)
 		nfp_bpf_xdp_offload(app, nn, NULL);
 		nfp_bpf_xdp_offload(app, nn, NULL);
@@ -149,8 +149,8 @@ const struct nfp_app_type app_bpf = {
 
 
 	.extra_cap	= nfp_bpf_extra_cap,
 	.extra_cap	= nfp_bpf_extra_cap,
 
 
-	.vnic_init	= nfp_bpf_vnic_init,
-	.vnic_clean	= nfp_bpf_vnic_clean,
+	.vnic_alloc	= nfp_bpf_vnic_alloc,
+	.vnic_free	= nfp_bpf_vnic_free,
 
 
 	.setup_tc	= nfp_bpf_setup_tc,
 	.setup_tc	= nfp_bpf_setup_tc,
 	.tc_busy	= nfp_bpf_tc_busy,
 	.tc_busy	= nfp_bpf_tc_busy,

+ 8 - 3
drivers/net/ethernet/netronome/nfp/flower/cmsg.c

@@ -141,12 +141,14 @@ nfp_flower_cmsg_portmod_rx(struct nfp_app *app, struct sk_buff *skb)
 	msg = nfp_flower_cmsg_get_data(skb);
 	msg = nfp_flower_cmsg_get_data(skb);
 	link = msg->info & NFP_FLOWER_CMSG_PORTMOD_INFO_LINK;
 	link = msg->info & NFP_FLOWER_CMSG_PORTMOD_INFO_LINK;
 
 
+	rtnl_lock();
 	rcu_read_lock();
 	rcu_read_lock();
 	netdev = nfp_app_repr_get(app, be32_to_cpu(msg->portnum));
 	netdev = nfp_app_repr_get(app, be32_to_cpu(msg->portnum));
+	rcu_read_unlock();
 	if (!netdev) {
 	if (!netdev) {
 		nfp_flower_cmsg_warn(app, "ctrl msg for unknown port 0x%08x\n",
 		nfp_flower_cmsg_warn(app, "ctrl msg for unknown port 0x%08x\n",
 				     be32_to_cpu(msg->portnum));
 				     be32_to_cpu(msg->portnum));
-		rcu_read_unlock();
+		rtnl_unlock();
 		return;
 		return;
 	}
 	}
 
 
@@ -161,7 +163,7 @@ nfp_flower_cmsg_portmod_rx(struct nfp_app *app, struct sk_buff *skb)
 	} else {
 	} else {
 		netif_carrier_off(netdev);
 		netif_carrier_off(netdev);
 	}
 	}
-	rcu_read_unlock();
+	rtnl_unlock();
 }
 }
 
 
 static void
 static void
@@ -189,8 +191,11 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
 	default:
 	default:
 		nfp_flower_cmsg_warn(app, "Cannot handle invalid repr control type %u\n",
 		nfp_flower_cmsg_warn(app, "Cannot handle invalid repr control type %u\n",
 				     type);
 				     type);
+		goto out;
 	}
 	}
 
 
+	dev_consume_skb_any(skb);
+	return;
 out:
 out:
 	dev_kfree_skb_any(skb);
 	dev_kfree_skb_any(skb);
 }
 }
@@ -203,7 +208,7 @@ void nfp_flower_cmsg_process_rx(struct work_struct *work)
 	priv = container_of(work, struct nfp_flower_priv, cmsg_work);
 	priv = container_of(work, struct nfp_flower_priv, cmsg_work);
 
 
 	while ((skb = skb_dequeue(&priv->cmsg_skbs)))
 	while ((skb = skb_dequeue(&priv->cmsg_skbs)))
-		nfp_flower_cmsg_process_one_rx(priv->nn->app, skb);
+		nfp_flower_cmsg_process_one_rx(priv->app, skb);
 }
 }
 
 
 void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
 void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)

+ 64 - 29
drivers/net/ethernet/netronome/nfp/flower/main.c

@@ -127,6 +127,11 @@ nfp_flower_repr_netdev_stop(struct nfp_app *app, struct nfp_repr *repr)
 
 
 static void nfp_flower_sriov_disable(struct nfp_app *app)
 static void nfp_flower_sriov_disable(struct nfp_app *app)
 {
 {
+	struct nfp_flower_priv *priv = app->priv;
+
+	if (!priv->nn)
+		return;
+
 	nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
 	nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
 }
 }
 
 
@@ -203,18 +208,16 @@ err_reprs_clean:
 
 
 static int nfp_flower_sriov_enable(struct nfp_app *app, int num_vfs)
 static int nfp_flower_sriov_enable(struct nfp_app *app, int num_vfs)
 {
 {
+	struct nfp_flower_priv *priv = app->priv;
+
+	if (!priv->nn)
+		return 0;
+
 	return nfp_flower_spawn_vnic_reprs(app,
 	return nfp_flower_spawn_vnic_reprs(app,
 					   NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
 					   NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
 					   NFP_REPR_TYPE_VF, num_vfs);
 					   NFP_REPR_TYPE_VF, num_vfs);
 }
 }
 
 
-static void nfp_flower_stop(struct nfp_app *app)
-{
-	nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
-	nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
-
-}
-
 static int
 static int
 nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
 nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
 {
 {
@@ -300,31 +303,14 @@ err_free_ctrl_skb:
 	return err;
 	return err;
 }
 }
 
 
-static int nfp_flower_start(struct nfp_app *app)
+static int nfp_flower_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
+				 unsigned int id)
 {
 {
-	int err;
-
-	err = nfp_flower_spawn_phy_reprs(app, app->priv);
-	if (err)
-		return err;
-
-	return nfp_flower_spawn_vnic_reprs(app,
-					   NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF,
-					   NFP_REPR_TYPE_PF, 1);
-}
-
-static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn,
-				unsigned int id)
-{
-	struct nfp_flower_priv *priv = app->priv;
-
 	if (id > 0) {
 	if (id > 0) {
 		nfp_warn(app->cpp, "FlowerNIC doesn't support more than one data vNIC\n");
 		nfp_warn(app->cpp, "FlowerNIC doesn't support more than one data vNIC\n");
 		goto err_invalid_port;
 		goto err_invalid_port;
 	}
 	}
 
 
-	priv->nn = nn;
-
 	eth_hw_addr_random(nn->dp.netdev);
 	eth_hw_addr_random(nn->dp.netdev);
 	netif_keep_dst(nn->dp.netdev);
 	netif_keep_dst(nn->dp.netdev);
 
 
@@ -335,6 +321,55 @@ err_invalid_port:
 	return PTR_ERR_OR_ZERO(nn->port);
 	return PTR_ERR_OR_ZERO(nn->port);
 }
 }
 
 
+static void nfp_flower_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
+{
+	struct nfp_flower_priv *priv = app->priv;
+
+	if (app->pf->num_vfs)
+		nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
+	nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
+	nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
+
+	priv->nn = NULL;
+}
+
+static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn)
+{
+	struct nfp_flower_priv *priv = app->priv;
+	int err;
+
+	priv->nn = nn;
+
+	err = nfp_flower_spawn_phy_reprs(app, app->priv);
+	if (err)
+		goto err_clear_nn;
+
+	err = nfp_flower_spawn_vnic_reprs(app,
+					  NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF,
+					  NFP_REPR_TYPE_PF, 1);
+	if (err)
+		goto err_destroy_reprs_phy;
+
+	if (app->pf->num_vfs) {
+		err = nfp_flower_spawn_vnic_reprs(app,
+						  NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
+						  NFP_REPR_TYPE_VF,
+						  app->pf->num_vfs);
+		if (err)
+			goto err_destroy_reprs_pf;
+	}
+
+	return 0;
+
+err_destroy_reprs_pf:
+	nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
+err_destroy_reprs_phy:
+	nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
+err_clear_nn:
+	priv->nn = NULL;
+	return err;
+}
+
 static int nfp_flower_init(struct nfp_app *app)
 static int nfp_flower_init(struct nfp_app *app)
 {
 {
 	const struct nfp_pf *pf = app->pf;
 	const struct nfp_pf *pf = app->pf;
@@ -374,6 +409,7 @@ static int nfp_flower_init(struct nfp_app *app)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	app->priv = app_priv;
 	app->priv = app_priv;
+	app_priv->app = app;
 	skb_queue_head_init(&app_priv->cmsg_skbs);
 	skb_queue_head_init(&app_priv->cmsg_skbs);
 	INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
 	INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
 
 
@@ -410,14 +446,13 @@ const struct nfp_app_type app_flower = {
 	.init		= nfp_flower_init,
 	.init		= nfp_flower_init,
 	.clean		= nfp_flower_clean,
 	.clean		= nfp_flower_clean,
 
 
+	.vnic_alloc	= nfp_flower_vnic_alloc,
 	.vnic_init	= nfp_flower_vnic_init,
 	.vnic_init	= nfp_flower_vnic_init,
+	.vnic_clean	= nfp_flower_vnic_clean,
 
 
 	.repr_open	= nfp_flower_repr_netdev_open,
 	.repr_open	= nfp_flower_repr_netdev_open,
 	.repr_stop	= nfp_flower_repr_netdev_stop,
 	.repr_stop	= nfp_flower_repr_netdev_stop,
 
 
-	.start		= nfp_flower_start,
-	.stop		= nfp_flower_stop,
-
 	.ctrl_msg_rx	= nfp_flower_cmsg_rx,
 	.ctrl_msg_rx	= nfp_flower_cmsg_rx,
 
 
 	.sriov_enable	= nfp_flower_sriov_enable,
 	.sriov_enable	= nfp_flower_sriov_enable,

+ 2 - 0
drivers/net/ethernet/netronome/nfp/flower/main.h

@@ -72,6 +72,7 @@ struct nfp_fl_stats_id {
 
 
 /**
 /**
  * struct nfp_flower_priv - Flower APP per-vNIC priv data
  * struct nfp_flower_priv - Flower APP per-vNIC priv data
+ * @app:		Back pointer to app
  * @nn:			Pointer to vNIC
  * @nn:			Pointer to vNIC
  * @mask_id_seed:	Seed used for mask hash table
  * @mask_id_seed:	Seed used for mask hash table
  * @flower_version:	HW version of flower
  * @flower_version:	HW version of flower
@@ -83,6 +84,7 @@ struct nfp_fl_stats_id {
  * @cmsg_skbs:		List of skbs for control message processing
  * @cmsg_skbs:		List of skbs for control message processing
  */
  */
 struct nfp_flower_priv {
 struct nfp_flower_priv {
+	struct nfp_app *app;
 	struct nfp_net *nn;
 	struct nfp_net *nn;
 	u32 mask_id_seed;
 	u32 mask_id_seed;
 	u64 flower_version;
 	u64 flower_version;

+ 1 - 1
drivers/net/ethernet/netronome/nfp/nfp_app.c

@@ -125,7 +125,7 @@ struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id)
 		return ERR_PTR(-EINVAL);
 		return ERR_PTR(-EINVAL);
 	}
 	}
 
 
-	if (WARN_ON(!apps[i]->name || !apps[i]->vnic_init))
+	if (WARN_ON(!apps[i]->name || !apps[i]->vnic_alloc))
 		return ERR_PTR(-EINVAL);
 		return ERR_PTR(-EINVAL);
 
 
 	app = kzalloc(sizeof(*app), GFP_KERNEL);
 	app = kzalloc(sizeof(*app), GFP_KERNEL);

+ 26 - 9
drivers/net/ethernet/netronome/nfp/nfp_app.h

@@ -69,8 +69,10 @@ extern const struct nfp_app_type app_flower;
  * @init:	perform basic app checks and init
  * @init:	perform basic app checks and init
  * @clean:	clean app state
  * @clean:	clean app state
  * @extra_cap:	extra capabilities string
  * @extra_cap:	extra capabilities string
- * @vnic_init:	init vNICs (assign port types, etc.)
- * @vnic_clean:	clean up app's vNIC state
+ * @vnic_alloc:	allocate vNICs (assign port types, etc.)
+ * @vnic_free:	free up app's vNIC state
+ * @vnic_init:	vNIC netdev was registered
+ * @vnic_clean:	vNIC netdev about to be unregistered
  * @repr_open:	representor netdev open callback
  * @repr_open:	representor netdev open callback
  * @repr_stop:	representor netdev stop callback
  * @repr_stop:	representor netdev stop callback
  * @start:	start application logic
  * @start:	start application logic
@@ -95,8 +97,10 @@ struct nfp_app_type {
 
 
 	const char *(*extra_cap)(struct nfp_app *app, struct nfp_net *nn);
 	const char *(*extra_cap)(struct nfp_app *app, struct nfp_net *nn);
 
 
-	int (*vnic_init)(struct nfp_app *app, struct nfp_net *nn,
-			 unsigned int id);
+	int (*vnic_alloc)(struct nfp_app *app, struct nfp_net *nn,
+			  unsigned int id);
+	void (*vnic_free)(struct nfp_app *app, struct nfp_net *nn);
+	int (*vnic_init)(struct nfp_app *app, struct nfp_net *nn);
 	void (*vnic_clean)(struct nfp_app *app, struct nfp_net *nn);
 	void (*vnic_clean)(struct nfp_app *app, struct nfp_net *nn);
 
 
 	int (*repr_open)(struct nfp_app *app, struct nfp_repr *repr);
 	int (*repr_open)(struct nfp_app *app, struct nfp_repr *repr);
@@ -157,10 +161,23 @@ static inline void nfp_app_clean(struct nfp_app *app)
 		app->type->clean(app);
 		app->type->clean(app);
 }
 }
 
 
-static inline int nfp_app_vnic_init(struct nfp_app *app, struct nfp_net *nn,
-				    unsigned int id)
+static inline int nfp_app_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
+				     unsigned int id)
 {
 {
-	return app->type->vnic_init(app, nn, id);
+	return app->type->vnic_alloc(app, nn, id);
+}
+
+static inline void nfp_app_vnic_free(struct nfp_app *app, struct nfp_net *nn)
+{
+	if (app->type->vnic_free)
+		app->type->vnic_free(app, nn);
+}
+
+static inline int nfp_app_vnic_init(struct nfp_app *app, struct nfp_net *nn)
+{
+	if (!app->type->vnic_init)
+		return 0;
+	return app->type->vnic_init(app, nn);
 }
 }
 
 
 static inline void nfp_app_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
 static inline void nfp_app_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
@@ -308,7 +325,7 @@ void nfp_app_free(struct nfp_app *app);
 
 
 /* Callbacks shared between apps */
 /* Callbacks shared between apps */
 
 
-int nfp_app_nic_vnic_init(struct nfp_app *app, struct nfp_net *nn,
-			  unsigned int id);
+int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
+			   unsigned int id);
 
 
 #endif
 #endif

+ 2 - 2
drivers/net/ethernet/netronome/nfp/nfp_app_nic.c

@@ -60,8 +60,8 @@ nfp_app_nic_vnic_init_phy_port(struct nfp_pf *pf, struct nfp_app *app,
 	return nn->port->type == NFP_PORT_INVALID;
 	return nn->port->type == NFP_PORT_INVALID;
 }
 }
 
 
-int nfp_app_nic_vnic_init(struct nfp_app *app, struct nfp_net *nn,
-			  unsigned int id)
+int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
+			   unsigned int id)
 {
 {
 	int err;
 	int err;
 
 

+ 1 - 1
drivers/net/ethernet/netronome/nfp/nfp_net_common.c

@@ -991,7 +991,7 @@ static void nfp_net_tx_complete(struct nfp_net_tx_ring *tx_ring)
 
 
 		/* check for last gather fragment */
 		/* check for last gather fragment */
 		if (fidx == nr_frags - 1)
 		if (fidx == nr_frags - 1)
-			dev_kfree_skb_any(skb);
+			dev_consume_skb_any(skb);
 
 
 		tx_ring->txbufs[idx].dma_addr = 0;
 		tx_ring->txbufs[idx].dma_addr = 0;
 		tx_ring->txbufs[idx].skb = NULL;
 		tx_ring->txbufs[idx].skb = NULL;

+ 25 - 17
drivers/net/ethernet/netronome/nfp/nfp_net_main.c

@@ -161,6 +161,8 @@ nfp_net_pf_map_rtsym(struct nfp_pf *pf, const char *name, const char *sym_fmt,
 
 
 static void nfp_net_pf_free_vnic(struct nfp_pf *pf, struct nfp_net *nn)
 static void nfp_net_pf_free_vnic(struct nfp_pf *pf, struct nfp_net *nn)
 {
 {
+	if (nfp_net_is_data_vnic(nn))
+		nfp_app_vnic_free(pf->app, nn);
 	nfp_port_free(nn->port);
 	nfp_port_free(nn->port);
 	list_del(&nn->vnic_list);
 	list_del(&nn->vnic_list);
 	pf->num_vnics--;
 	pf->num_vnics--;
@@ -205,7 +207,7 @@ nfp_net_pf_alloc_vnic(struct nfp_pf *pf, bool needs_netdev,
 	nn->stride_tx = stride;
 	nn->stride_tx = stride;
 
 
 	if (needs_netdev) {
 	if (needs_netdev) {
-		err = nfp_app_vnic_init(pf->app, nn, id);
+		err = nfp_app_vnic_alloc(pf->app, nn, id);
 		if (err) {
 		if (err) {
 			nfp_net_free(nn);
 			nfp_net_free(nn);
 			return ERR_PTR(err);
 			return ERR_PTR(err);
@@ -243,8 +245,17 @@ nfp_net_pf_init_vnic(struct nfp_pf *pf, struct nfp_net *nn, unsigned int id)
 
 
 	nfp_net_info(nn);
 	nfp_net_info(nn);
 
 
+	if (nfp_net_is_data_vnic(nn)) {
+		err = nfp_app_vnic_init(pf->app, nn);
+		if (err)
+			goto err_devlink_port_clean;
+	}
+
 	return 0;
 	return 0;
 
 
+err_devlink_port_clean:
+	if (nn->port)
+		nfp_devlink_port_unregister(nn->port);
 err_dfs_clean:
 err_dfs_clean:
 	nfp_net_debugfs_dir_clean(&nn->debugfs_dir);
 	nfp_net_debugfs_dir_clean(&nn->debugfs_dir);
 	nfp_net_clean(nn);
 	nfp_net_clean(nn);
@@ -288,11 +299,12 @@ err_free_prev:
 
 
 static void nfp_net_pf_clean_vnic(struct nfp_pf *pf, struct nfp_net *nn)
 static void nfp_net_pf_clean_vnic(struct nfp_pf *pf, struct nfp_net *nn)
 {
 {
+	if (nfp_net_is_data_vnic(nn))
+		nfp_app_vnic_clean(pf->app, nn);
 	if (nn->port)
 	if (nn->port)
 		nfp_devlink_port_unregister(nn->port);
 		nfp_devlink_port_unregister(nn->port);
 	nfp_net_debugfs_dir_clean(&nn->debugfs_dir);
 	nfp_net_debugfs_dir_clean(&nn->debugfs_dir);
 	nfp_net_clean(nn);
 	nfp_net_clean(nn);
-	nfp_app_vnic_clean(pf->app, nn);
 }
 }
 
 
 static int nfp_net_pf_alloc_irqs(struct nfp_pf *pf)
 static int nfp_net_pf_alloc_irqs(struct nfp_pf *pf)
@@ -457,10 +469,14 @@ static int nfp_net_pf_app_start(struct nfp_pf *pf)
 {
 {
 	int err;
 	int err;
 
 
-	err = nfp_app_start(pf->app, pf->ctrl_vnic);
+	err = nfp_net_pf_app_start_ctrl(pf);
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
+	err = nfp_app_start(pf->app, pf->ctrl_vnic);
+	if (err)
+		goto err_ctrl_stop;
+
 	if (pf->num_vfs) {
 	if (pf->num_vfs) {
 		err = nfp_app_sriov_enable(pf->app, pf->num_vfs);
 		err = nfp_app_sriov_enable(pf->app, pf->num_vfs);
 		if (err)
 		if (err)
@@ -471,6 +487,8 @@ static int nfp_net_pf_app_start(struct nfp_pf *pf)
 
 
 err_app_stop:
 err_app_stop:
 	nfp_app_stop(pf->app);
 	nfp_app_stop(pf->app);
+err_ctrl_stop:
+	nfp_net_pf_app_stop_ctrl(pf);
 	return err;
 	return err;
 }
 }
 
 
@@ -479,6 +497,7 @@ static void nfp_net_pf_app_stop(struct nfp_pf *pf)
 	if (pf->num_vfs)
 	if (pf->num_vfs)
 		nfp_app_sriov_disable(pf->app);
 		nfp_app_sriov_disable(pf->app);
 	nfp_app_stop(pf->app);
 	nfp_app_stop(pf->app);
+	nfp_net_pf_app_stop_ctrl(pf);
 }
 }
 
 
 static void nfp_net_pci_unmap_mem(struct nfp_pf *pf)
 static void nfp_net_pci_unmap_mem(struct nfp_pf *pf)
@@ -570,7 +589,7 @@ err_unmap_ctrl:
 
 
 static void nfp_net_pci_remove_finish(struct nfp_pf *pf)
 static void nfp_net_pci_remove_finish(struct nfp_pf *pf)
 {
 {
-	nfp_net_pf_app_stop_ctrl(pf);
+	nfp_net_pf_app_stop(pf);
 	/* stop app first, to avoid double free of ctrl vNIC's ddir */
 	/* stop app first, to avoid double free of ctrl vNIC's ddir */
 	nfp_net_debugfs_dir_clean(&pf->ddir);
 	nfp_net_debugfs_dir_clean(&pf->ddir);
 
 
@@ -701,7 +720,6 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
 {
 {
 	struct nfp_net_fw_version fw_ver;
 	struct nfp_net_fw_version fw_ver;
 	u8 __iomem *ctrl_bar, *qc_bar;
 	u8 __iomem *ctrl_bar, *qc_bar;
-	struct nfp_net *nn;
 	int stride;
 	int stride;
 	int err;
 	int err;
 
 
@@ -778,7 +796,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
 	if (err)
 	if (err)
 		goto err_free_vnics;
 		goto err_free_vnics;
 
 
-	err = nfp_net_pf_app_start_ctrl(pf);
+	err = nfp_net_pf_app_start(pf);
 	if (err)
 	if (err)
 		goto err_free_irqs;
 		goto err_free_irqs;
 
 
@@ -786,20 +804,12 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
 	if (err)
 	if (err)
 		goto err_stop_app;
 		goto err_stop_app;
 
 
-	err = nfp_net_pf_app_start(pf);
-	if (err)
-		goto err_clean_vnics;
-
 	mutex_unlock(&pf->lock);
 	mutex_unlock(&pf->lock);
 
 
 	return 0;
 	return 0;
 
 
-err_clean_vnics:
-	list_for_each_entry(nn, &pf->vnics, vnic_list)
-		if (nfp_net_is_data_vnic(nn))
-			nfp_net_pf_clean_vnic(pf, nn);
 err_stop_app:
 err_stop_app:
-	nfp_net_pf_app_stop_ctrl(pf);
+	nfp_net_pf_app_stop(pf);
 err_free_irqs:
 err_free_irqs:
 	nfp_net_pf_free_irqs(pf);
 	nfp_net_pf_free_irqs(pf);
 err_free_vnics:
 err_free_vnics:
@@ -823,8 +833,6 @@ void nfp_net_pci_remove(struct nfp_pf *pf)
 	if (list_empty(&pf->vnics))
 	if (list_empty(&pf->vnics))
 		goto out;
 		goto out;
 
 
-	nfp_net_pf_app_stop(pf);
-
 	list_for_each_entry(nn, &pf->vnics, vnic_list)
 	list_for_each_entry(nn, &pf->vnics, vnic_list)
 		if (nfp_net_is_data_vnic(nn))
 		if (nfp_net_is_data_vnic(nn))
 			nfp_net_pf_clean_vnic(pf, nn);
 			nfp_net_pf_clean_vnic(pf, nn);

+ 1 - 1
drivers/net/ethernet/netronome/nfp/nic/main.c

@@ -63,7 +63,7 @@ const struct nfp_app_type app_nic = {
 	.name		= "nic",
 	.name		= "nic",
 
 
 	.init		= nfp_nic_init,
 	.init		= nfp_nic_init,
-	.vnic_init	= nfp_app_nic_vnic_init,
+	.vnic_alloc	= nfp_app_nic_vnic_alloc,
 
 
 	.sriov_enable	= nfp_nic_sriov_enable,
 	.sriov_enable	= nfp_nic_sriov_enable,
 	.sriov_disable	= nfp_nic_sriov_disable,
 	.sriov_disable	= nfp_nic_sriov_disable,