diff options
author | Jiri Pirko <jiri@mellanox.com> | 2018-05-17 12:06:43 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-05-17 16:23:29 -0400 |
commit | 3b734ff604d32e3e1d7db877d801818967ad325f (patch) | |
tree | 94e4b4efbfe94058b2ef64c0d05b6a6b5ff5c2d9 | |
parent | 6d9f868fc7d3b3137638895d659b986a49253a7d (diff) | |
download | op-kernel-dev-3b734ff604d32e3e1d7db877d801818967ad325f.zip op-kernel-dev-3b734ff604d32e3e1d7db877d801818967ad325f.tar.gz |
nfp: flower: fix error path during representor creation
Don't store repr pointer to reprs array until the representor is
successfully created. This avoids message about "representor
destruction" even when it was never created. Also it cleans-up the flow.
Also, check return value after port alloc.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/flower/main.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_repr.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_net_repr.h | 1 |
3 files changed, 19 insertions, 4 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index 84e3b9f..4e67c0c 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c @@ -247,12 +247,16 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app, err = -ENOMEM; goto err_reprs_clean; } - RCU_INIT_POINTER(reprs->reprs[i], repr); /* For now we only support 1 PF */ WARN_ON(repr_type == NFP_REPR_TYPE_PF && i); port = nfp_port_alloc(app, port_type, repr); + if (IS_ERR(port)) { + err = PTR_ERR(port); + nfp_repr_free(repr); + goto err_reprs_clean; + } if (repr_type == NFP_REPR_TYPE_PF) { port->pf_id = i; port->vnic = priv->nn->dp.ctrl_bar; @@ -271,9 +275,11 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app, port_id, port, priv->nn->dp.netdev); if (err) { nfp_port_free(port); + nfp_repr_free(repr); goto err_reprs_clean; } + RCU_INIT_POINTER(reprs->reprs[i], repr); nfp_info(app->cpp, "%s%d Representor(%s) created\n", repr_type == NFP_REPR_TYPE_PF ? "PF" : "VF", i, repr->name); @@ -344,16 +350,17 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv) err = -ENOMEM; goto err_reprs_clean; } - RCU_INIT_POINTER(reprs->reprs[phys_port], repr); port = nfp_port_alloc(app, NFP_PORT_PHYS_PORT, repr); if (IS_ERR(port)) { err = PTR_ERR(port); + nfp_repr_free(repr); goto err_reprs_clean; } err = nfp_port_init_phy_port(app->pf, app, port, i); if (err) { nfp_port_free(port); + nfp_repr_free(repr); goto err_reprs_clean; } @@ -365,6 +372,7 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv) cmsg_port_id, port, priv->nn->dp.netdev); if (err) { nfp_port_free(port); + nfp_repr_free(repr); goto err_reprs_clean; } @@ -373,6 +381,7 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv) eth_tbl->ports[i].base, phys_port); + RCU_INIT_POINTER(reprs->reprs[phys_port], repr); nfp_info(app->cpp, "Phys Port %d Representor(%s) created\n", phys_port, repr->name); } diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c index 0cd077a..6e79da9 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c @@ -348,12 +348,17 @@ err_clean: return err; } -static void nfp_repr_free(struct nfp_repr *repr) +static void __nfp_repr_free(struct nfp_repr *repr) { free_percpu(repr->stats); free_netdev(repr->netdev); } +void nfp_repr_free(struct net_device *netdev) +{ + __nfp_repr_free(netdev_priv(netdev)); +} + struct net_device *nfp_repr_alloc(struct nfp_app *app) { struct net_device *netdev; @@ -385,7 +390,7 @@ static void nfp_repr_clean_and_free(struct nfp_repr *repr) nfp_info(repr->app->cpp, "Destroying Representor(%s)\n", repr->netdev->name); nfp_repr_clean(repr); - nfp_repr_free(repr); + __nfp_repr_free(repr); } void nfp_reprs_clean_and_free(struct nfp_app *app, struct nfp_reprs *reprs) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h index a621e8f..cd756a1 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.h @@ -123,6 +123,7 @@ void nfp_repr_inc_rx_stats(struct net_device *netdev, unsigned int len); int nfp_repr_init(struct nfp_app *app, struct net_device *netdev, u32 cmsg_port_id, struct nfp_port *port, struct net_device *pf_netdev); +void nfp_repr_free(struct net_device *netdev); struct net_device *nfp_repr_alloc(struct nfp_app *app); void nfp_reprs_clean_and_free(struct nfp_app *app, struct nfp_reprs *reprs); void nfp_reprs_clean_and_free_by_type(struct nfp_app *app, |