ice: make representor code generic
authorMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tue, 20 Aug 2024 06:57:53 +0000 (08:57 +0200)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Fri, 6 Sep 2024 18:01:24 +0000 (11:01 -0700)
Keep the same flow of port representor creation, but instead of general
attach function create helpers for specific representor type.

Store function pointer for add and remove representor.

Type of port representor can be also known based on VSI type, but it
is more clean to have it directly saved in port representor structure.

Add devlink lock for whole port representor creation and destruction.

Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ice/devlink/devlink_port.h
drivers/net/ethernet/intel/ice/ice_eswitch.c
drivers/net/ethernet/intel/ice/ice_eswitch.h
drivers/net/ethernet/intel/ice/ice_repr.c
drivers/net/ethernet/intel/ice/ice_repr.h
drivers/net/ethernet/intel/ice/ice_sriov.c
drivers/net/ethernet/intel/ice/ice_vf_lib.c

index 97b21b58c3008625886cb68ca821565e81b76fb8..479d2b976745e2bfd5c3b4a1b7995efdc584853f 100644 (file)
@@ -14,6 +14,7 @@
  * @devlink_port: the associated devlink port structure
  * @pf: pointer to the PF private structure
  * @vsi: the VSI associated with this port
+ * @repr_id: the representor ID
  * @sfnum: the subfunction ID
  *
  * An instance of a dynamically added devlink port. Each port flavour
@@ -24,6 +25,7 @@ struct ice_dynamic_port {
        struct devlink_port devlink_port;
        struct ice_pf *pf;
        struct ice_vsi *vsi;
+       unsigned long repr_id;
        u32 sfnum;
 };
 
index 3cfa071e371858cba9b2e44d39927b9e2c708c58..00d49477bdcb96eef7911e789cfd887aef5f3921 100644 (file)
@@ -452,11 +452,9 @@ static void ice_eswitch_start_reprs(struct ice_pf *pf)
        ice_eswitch_start_all_tx_queues(pf);
 }
 
-int
-ice_eswitch_attach(struct ice_pf *pf, struct ice_vf *vf)
+static int
+ice_eswitch_attach(struct ice_pf *pf, struct ice_repr *repr, unsigned long *id)
 {
-       struct devlink *devlink = priv_to_devlink(pf);
-       struct ice_repr *repr;
        int err;
 
        if (pf->eswitch_mode == DEVLINK_ESWITCH_MODE_LEGACY)
@@ -470,13 +468,9 @@ ice_eswitch_attach(struct ice_pf *pf, struct ice_vf *vf)
 
        ice_eswitch_stop_reprs(pf);
 
-       devl_lock(devlink);
-       repr = ice_repr_add_vf(vf);
-       devl_unlock(devlink);
-       if (IS_ERR(repr)) {
-               err = PTR_ERR(repr);
+       err = repr->ops.add(repr);
+       if (err)
                goto err_create_repr;
-       }
 
        err = ice_eswitch_setup_repr(pf, repr);
        if (err)
@@ -486,7 +480,7 @@ ice_eswitch_attach(struct ice_pf *pf, struct ice_vf *vf)
        if (err)
                goto err_xa_alloc;
 
-       vf->repr_id = repr->id;
+       *id = repr->id;
 
        ice_eswitch_start_reprs(pf);
 
@@ -495,9 +489,7 @@ ice_eswitch_attach(struct ice_pf *pf, struct ice_vf *vf)
 err_xa_alloc:
        ice_eswitch_release_repr(pf, repr);
 err_setup_repr:
-       devl_lock(devlink);
-       ice_repr_rem_vf(repr);
-       devl_unlock(devlink);
+       repr->ops.rem(repr);
 err_create_repr:
        if (xa_empty(&pf->eswitch.reprs))
                ice_eswitch_disable_switchdev(pf);
@@ -506,14 +498,35 @@ err_create_repr:
        return err;
 }
 
