nfp: flower: fix error path during representor creation
authorJiri Pirko <jiri@mellanox.com>
Thu, 17 May 2018 10:06:43 +0000 (12:06 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 17 May 2018 20:23:29 +0000 (16:23 -0400)
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>
drivers/net/ethernet/netronome/nfp/flower/main.c
drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
drivers/net/ethernet/netronome/nfp/nfp_net_repr.h

index 84e3b9f5abb149a28016a0ad7df09d78f96c7a60..4e67c0cbf9f08ce7c5c6e131130f382f57bb45c5 100644 (file)
@@ -247,12 +247,16 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
                        err = -ENOMEM;
                        goto err_reprs_clean;
                }
                        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);
 
                /* 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;
                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);
                                    port_id, port, priv->nn->dp.netdev);
                if (err) {
                        nfp_port_free(port);
+                       nfp_repr_free(repr);
                        goto err_reprs_clean;
                }
 
                        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);
                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;
                }
                        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);
 
                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);
                        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;
                }
 
                        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);
                                    cmsg_port_id, port, priv->nn->dp.netdev);
                if (err) {
                        nfp_port_free(port);
+                       nfp_repr_free(repr);
                        goto err_reprs_clean;
                }
 
                        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);
 
                                             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);
        }
                nfp_info(app->cpp, "Phys Port %d Representor(%s) created\n",
                         phys_port, repr->name);
        }
index 0cd077addb26a5bd666a15d3d1c361186d8f8678..6e79da91e475d3fccf99989ece63a865cfbea160 100644 (file)
@@ -348,12 +348,17 @@ err_clean:
        return err;
 }
 
        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);
 }
 
 {
        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;
 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_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)
 }
 
 void nfp_reprs_clean_and_free(struct nfp_app *app, struct nfp_reprs *reprs)
index a621e8ff528e322f59ceef2aa4252c4ac6325297..cd756a15445f29e777c43de80b1879bb596f150e 100644 (file)
@@ -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);
 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,
 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,