]> git.itanic.dy.fi Git - linux-stable/commitdiff
net/mlx5: DR, handle more than one peer domain
authorShay Drory <shayd@nvidia.com>
Tue, 21 Feb 2023 08:17:06 +0000 (10:17 +0200)
committerSaeed Mahameed <saeedm@nvidia.com>
Fri, 2 Jun 2023 19:10:48 +0000 (12:10 -0700)
Currently, DR domain is using the assumption that each domain can only
have a single peer.
In order to support VF LAG of more then two ports, expand peer domain
to use an array of peers, and align the code accordingly.

Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
12 files changed:
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste_v0.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste_v1.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h
drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c
drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h

index 98d75a33a6249c3584770380965652a93781f26c..761278e1af5ca06f2e8b1216805a3eef73320542 100644 (file)
@@ -2778,7 +2778,9 @@ static int mlx5_esw_offloads_set_ns_peer(struct mlx5_eswitch *esw,
                                         struct mlx5_eswitch *peer_esw,
                                         bool pair)
 {
+       u8 peer_idx = mlx5_get_dev_index(peer_esw->dev);
        struct mlx5_flow_root_namespace *peer_ns;
+       u8 idx = mlx5_get_dev_index(esw->dev);
        struct mlx5_flow_root_namespace *ns;
        int err;
 
@@ -2786,18 +2788,18 @@ static int mlx5_esw_offloads_set_ns_peer(struct mlx5_eswitch *esw,
        ns = esw->dev->priv.steering->fdb_root_ns;
 
        if (pair) {
-               err = mlx5_flow_namespace_set_peer(ns, peer_ns);
+               err = mlx5_flow_namespace_set_peer(ns, peer_ns, peer_idx);
                if (err)
                        return err;
 
-               err = mlx5_flow_namespace_set_peer(peer_ns, ns);
+               err = mlx5_flow_namespace_set_peer(peer_ns, ns, idx);
                if (err) {
-                       mlx5_flow_namespace_set_peer(ns, NULL);
+                       mlx5_flow_namespace_set_peer(ns, NULL, peer_idx);
                        return err;
                }
        } else {
-               mlx5_flow_namespace_set_peer(ns, NULL);
-               mlx5_flow_namespace_set_peer(peer_ns, NULL);
+               mlx5_flow_namespace_set_peer(ns, NULL, peer_idx);
+               mlx5_flow_namespace_set_peer(peer_ns, NULL, idx);
        }
 
        return 0;
index 144e59480686447de7c74d60f28b5efa9066dce6..11374c3744c5f0d588a9804c62b32ee1e894335e 100644 (file)
@@ -139,7 +139,8 @@ static void mlx5_cmd_stub_modify_header_dealloc(struct mlx5_flow_root_namespace
 }
 
 static int mlx5_cmd_stub_set_peer(struct mlx5_flow_root_namespace *ns,
-                                 struct mlx5_flow_root_namespace *peer_ns)
+                                 struct mlx5_flow_root_namespace *peer_ns,
+                                 u8 peer_idx)
 {
        return 0;
 }
index 8ef4254b9ea126e13a9052d6d36c561a33962898..b6b9a5a20591dfe59e8213fd3f92987d1c8d4ebd 100644 (file)
@@ -93,7 +93,8 @@ struct mlx5_flow_cmds {
                                      struct mlx5_modify_hdr *modify_hdr);
 
        int (*set_peer)(struct mlx5_flow_root_namespace *ns,
-                       struct mlx5_flow_root_namespace *peer_ns);
+                       struct mlx5_flow_root_namespace *peer_ns,
+                       u8 peer_idx);
 
        int (*create_ns)(struct mlx5_flow_root_namespace *ns);
        int (*destroy_ns)(struct mlx5_flow_root_namespace *ns);
index 19da02c41616182ca26f8ca1d28eb3fd3e93d1ee..4ef04aa287719ee469ca8f0e47453b7929719fd1 100644 (file)
@@ -3620,7 +3620,8 @@ void mlx5_destroy_match_definer(struct mlx5_core_dev *dev,
 }
 
 int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns,