-void ice_eswitch_detach(struct ice_pf *pf, struct ice_vf *vf)
+/**
+ * ice_eswitch_attach_vf - attach VF to a eswitch
+ * @pf: pointer to PF structure
+ * @vf: pointer to VF structure to be attached
+ *
+ * During attaching port representor for VF is created.
+ *
+ * Return: zero on success or an error code on failure.
+ */
+int ice_eswitch_attach_vf(struct ice_pf *pf, struct ice_vf *vf)
 {
-       struct ice_repr *repr = xa_load(&pf->eswitch.reprs, vf->repr_id);
+       struct ice_repr *repr = ice_repr_create_vf(vf);
        struct devlink *devlink = priv_to_devlink(pf);
+       int err;
 
-       if (!repr)
-               return;
+       if (IS_ERR(repr))
+               return PTR_ERR(repr);
 
+       devl_lock(devlink);
+       err = ice_eswitch_attach(pf, repr, &vf->repr_id);
+       if (err)
+               ice_repr_destroy(repr);
+       devl_unlock(devlink);
+
+       return err;
+}
+
+static void ice_eswitch_detach(struct ice_pf *pf, struct ice_repr *repr)
+{
        ice_eswitch_stop_reprs(pf);
        xa_erase(&pf->eswitch.reprs, repr->id);
 
@@ -521,10 +534,12 @@ void ice_eswitch_detach(struct ice_pf *pf, struct ice_vf *vf)
                ice_eswitch_disable_switchdev(pf);
 
        ice_eswitch_release_repr(pf, repr);
-       devl_lock(devlink);
-       ice_repr_rem_vf(repr);
+       repr->ops.rem(repr);
+       ice_repr_destroy(repr);
 
        if (xa_empty(&pf->eswitch.reprs)) {
+               struct devlink *devlink = priv_to_devlink(pf);
+
                /* since all port representors are destroyed, there is
                 * no point in keeping the nodes
                 */
@@ -533,6 +548,23 @@ void ice_eswitch_detach(struct ice_pf *pf, struct ice_vf *vf)
        } else {
                ice_eswitch_start_reprs(pf);
        }
+}
+
+/**
+ * ice_eswitch_detach_vf - detach VF from a eswitch
+ * @pf: pointer to PF structure
+ * @vf: pointer to VF structure to be detached
+ */
+void ice_eswitch_detach_vf(struct ice_pf *pf, struct ice_vf *vf)
+{
+       struct ice_repr *repr = xa_load(&pf->eswitch.reprs, vf->repr_id);
+       struct devlink *devlink = priv_to_devlink(pf);
+
+       if (!repr)
+               return;
+
+       devl_lock(devlink);
+       ice_eswitch_detach(pf, repr);
        devl_unlock(devlink);
 }
 
index 78fd39a6935d35f175d96822e94b0be4e1cfceed..d1699954a7ad20d8971ce14d676e22bfe56d6430 100644 (file)
@@ -5,11 +5,11 @@
 #define _ICE_ESWITCH_H_
 
 #include <net/devlink.h>
+#include "devlink/devlink_port.h"
 
 #ifdef CONFIG_ICE_SWITCHDEV
-void ice_eswitch_detach(struct ice_pf *pf, struct ice_vf *vf);
-int
-ice_eswitch_attach(struct ice_pf *pf, struct ice_vf *vf);
+void ice_eswitch_detach_vf(struct ice_pf *pf, struct ice_vf *vf);
+int ice_eswitch_attach_vf(struct ice_pf *pf, struct ice_vf *vf);
 
 int ice_eswitch_mode_get(struct devlink *devlink, u16 *mode);
 int
@@ -31,10 +31,11 @@ struct net_device *ice_eswitch_get_target(struct ice_rx_ring *rx_ring,
 int ice_eswitch_cfg_vsi(struct ice_vsi *vsi, const u8 *mac);
 void ice_eswitch_decfg_vsi(struct ice_vsi *vsi, const u8 *mac);
 #else /* CONFIG_ICE_SWITCHDEV */
-static inline void ice_eswitch_detach(struct ice_pf *pf, struct ice_vf *vf) { }
+static inline void
+ice_eswitch_detach_vf(struct ice_pf *pf, struct ice_vf *vf) { }
 
 static inline int
-ice_eswitch_attach(struct ice_pf *pf, struct ice_vf *vf)
+ice_eswitch_attach_vf(struct ice_pf *pf, struct ice_vf *vf)
 {
        return -EOPNOTSUPP;
 }
index bdda3401e3438b2395dfee50207c2057735d2d5c..5d71f623b1e0ea99bf3d9c0ec942565b306b627b 100644 (file)
@@ -283,34 +283,23 @@ ice_repr_reg_netdev(struct net_device *netdev)
        return register_netdev(netdev);
 }
 
