ice: make representor code generic
authorMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tue, 24 Oct 2023 11:09:22 +0000 (13:09 +0200)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Mon, 13 Nov 2023 19:42:14 +0000 (11:42 -0800)
Representor code needs to be independent from specific device type, like
in this case VF. Make generic add / remove representor function and
specific add VF / rem VF function. New device types will follow this
scheme.

In bridge offload code there is a need to get representor pointer based
on VSI. Implement helper function to achieve that.

Reviewed-by: Piotr Raczynski <piotr.raczynski@intel.com>
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ice/ice_eswitch.c
drivers/net/ethernet/intel/ice/ice_eswitch.h
drivers/net/ethernet/intel/ice/ice_eswitch_br.c
drivers/net/ethernet/intel/ice/ice_lib.c
drivers/net/ethernet/intel/ice/ice_repr.c
drivers/net/ethernet/intel/ice/ice_repr.h
drivers/net/ethernet/intel/ice/ice_vf_lib.c
drivers/net/ethernet/intel/ice/ice_vf_lib.h

index 66cbe2c80fea33c3c1fbe95887fb6322036162c8..67231e43ffa66fd27f3e6aeb655725cb8bdc9f07 100644 (file)
@@ -285,17 +285,22 @@ err:
 
 /**
  * ice_eswitch_update_repr - reconfigure port representor
- * @repr: pointer to repr struct
+ * @repr_id: representor ID
  * @vsi: VSI for which port representor is configured
  */