-                                struct mlx5_flow_root_namespace *peer_ns)
+                                struct mlx5_flow_root_namespace *peer_ns,
+                                u8 peer_idx)
 {
        if (peer_ns && ns->mode != peer_ns->mode) {
                mlx5_core_err(ns->dev,
@@ -3628,7 +3629,7 @@ int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns,
                return -EINVAL;
        }
 
-       return ns->cmds->set_peer(ns, peer_ns);
+       return ns->cmds->set_peer(ns, peer_ns, peer_idx);
 }
 
 /* This function should be called only at init stage of the namespace.
index f137a0611b77b41a7c733b60b1321af60b70c0f3..200ec946409c25c9f008ec45cab8529544327abf 100644 (file)
@@ -295,7 +295,8 @@ void mlx5_fc_update_sampling_interval(struct mlx5_core_dev *dev,
 const struct mlx5_flow_cmds *mlx5_fs_cmd_get_fw_cmds(void);
 
 int mlx5_flow_namespace_set_peer(struct mlx5_flow_root_namespace *ns,
-                                struct mlx5_flow_root_namespace *peer_ns);
+                                struct mlx5_flow_root_namespace *peer_ns,
+                                u8 peer_idx);
 
 int mlx5_flow_namespace_set_mode(struct mlx5_flow_namespace *ns,
                                 enum mlx5_flow_steering_mode mode);
index 0eb9a8d7f282fc93e99ab4598a52b950d877f6d0..4e9bc1897a88563b0ffd67e93d0eb99d32d7c953 100644 (file)
@@ -2071,8 +2071,9 @@ mlx5dr_action_create_dest_vport(struct mlx5dr_domain *dmn,
        struct mlx5dr_action *action;
        u8 peer_vport;
 
-       peer_vport = vhca_id_valid && (vhca_id != dmn->info.caps.gvmi);
-       vport_dmn = peer_vport ? dmn->peer_dmn : dmn;
+       peer_vport = vhca_id_valid && mlx5_core_is_pf(dmn->mdev) &&
+               (vhca_id != dmn->info.caps.gvmi);
+       vport_dmn = peer_vport ? dmn->peer_dmn[vhca_id] : dmn;
        if (!vport_dmn) {
                mlx5dr_dbg(dmn, "No peer vport domain for given vhca_id\n");
                return NULL;
index 9a2dfe6ebe3188941a273afcc1f90dbe1eb85667..75dc85dc24ef212a34aa02e4173fc25b17b53154 100644 (file)
@@ -555,17 +555,18 @@ int mlx5dr_domain_destroy(struct mlx5dr_domain *dmn)
 }
 
 void mlx5dr_domain_set_peer(struct mlx5dr_domain *dmn,
-                           struct mlx5dr_domain *peer_dmn)
+                           struct mlx5dr_domain *peer_dmn,
+                           u8 peer_idx)
 {
        mlx5dr_domain_lock(dmn);
 
-       if (dmn->peer_dmn)
-               refcount_dec(&dmn->peer_dmn->refcount);
+       if (dmn->peer_dmn[peer_idx])
+               refcount_dec(&dmn->peer_dmn[peer_idx]->refcount);
 
-       dmn->peer_dmn = peer_dmn;
+       dmn->peer_dmn[peer_idx] = peer_dmn;
 
-       if (dmn->peer_dmn)
-               refcount_inc(&dmn->peer_dmn->refcount);
+       if (dmn->peer_dmn[peer_idx])
+               refcount_inc(&dmn->peer_dmn[peer_idx]->refcount);
 
        mlx5dr_domain_unlock(dmn);
 }
index 2010d4ac651909e1ff2d5d8a7ca2a485ae13e50c..69d7a8f3c402e31a942eea82bce6e4deb231d5a0 100644 (file)
@@ -1647,6 +1647,7 @@ dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
                                 u8 *tag)
 {
        struct mlx5dr_match_misc *misc = &value->misc;
+       int id = misc->source_eswitch_owner_vhca_id;
        struct mlx5dr_cmd_vport_cap *vport_cap;
        struct mlx5dr_domain *dmn = sb->dmn;
        struct mlx5dr_domain *vport_dmn;
@@ -1657,11 +1658,11 @@ dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
 
        if (sb->vhca_id_valid) {
                /* Find port GVMI based on the eswitch_owner_vhca_id */
-               if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi)
+               if (id == dmn->info.caps.gvmi)
                        vport_dmn = dmn;