-static void ice_repr_remove_node(struct devlink_port *devlink_port)
-{
-       devl_rate_leaf_destroy(devlink_port);
-}
-
 /**
- * ice_repr_rem - remove representor from VF
+ * ice_repr_destroy - remove representor from VF
  * @repr: pointer to representor structure
  */
-static void ice_repr_rem(struct ice_repr *repr)
+void ice_repr_destroy(struct ice_repr *repr)
 {
        free_percpu(repr->stats);
        free_netdev(repr->netdev);
        kfree(repr);
 }
 
-/**
- * ice_repr_rem_vf - remove representor from VF
- * @repr: pointer to representor structure
- */
-void ice_repr_rem_vf(struct ice_repr *repr)
+static void ice_repr_rem_vf(struct ice_repr *repr)
 {
-       ice_repr_remove_node(&repr->vf->devlink_port);
        ice_eswitch_decfg_vsi(repr->src_vsi, repr->parent_mac);
        unregister_netdev(repr->netdev);
        ice_devlink_destroy_vf_port(repr->vf);
        ice_virtchnl_set_dflt_ops(repr->vf);
-       ice_repr_rem(repr);
 }
 
 static void ice_repr_set_tx_topology(struct ice_pf *pf)
@@ -327,13 +316,10 @@ static void ice_repr_set_tx_topology(struct ice_pf *pf)
 }
 
 /**
- * ice_repr_add - add representor for generic VSI
- * @pf: pointer to PF structure
+ * ice_repr_create - add representor for generic VSI
  * @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)
+static struct ice_repr *ice_repr_create(struct ice_vsi *src_vsi)
 {
        struct ice_netdev_priv *np;
        struct ice_repr *repr;
@@ -360,7 +346,10 @@ ice_repr_add(struct ice_pf *pf, struct ice_vsi *src_vsi, const u8 *parent_mac)
        np = netdev_priv(repr->netdev);
        np->repr = repr;
 
-       ether_addr_copy(repr->parent_mac, parent_mac);
+       repr->netdev->min_mtu = ETH_MIN_MTU;
+       repr->netdev->max_mtu = ICE_MAX_MTU;
+
+       SET_NETDEV_DEV(repr->netdev, ice_pf_to_dev(src_vsi->back));
 
        return repr;
 
@@ -371,32 +360,15 @@ err_alloc:
        return ERR_PTR(err);
 }
 
-struct ice_repr *ice_repr_add_vf(struct ice_vf *vf)
+static int ice_repr_add_vf(struct ice_repr *repr)
 {
-       struct ice_repr *repr;
-       struct ice_vsi *vsi;
+       struct ice_vf *vf = repr->vf;
        int err;
 
-       vsi = ice_get_vf_vsi(vf);
-       if (!vsi)
-               return ERR_PTR(-ENOENT);
-
        err = ice_devlink_create_vf_port(vf);
        if (err)
-               return ERR_PTR(err);
-
-       repr = ice_repr_add(vf->pf, vsi, vf->hw_lan_addr);
-       if (IS_ERR(repr)) {
-               err = PTR_ERR(repr);
-               goto err_repr_add;
-       }
-
-       repr->vf = vf;
+               return err;
 
-       repr->netdev->min_mtu = ETH_MIN_MTU;
-       repr->netdev->max_mtu = ICE_MAX_MTU;
-
-       SET_NETDEV_DEV(repr->netdev, ice_pf_to_dev(vf->pf));
        SET_NETDEV_DEVLINK_PORT(repr->netdev, &vf->devlink_port);
        err = ice_repr_reg_netdev(repr->netdev);
        if (err)
@@ -409,15 +381,43 @@ struct ice_repr *ice_repr_add_vf(struct ice_vf *vf)
        ice_virtchnl_set_repr_ops(vf);
        ice_repr_set_tx_topology(vf->pf);
 
-       return repr;
+       return 0;
 
 err_cfg_vsi:
        unregister_netdev(repr->netdev);
 err_netdev:
-       ice_repr_rem(repr);
-err_repr_add:
        ice_devlink_destroy_vf_port(vf);
-       return ERR_PTR(err);
+       return err;
+}
+
+/**
+ * ice_repr_create_vf - add representor for VF VSI
+ * @vf: VF to create port representor on
+ *
+ * Set correct representor type for VF and functions pointer.
+ *
+ * Return: created port representor on success, error otherwise
+ */
+struct ice_repr *ice_repr_create_vf(struct ice_vf *vf)
+{
+       struct ice_vsi *vsi = ice_get_vf_vsi(vf);
+       struct ice_repr *repr;
+
+       if (!vsi)
+               return ERR_PTR(-EINVAL);
+
+       repr = ice_repr_create(vsi);
+       if (!repr)
+               return ERR_PTR(-ENOMEM);
+
+       repr->type = ICE_REPR_TYPE_VF;
+       repr->vf = vf;
+       repr->ops.add = ice_repr_add_vf;
+       repr->ops.rem = ice_repr_rem_vf;
+
+       ether_addr_copy(repr->parent_mac, vf->hw_lan_addr);
+
+       return repr;
 }
 
 struct ice_repr *ice_repr_get(struct ice_pf *pf, u32 id)
