if (port >= reprs->num_reprs)
                return NULL;
 
-       return reprs->reprs[port];
+       return rcu_dereference(reprs->reprs[port]);
 }
 
 static int
        if (!reprs)
                return 0;
 
-       for (i = 0; i < reprs->num_reprs; i++)
-               if (reprs->reprs[i]) {
-                       struct nfp_repr *repr = netdev_priv(reprs->reprs[i]);
+       for (i = 0; i < reprs->num_reprs; i++) {
+               struct net_device *netdev;
+
+               netdev = nfp_repr_get_locked(app, reprs, i);
+               if (netdev) {
+                       struct nfp_repr *repr = netdev_priv(netdev);
 
                        err = nfp_flower_cmsg_portreify(repr, exists);
                        if (err)
                                return err;
                        count++;
                }
+       }
 
        return count;
 }
                return -ENOMEM;
 
        for (i = 0; i < cnt; i++) {
+               struct net_device *repr;
                struct nfp_port *port;
                u32 port_id;
 
-               reprs->reprs[i] = nfp_repr_alloc(app);
-               if (!reprs->reprs[i]) {
+               repr = nfp_repr_alloc(app);
+               if (!repr) {
                        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, reprs->reprs[i]);
+               port = nfp_port_alloc(app, port_type, repr);
                if (repr_type == NFP_REPR_TYPE_PF) {
                        port->pf_id = i;
                        port->vnic = priv->nn->dp.ctrl_bar;
                                app->pf->vf_cfg_mem + i * NFP_NET_CFG_BAR_SZ;
                }
 
-               eth_hw_addr_random(reprs->reprs[i]);
+               eth_hw_addr_random(repr);
 
                port_id = nfp_flower_cmsg_pcie_port(nfp_pcie, vnic_type,
                                                    i, queue);
-               err = nfp_repr_init(app, reprs->reprs[i],
+               err = nfp_repr_init(app, repr,
                                    port_id, port, priv->nn->dp.netdev);
                if (err) {
                        nfp_port_free(port);
 
                nfp_info(app->cpp, "%s%d Representor(%s) created\n",
                         repr_type == NFP_REPR_TYPE_PF ? "PF" : "VF", i,
-                        reprs->reprs[i]->name);
+                        repr->name);
        }
 
        nfp_app_reprs_set(app, repr_type, reprs);
 err_reprs_remove:
        reprs = nfp_app_reprs_set(app, repr_type, NULL);
 err_reprs_clean:
-       nfp_reprs_clean_and_free(reprs);
+       nfp_reprs_clean_and_free(app, reprs);
        return err;
 }
 
 
        for (i = 0; i < eth_tbl->count; i++) {
                unsigned int phys_port = eth_tbl->ports[i].index;
+               struct net_device *repr;
                struct nfp_port *port;
                u32 cmsg_port_id;
 
-               reprs->reprs[phys_port] = nfp_repr_alloc(app);
-               if (!reprs->reprs[phys_port]) {
+               repr = nfp_repr_alloc(app);
+               if (!repr) {
                        err = -ENOMEM;
                        goto err_reprs_clean;
                }
+               RCU_INIT_POINTER(reprs->reprs[phys_port], repr);
 
-               port = nfp_port_alloc(app, NFP_PORT_PHYS_PORT,
-                                     reprs->reprs[phys_port]);
+               port = nfp_port_alloc(app, NFP_PORT_PHYS_PORT, repr);
                if (IS_ERR(port)) {
                        err = PTR_ERR(port);
                        goto err_reprs_clean;
                        goto err_reprs_clean;
                }
 
-               SET_NETDEV_DEV(reprs->reprs[phys_port], &priv->nn->pdev->dev);
+               SET_NETDEV_DEV(repr, &priv->nn->pdev->dev);
                nfp_net_get_mac_addr(app->pf, port);
 
                cmsg_port_id = nfp_flower_cmsg_phys_port(phys_port);
-               err = nfp_repr_init(app, reprs->reprs[phys_port],
+               err = nfp_repr_init(app, repr,
                                    cmsg_port_id, port, priv->nn->dp.netdev);
                if (err) {
                        nfp_port_free(port);
                                             phys_port);
 
                nfp_info(app->cpp, "Phys Port %d Representor(%s) created\n",
-                        phys_port, reprs->reprs[phys_port]->name);
+                        phys_port, repr->name);
        }
 
        nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, reprs);
 err_reprs_remove:
        reprs = nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, NULL);
 err_reprs_clean:
-       nfp_reprs_clean_and_free(reprs);
+       nfp_reprs_clean_and_free(app, reprs);
 err_free_ctrl_skb:
        kfree_skb(ctrl_skb);
        return err;
 
 #include "nfp_net_sriov.h"
 #include "nfp_port.h"
 