-               else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id ==
-                                          dmn->peer_dmn->info.caps.gvmi))
-                       vport_dmn = dmn->peer_dmn;
+               else if (id < MLX5_MAX_PORTS && dmn->peer_dmn[id] &&
+                        (id == dmn->peer_dmn[id]->info.caps.gvmi))
+                       vport_dmn = dmn->peer_dmn[id];
                else
                        return -EINVAL;
 
index 4c0704ad166b35a2309508fcdf8ecda3c316e5c9..f4ef0b22b991211c83c8a914fab296ace8355996 100644 (file)
@@ -1979,6 +1979,7 @@ static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
                                            u8 *tag)
 {
        struct mlx5dr_match_misc *misc = &value->misc;
+       int id = misc->source_eswitch_owner_vhca_id;
        struct mlx5dr_cmd_vport_cap *vport_cap;
        struct mlx5dr_domain *dmn = sb->dmn;
        struct mlx5dr_domain *vport_dmn;
@@ -1988,11 +1989,11 @@ static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
 
        if (sb->vhca_id_valid) {
                /* Find port GVMI based on the eswitch_owner_vhca_id */
-               if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi)
+               if (id == dmn->info.caps.gvmi)
                        vport_dmn = dmn;
-               else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id ==
-                                          dmn->peer_dmn->info.caps.gvmi))
-                       vport_dmn = dmn->peer_dmn;
+               else if (id < MLX5_MAX_PORTS && dmn->peer_dmn[id] &&
+                        (id == dmn->peer_dmn[id]->info.caps.gvmi))
+                       vport_dmn = dmn->peer_dmn[id];
                else
                        return -EINVAL;
 
index 678a993ab053d490302ed58a9b0bc449273395e3..1622dbbe6b970d2cb66e53de2857485f6bc78a41 100644 (file)
@@ -935,7 +935,7 @@ struct mlx5dr_domain_info {
 };
 
 struct mlx5dr_domain {
-       struct mlx5dr_domain *peer_dmn;
+       struct mlx5dr_domain *peer_dmn[MLX5_MAX_PORTS];
        struct mlx5_core_dev *mdev;
        u32 pdn;
        struct mlx5_uars_page *uar;
index 984653756779616de63528501cbdab338c025162..c6fda1cbfcffb17140acf4386412b11aa4f5f671 100644 (file)
@@ -770,14 +770,15 @@ static int mlx5_cmd_dr_update_fte(struct mlx5_flow_root_namespace *ns,
 }
 
 static int mlx5_cmd_dr_set_peer(struct mlx5_flow_root_namespace *ns,
-                               struct mlx5_flow_root_namespace *peer_ns)
+                               struct mlx5_flow_root_namespace *peer_ns,
+                               u8 peer_idx)
 {
        struct mlx5dr_domain *peer_domain = NULL;
 
        if (peer_ns)
                peer_domain = peer_ns->fs_dr_domain.dr_domain;
        mlx5dr_domain_set_peer(ns->fs_dr_domain.dr_domain,
-                              peer_domain);
+                              peer_domain, peer_idx);
        return 0;
 }
 
index 9afd268a257381015d347eae469f5407b1132bfd..5ba88f2ecb3f4de48f3dd91d4b058cbcaea57d2f 100644 (file)
@@ -48,7 +48,8 @@ int mlx5dr_domain_destroy(struct mlx5dr_domain *domain);
 int mlx5dr_domain_sync(struct mlx5dr_domain *domain, u32 flags);
 
 void mlx5dr_domain_set_peer(struct mlx5dr_domain *dmn,
-                           struct mlx5dr_domain *peer_dmn);
+                           struct mlx5dr_domain *peer_dmn,
+                           u8 peer_idx);
 
 struct mlx5dr_table *
 mlx5dr_table_create(struct mlx5dr_domain *domain, u32 level, u32 flags,