index 488661b2900b0c9a38f50a10d9ea68143dda2734..c6e77b9c6a3262628db052fbe88f6cc65d329611 100644 (file)
@@ -15,19 +15,29 @@ struct ice_repr_pcpu_stats {
        u64 tx_drops;
 };
 
+enum ice_repr_type {
+       ICE_REPR_TYPE_VF,
+};
+
 struct ice_repr {
        struct ice_vsi *src_vsi;
-       struct ice_vf *vf;
        struct net_device *netdev;
        struct metadata_dst *dst;
        struct ice_esw_br_port *br_port;
        struct ice_repr_pcpu_stats __percpu *stats;
        u32 id;
        u8 parent_mac[ETH_ALEN];
+       enum ice_repr_type type;
+       struct ice_vf *vf;
+       struct {
+               int (*add)(struct ice_repr *repr);
+               void (*rem)(struct ice_repr *repr);
+       } ops;
 };
 
-struct ice_repr *ice_repr_add_vf(struct ice_vf *vf);
-void ice_repr_rem_vf(struct ice_repr *repr);
+struct ice_repr *ice_repr_create_vf(struct ice_vf *vf);
+
+void ice_repr_destroy(struct ice_repr *repr);
 
 void ice_repr_start_tx_queues(struct ice_repr *repr);
 void ice_repr_stop_tx_queues(struct ice_repr *repr);
index 55ef33208456a4566e95ce725326c595320b3e99..e34fe2516cccf2bd01df0db83addfc76e77a09f2 100644 (file)
@@ -175,7 +175,7 @@ void ice_free_vfs(struct ice_pf *pf)
        ice_for_each_vf(pf, bkt, vf) {
                mutex_lock(&vf->cfg_lock);
 
-               ice_eswitch_detach(pf, vf);
+               ice_eswitch_detach_vf(pf, vf);
                ice_dis_vf_qs(vf);
 
                if (test_bit(ICE_VF_STATE_INIT, vf->vf_states)) {
@@ -598,7 +598,7 @@ static int ice_start_vfs(struct ice_pf *pf)
                        goto teardown;
                }
 
-               retval = ice_eswitch_attach(pf, vf);
+               retval = ice_eswitch_attach_vf(pf, vf);
                if (retval) {
                        dev_err(ice_pf_to_dev(pf), "Failed to attach VF %d to eswitch, error %d",
                                vf->vf_id, retval);
index 5635e9da2212ba8d5f847e4e2bc149731bbd87c5..a69e91f88d81181d4897c9fda2a930267f139404 100644 (file)
@@ -766,7 +766,7 @@ void ice_reset_all_vfs(struct ice_pf *pf)
        ice_for_each_vf(pf, bkt, vf) {
                mutex_lock(&vf->cfg_lock);
 
-               ice_eswitch_detach(pf, vf);
+               ice_eswitch_detach_vf(pf, vf);
                vf->driver_caps = 0;
                ice_vc_set_default_allowlist(vf);
 
@@ -782,7 +782,7 @@ void ice_reset_all_vfs(struct ice_pf *pf)
                ice_vf_rebuild_vsi(vf);
                ice_vf_post_vsi_rebuild(vf);
 
-               ice_eswitch_attach(pf, vf);
+               ice_eswitch_attach_vf(pf, vf);
 
                mutex_unlock(&vf->cfg_lock);
        }