-void ice_eswitch_update_repr(struct ice_repr *repr, struct ice_vsi *vsi)
+void ice_eswitch_update_repr(unsigned long repr_id, struct ice_vsi *vsi)
 {
        struct ice_pf *pf = vsi->back;
+       struct ice_repr *repr;
        int ret;
 
        if (!ice_is_switchdev_running(pf))
                return;
 
+       repr = xa_load(&pf->eswitch.reprs, repr_id);
+       if (!repr)
+               return;
+
        repr->src_vsi = vsi;
        repr->dst->u.port_info.port_id = vsi->vsi_num;
 
index f43db1cce3ad85d4d62b90555bb2d5612ce9cd90..ff110bd9fc4c79402a65b44b8905d66a7edf9ffa 100644 (file)
@@ -17,7 +17,7 @@ ice_eswitch_mode_set(struct devlink *devlink, u16 mode,
                     struct netlink_ext_ack *extack);
 bool ice_is_eswitch_mode_switchdev(struct ice_pf *pf);
 
-void ice_eswitch_update_repr(struct ice_repr *repr, struct ice_vsi *vsi);
+void ice_eswitch_update_repr(unsigned long repr_id, struct ice_vsi *vsi);
 
 void ice_eswitch_stop_all_tx_queues(struct ice_pf *pf);
 
@@ -35,7 +35,7 @@ ice_eswitch_set_target_vsi(struct sk_buff *skb,
                           struct ice_tx_offload_params *off) { }
 
 static inline void
-ice_eswitch_update_repr(struct ice_repr *repr, struct ice_vsi *vsi) { }
+ice_eswitch_update_repr(unsigned long repr_id, struct ice_vsi *vsi) { }
 
 static inline int ice_eswitch_configure(struct ice_pf *pf)
 {
index 16bbcaca8fda46753e7322930534b2726dfade4c..ac5beecd028b53e6796c688184e419cf49d445d5 100644 (file)
@@ -893,10 +893,14 @@ ice_eswitch_br_port_deinit(struct ice_esw_br *bridge,
                        ice_eswitch_br_fdb_entry_delete(bridge, fdb_entry);
        }
 
-       if (br_port->type == ICE_ESWITCH_BR_UPLINK_PORT && vsi->back)
+       if (br_port->type == ICE_ESWITCH_BR_UPLINK_PORT && vsi->back) {
                vsi->back->br_port = NULL;
-       else if (vsi->vf && vsi->vf->repr)
-               vsi->vf->repr->br_port = NULL;
+       } else {
+               struct ice_repr *repr = ice_repr_get_by_vsi(vsi);
+
+               if (repr)
+                       repr->br_port = NULL;
+       }
 
        xa_erase(&bridge->ports, br_port->vsi_idx);
        ice_eswitch_br_port_vlans_flush(br_port);
index 4b1e56396293a40098ee9956241e3536efd6074e..ae4b4220e1bb33230b05642e649ad5dc6aa75ba7 100644 (file)
@@ -519,16 +519,14 @@ static irqreturn_t ice_eswitch_msix_clean_rings(int __always_unused irq, void *d
 {
        struct ice_q_vector *q_vector = (struct ice_q_vector *)data;
        struct ice_pf *pf = q_vector->vsi->back;
-       struct ice_vf *vf;
-       unsigned int bkt;
+       struct ice_repr *repr;
+       unsigned long id;
 
        if (!q_vector->tx.tx_ring && !q_vector->rx.rx_ring)
                return IRQ_HANDLED;
 
-       rcu_read_lock();
-       ice_for_each_vf_rcu(pf, bkt, vf)
-               napi_schedule(&vf->repr->q_vector->napi);
-       rcu_read_unlock();
+       xa_for_each(&pf->eswitch.reprs, id, repr)
+               napi_schedule(&repr->q_vector->napi);
 
        return IRQ_HANDLED;
 }
index 77cc77ab826aaa8b924049f335624a747ed88a06..fce25472d05300f2d5cc761aeefa3219af48a369 100644 (file)
@@ -14,7 +14,7 @@
  */
 static int ice_repr_get_sw_port_id(struct ice_repr *repr)
 {
-       return repr->vf->pf->hw.port_info->lport;
+       return repr->src_vsi->back->hw.port_info->lport;
 }
 
 /**
@@ -35,7 +35,7 @@ ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len)
                return -EOPNOTSUPP;
 
        res = snprintf(buf, len, "pf%dvfr%d", ice_repr_get_sw_port_id(repr),
-                      repr->vf->vf_id);
+                      repr->id);
        if (res <= 0)
                return -EOPNOTSUPP;
        return 0;
@@ -279,24 +279,72 @@ ice_repr_reg_netdev(struct net_device *netdev)
 }
 
 /**
- * ice_repr_add - add representor for VF
- * @vf: pointer to VF structure
+ * ice_repr_rem - remove representor from VF
+ * @reprs: xarray storing representors
+ * @repr: pointer to representor structure
  */
-static int ice_repr_add(struct ice_vf *vf)
+static void ice_repr_rem(struct xarray *reprs, struct ice_repr *repr)
+{
+       xa_erase(reprs, repr->id);
+       kfree(repr->q_vector);
+       free_netdev(repr->netdev);
+       kfree(repr);
+}
+
+static void ice_repr_rem_vf(struct ice_vf *vf)
+{
+       struct ice_repr *repr = xa_load(&vf->pf->eswitch.reprs, vf->repr_id);
+
+       if (!repr)
+               return;
+
+       unregister_netdev(repr->netdev);
+       ice_repr_rem(&vf->pf->eswitch.reprs, repr);
+       ice_devlink_destroy_vf_port(vf);
+       ice_virtchnl_set_dflt_ops(vf);
+}
+
+/**
+ * ice_repr_rem_from_all_vfs - remove port representor for all VFs
+ * @pf: pointer to PF structure
+ */
+void ice_repr_rem_from_all_vfs(struct ice_pf *pf)
+{
+       struct devlink *devlink;
+       struct ice_vf *vf;
+       unsigned int bkt;
+
+       lockdep_assert_held(&pf->vfs.table_lock);
+
+       ice_for_each_vf(pf, bkt, vf)
+               ice_repr_rem_vf(vf);
+
+       /* since all port representors are destroyed, there is
+        * no point in keeping the nodes
+        */
+       devlink = priv_to_devlink(pf);
+       devl_lock(devlink);
+       devl_rate_nodes_destroy(devlink);
+       devl_unlock(devlink);
+}
+
+/**
+ * ice_repr_add - add representor for generic VSI
+ * @pf: pointer to PF structure
+ * @src_vsi: pointer to VSI structure of device to represent
+ * @parent_mac: device MAC address
+ */
+static struct ice_repr *
+ice_repr_add(struct ice_pf *pf, struct ice_vsi *src_vsi, const u8 *parent_mac)
 {
        struct ice_q_vector *q_vector;
        struct ice_netdev_priv *np;
        struct ice_repr *repr;
-       struct ice_vsi *vsi;
        int err;
 
-       vsi = ice_get_vf_vsi(vf);
-       if (!vsi)
-               return -EINVAL;
-
        repr = kzalloc(sizeof(*repr), GFP_KERNEL);
        if (!repr)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        repr->netdev = alloc_etherdev(sizeof(struct ice_netdev_priv));
        if (!repr->netdev) {
@@ -304,10 +352,7 @@ static int ice_repr_add(struct ice_vf *vf)
                goto err_alloc;
        }
 
-       repr->src_vsi = vsi;
-       repr->vf = vf;
-       repr->q_id = vf->vf_id;
-       vf->repr = repr;
+       repr->src_vsi = src_vsi;
        np = netdev_priv(repr->netdev);
        np->repr = repr;
 
@@ -318,14 +363,47 @@ static int ice_repr_add(struct ice_vf *vf)
        }
        repr->q_vector = q_vector;
 
-       err = xa_alloc(&vf->pf->eswitch.reprs, &repr->id, repr,
-                      xa_limit_32b, GFP_KERNEL);
+       err = xa_alloc(&pf->eswitch.reprs, &repr->id, repr,
+                      XA_LIMIT(1, INT_MAX), GFP_KERNEL);
        if (err)
                goto err_xa_alloc;
+       repr->q_id = repr->id;
+
+       ether_addr_copy(repr->parent_mac, parent_mac);
+
+       return repr;
+
+err_xa_alloc:
+       kfree(repr->q_vector);
+err_alloc_q_vector:
+       free_netdev(repr->netdev);
+err_alloc:
+       kfree(repr);
+       return ERR_PTR(err);
+}
+
+static int ice_repr_add_vf(struct ice_vf *vf)
+{
+       struct ice_repr *repr;
+       struct ice_vsi *vsi;
+       int err;
+
+       vsi = ice_get_vf_vsi(vf);
+       if (!vsi)
+               return -EINVAL;
 
        err = ice_devlink_create_vf_port(vf);
        if (err)
-               goto err_devlink;
+               return err;
+
+       repr = ice_repr_add(vf->pf, vsi, vf->hw_lan_addr);
+       if (IS_ERR(repr)) {
+               err = PTR_ERR(repr);
+               goto err_repr_add;
+       }
+
+       vf->repr_id = repr->id;
+       repr->vf = vf;
 
        repr->netdev->min_mtu = ETH_MIN_MTU;
        repr->netdev->max_mtu = ICE_MAX_MTU;
@@ -336,73 +414,17 @@ static int ice_repr_add(struct ice_vf *vf)
        if (err)
                goto err_netdev;
 
-       ether_addr_copy(repr->parent_mac, vf->hw_lan_addr);
        ice_virtchnl_set_repr_ops(vf);
 
        return 0;
 
 err_netdev:
+       ice_repr_rem(&vf->pf->eswitch.reprs, repr);
+err_repr_add:
        ice_devlink_destroy_vf_port(vf);
-err_devlink:
-       xa_erase(&vf->pf->eswitch.reprs, repr->id);
-err_xa_alloc:
-       kfree(repr->q_vector);
-       vf->repr->q_vector = NULL;
-err_alloc_q_vector:
-       free_netdev(repr->netdev);
-       repr->netdev = NULL;
-err_alloc:
-       kfree(repr);
-       vf->repr = NULL;
        return err;
 }
 
-/**
- * ice_repr_rem - remove representor from VF
- * @vf: pointer to VF structure
- */
-static void ice_repr_rem(struct ice_vf *vf)
-{
-       struct ice_repr *repr = vf->repr;
-
-       if (!repr)
-               return;
-
-       kfree(repr->q_vector);
-       unregister_netdev(repr->netdev);
-       ice_devlink_destroy_vf_port(vf);
-       xa_erase(&vf->pf->eswitch.reprs, repr->id);
-       free_netdev(repr->netdev);
-       kfree(repr);
-       vf->repr = NULL;
-
-       ice_virtchnl_set_dflt_ops(vf);
-}
-
-/**
- * ice_repr_rem_from_all_vfs - remove port representor for all VFs
- * @pf: pointer to PF structure
- */
-void ice_repr_rem_from_all_vfs(struct ice_pf *pf)
-{
-       struct devlink *devlink;
-       struct ice_vf *vf;
-       unsigned int bkt;
-
-       lockdep_assert_held(&pf->vfs.table_lock);
-
-       ice_for_each_vf(pf, bkt, vf)
-               ice_repr_rem(vf);
-
-       /* since all port representors are destroyed, there is
-        * no point in keeping the nodes
-        */
-       devlink = priv_to_devlink(pf);
-       devl_lock(devlink);
-       devl_rate_nodes_destroy(devlink);
-       devl_unlock(devlink);
-}
-
 /**
  * ice_repr_add_for_all_vfs - add port representor for all VFs
  * @pf: pointer to PF structure
@@ -417,7 +439,7 @@ int ice_repr_add_for_all_vfs(struct ice_pf *pf)
        lockdep_assert_held(&pf->vfs.table_lock);
 
        ice_for_each_vf(pf, bkt, vf) {
-               err = ice_repr_add(vf);
+               err = ice_repr_add_vf(vf);
                if (err)
                        goto err;
        }
@@ -437,6 +459,14 @@ err:
        return err;
 }
 
+struct ice_repr *ice_repr_get_by_vsi(struct ice_vsi *vsi)
+{
+       if (!vsi->vf)
+               return NULL;
+
+       return xa_load(&vsi->back->eswitch.reprs, vsi->vf->repr_id);
+}
+
 /**
  * ice_repr_start_tx_queues - start Tx queues of port representor
  * @repr: pointer to repr structure
index 735cb556c62055b5e554d64fc7cec243c0351b23..a3cd256d82b718fd0bd3be41061f3343f176f9cd 100644 (file)
@@ -32,4 +32,6 @@ void ice_repr_set_traffic_vsi(struct ice_repr *repr, struct ice_vsi *vsi);
 
 struct ice_repr *ice_netdev_to_repr(struct net_device *netdev);
 bool ice_is_port_repr_netdev(const struct net_device *netdev);
+
+struct ice_repr *ice_repr_get_by_vsi(struct ice_vsi *vsi);
 #endif
index 462ee9fdf815da61d82c5039335ebe7c5ce521b1..68f9de0a7a8ff447523f469e8eec0bd28a3f7609 100644 (file)
@@ -928,7 +928,7 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
                goto out_unlock;
        }
 
-       ice_eswitch_update_repr(vf->repr, vsi);
+       ice_eswitch_update_repr(vf->repr_id, vsi);
 
        /* if the VF has been reset allow it to come up again */
        ice_mbx_clear_malvf(&vf->mbx_info);
index 93c774f2f4376e3b024750e009d5b028f288a672..35866553f288f70548216e1a34db75b618efb7b0 100644 (file)
@@ -130,7 +130,7 @@ struct ice_vf {
        struct ice_mdd_vf_events mdd_tx_events;
        DECLARE_BITMAP(opcodes_allowlist, VIRTCHNL_OP_MAX);
 
-       struct ice_repr *repr;
+       unsigned long repr_id;
        const struct ice_virtchnl_ops *virtchnl_ops;
        const struct ice_vf_ops *vf_ops;