+struct net_device *
+nfp_repr_get_locked(struct nfp_app *app, struct nfp_reprs *set, unsigned int id)
+{
+       return rcu_dereference_protected(set->reprs[id],
+                                        lockdep_is_held(&app->pf->lock));
+}
+
 static void
 nfp_repr_inc_tx_stats(struct net_device *netdev, unsigned int len,
                      int tx_status)
        nfp_repr_free(repr);
 }
 
-void nfp_reprs_clean_and_free(struct nfp_reprs *reprs)
+void nfp_reprs_clean_and_free(struct nfp_app *app, struct nfp_reprs *reprs)
 {
+       struct net_device *netdev;
        unsigned int i;
 
-       for (i = 0; i < reprs->num_reprs; i++)
-               if (reprs->reprs[i])
-                       nfp_repr_clean_and_free(netdev_priv(reprs->reprs[i]));
+       for (i = 0; i < reprs->num_reprs; i++) {
+               netdev = nfp_repr_get_locked(app, reprs, i);
+               if (netdev)
+                       nfp_repr_clean_and_free(netdev_priv(netdev));
+       }
 
        kfree(reprs);
 }
 
 void
-nfp_reprs_clean_and_free_by_type(struct nfp_app *app,
-                                enum nfp_repr_type type)
+nfp_reprs_clean_and_free_by_type(struct nfp_app *app, enum nfp_repr_type type)
 {
+       struct net_device *netdev;
        struct nfp_reprs *reprs;
        int i;
 
        /* Preclean must happen before we remove the reprs reference from the
         * app below.
         */
-       for (i = 0; i < reprs->num_reprs; i++)
-               if (reprs->reprs[i])
-                       nfp_app_repr_preclean(app, reprs->reprs[i]);
+       for (i = 0; i < reprs->num_reprs; i++) {
+               netdev = nfp_repr_get_locked(app, reprs, i);
+               if (netdev)
+                       nfp_app_repr_preclean(app, netdev);
+       }
 
        reprs = nfp_app_reprs_set(app, type, NULL);
 
        synchronize_rcu();
-       nfp_reprs_clean_and_free(reprs);
+       nfp_reprs_clean_and_free(app, reprs);
 }
 
 struct nfp_reprs *nfp_reprs_alloc(unsigned int num_reprs)
 
 int nfp_reprs_resync_phys_ports(struct nfp_app *app)
 {
-       struct nfp_reprs *reprs, *old_reprs;
+       struct net_device *netdev;
+       struct nfp_reprs *reprs;
        struct nfp_repr *repr;
        int i;
 
-       old_reprs = nfp_reprs_get_locked(app, NFP_REPR_TYPE_PHYS_PORT);
-       if (!old_reprs)
-               return 0;
-
-       reprs = nfp_reprs_alloc(old_reprs->num_reprs);
+       reprs = nfp_reprs_get_locked(app, NFP_REPR_TYPE_PHYS_PORT);
        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) {
-                       nfp_app_repr_preclean(app, old_reprs->reprs[i]);
-                       continue;
-               }
-
-               reprs->reprs[i] = old_reprs->reprs[i];
-       }
-
-       old_reprs = nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, reprs);
-       synchronize_rcu();
+               return 0;
 
-       /* Now we free up removed representors */
-       for (i = 0; i < old_reprs->num_reprs; i++) {
-               if (!old_reprs->reprs[i])
+       for (i = 0; i < reprs->num_reprs; i++) {
+               netdev = nfp_repr_get_locked(app, reprs, i);
+               if (!netdev)
                        continue;
 
-               repr = netdev_priv(old_reprs->reprs[i]);
+               repr = netdev_priv(netdev);
                if (repr->port->type != NFP_PORT_INVALID)
                        continue;
 
+               nfp_app_repr_preclean(app, netdev);
+               rcu_assign_pointer(reprs->reprs[i], NULL);
+               synchronize_rcu();
                nfp_repr_clean(repr);
        }
 
-       kfree(old_reprs);
        return 0;
 }
 
 #define NFP_NET_REPR_H
 
 struct metadata_dst;
+struct nfp_app;
 struct nfp_net;
 struct nfp_port;
 
  */
 struct nfp_reprs {
        unsigned int num_reprs;
-       struct net_device *reprs[0];
+       struct net_device __rcu *reprs[0];
 };
 
 /**
        return priv->dst->u.port_info.port_id;
 }
 
+struct net_device *
+nfp_repr_get_locked(struct nfp_app *app, struct nfp_reprs *set,
+                   unsigned int id);
+
 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);
 struct net_device *nfp_repr_alloc(struct nfp_app *app);
-void
-nfp_reprs_clean_and_free(struct nfp_reprs *reprs);
-void
-nfp_reprs_clean_and_free_by_type(struct nfp_app *app,
-                                enum nfp_repr_type type);
+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,
+                                     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);