From e8d31c4d65998c38feccc539297ca506099e0194 Mon Sep 17 00:00:00 2001 From: Mark Bloch Date: Wed, 9 Aug 2017 11:47:14 +0000 Subject: net/mlx5: E-Switch, Refactor vport representors initialization Refactor the init stage of vport representors registration. vport number and hw id can be assigned by the E-Switch driver and not by the netdevice driver. While here, make the error path of mlx5_eswitch_init() a reverse order of the good path, also use kcalloc to allocate an array instead of kzalloc. Signed-off-by: Mark Bloch Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 7 ---- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 12 +++---- drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 2 ++ .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 39 +++++++++++++++++++--- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 2c43606c26b5..4661ef12c18c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -1100,17 +1100,12 @@ static void mlx5e_rep_register_vf_vports(struct mlx5e_priv *priv) struct mlx5_eswitch *esw = mdev->priv.eswitch; int total_vfs = MLX5_TOTAL_VPORTS(mdev); int vport; - u8 mac[ETH_ALEN]; - - mlx5_query_nic_vport_mac_address(mdev, 0, mac); for (vport = 1; vport < total_vfs; vport++) { struct mlx5_eswitch_rep rep; rep.load = mlx5e_vport_rep_load; rep.unload = mlx5e_vport_rep_unload; - rep.vport = vport; - ether_addr_copy(rep.hw_id, mac); mlx5_eswitch_register_vport_rep(esw, vport, &rep); } } @@ -1132,10 +1127,8 @@ void mlx5e_register_vport_reps(struct mlx5e_priv *priv) struct mlx5_eswitch *esw = mdev->priv.eswitch; struct mlx5_eswitch_rep rep; - mlx5_query_nic_vport_mac_address(mdev, 0, rep.hw_id); rep.load = mlx5e_nic_rep_load; rep.unload = mlx5e_nic_rep_unload; - rep.vport = FDB_UPLINK_VPORT; rep.netdev = priv->netdev; mlx5_eswitch_register_vport_rep(esw, 0, &rep); /* UPLINK PF vport*/ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index bbb140f517c4..6d4cbdb69823 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1644,13 +1644,9 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev) goto abort; } - esw->offloads.vport_reps = - kzalloc(total_vports * sizeof(struct mlx5_eswitch_rep), - GFP_KERNEL); - if (!esw->offloads.vport_reps) { - err = -ENOMEM; + err = esw_offloads_init_reps(esw); + if (err) goto abort; - } hash_init(esw->offloads.encap_tbl); hash_init(esw->offloads.mod_hdr_tbl); @@ -1681,8 +1677,8 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev) abort: if (esw->work_queue) destroy_workqueue(esw->work_queue); + esw_offloads_cleanup_reps(esw); kfree(esw->vports); - kfree(esw->offloads.vport_reps); kfree(esw); return err; } @@ -1696,7 +1692,7 @@ void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) esw->dev->priv.eswitch = NULL; destroy_workqueue(esw->work_queue); - kfree(esw->offloads.vport_reps); + esw_offloads_cleanup_reps(esw); kfree(esw->vports); kfree(esw); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index 565c8b7a399a..9722c2a96090 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -197,6 +197,8 @@ struct mlx5_eswitch { void esw_offloads_cleanup(struct mlx5_eswitch *esw, int nvports); int esw_offloads_init(struct mlx5_eswitch *esw, int nvports); +void esw_offloads_cleanup_reps(struct mlx5_eswitch *esw); +int esw_offloads_init_reps(struct mlx5_eswitch *esw); /* E-Switch API */ int mlx5_eswitch_init(struct mlx5_core_dev *dev); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 1143d80119bd..7e15854c1087 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -732,6 +732,41 @@ static int esw_offloads_start(struct mlx5_eswitch *esw) return err; } +void esw_offloads_cleanup_reps(struct mlx5_eswitch *esw) +{ + kfree(esw->offloads.vport_reps); +} + +int esw_offloads_init_reps(struct mlx5_eswitch *esw) +{ + int total_vfs = MLX5_TOTAL_VPORTS(esw->dev); + struct mlx5_core_dev *dev = esw->dev; + struct mlx5_esw_offload *offloads; + struct mlx5_eswitch_rep *rep; + u8 hw_id[ETH_ALEN]; + int vport; + + esw->offloads.vport_reps = kcalloc(total_vfs, + sizeof(struct mlx5_eswitch_rep), + GFP_KERNEL); + if (!esw->offloads.vport_reps) + return -ENOMEM; + + offloads = &esw->offloads; + mlx5_query_nic_vport_mac_address(dev, 0, hw_id); + + for (vport = 0; vport < total_vfs; vport++) { + rep = &offloads->vport_reps[vport]; + + rep->vport = vport; + ether_addr_copy(rep->hw_id, hw_id); + } + + offloads->vport_reps[0].vport = FDB_UPLINK_VPORT; + + return 0; +} + int esw_offloads_init(struct mlx5_eswitch *esw, int nvports) { struct mlx5_eswitch_rep *rep; @@ -1127,13 +1162,9 @@ void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw, rep = &offloads->vport_reps[vport_index]; - memset(rep, 0, sizeof(*rep)); - rep->load = __rep->load; rep->unload = __rep->unload; - rep->vport = __rep->vport; rep->netdev = __rep->netdev; - ether_addr_copy(rep->hw_id, __rep->hw_id); INIT_LIST_HEAD(&rep->vport_sqs_list); rep->valid = true; -- cgit v1.2.3-59-g8ed1b From 6ed1803abe401ec44eb65a4ca12d3b9da2839f45 Mon Sep 17 00:00:00 2001 From: Mark Bloch Date: Wed, 9 Aug 2017 14:50:57 +0000 Subject: net/mlx5: E-Switch, Refactor load/unload of representors Refactor the load/unload stages for better code reuse. Signed-off-by: Mark Bloch Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 66 +++++++++++++--------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 7e15854c1087..26fbc50ddc6d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -767,12 +767,47 @@ int esw_offloads_init_reps(struct mlx5_eswitch *esw) return 0; } -int esw_offloads_init(struct mlx5_eswitch *esw, int nvports) +static void esw_offloads_unload_reps(struct mlx5_eswitch *esw, int nvports) +{ + struct mlx5_eswitch_rep *rep; + int vport; + + for (vport = nvports - 1; vport >= 0; vport--) { + rep = &esw->offloads.vport_reps[vport]; + if (!rep->valid) + continue; + + rep->unload(esw, rep); + } +} + +static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports) { struct mlx5_eswitch_rep *rep; int vport; int err; + for (vport = 0; vport < nvports; vport++) { + rep = &esw->offloads.vport_reps[vport]; + if (!rep->valid) + continue; + + err = rep->load(esw, rep); + if (err) + goto err_reps; + } + + return 0; + +err_reps: + esw_offloads_unload_reps(esw, vport); + return err; +} + +int esw_offloads_init(struct mlx5_eswitch *esw, int nvports) +{ + int err; + /* disable PF RoCE so missed packets don't go through RoCE steering */ mlx5_dev_list_lock(); mlx5_remove_dev_by_protocol(esw->dev, MLX5_INTERFACE_PROTOCOL_IB); @@ -790,25 +825,13 @@ int esw_offloads_init(struct mlx5_eswitch *esw, int nvports) if (err) goto create_fg_err; - for (vport = 0; vport < nvports; vport++) { - rep = &esw->offloads.vport_reps[vport]; - if (!rep->valid) - continue; - - err = rep->load(esw, rep); - if (err) - goto err_reps; - } + err = esw_offloads_load_reps(esw, nvports); + if (err) + goto err_reps; return 0; err_reps: - for (vport--; vport >= 0; vport--) { - rep = &esw->offloads.vport_reps[vport]; - if (!rep->valid) - continue; - rep->unload(esw, rep); - } esw_destroy_vport_rx_group(esw); create_fg_err: @@ -849,16 +872,7 @@ static int esw_offloads_stop(struct mlx5_eswitch *esw) void esw_offloads_cleanup(struct mlx5_eswitch *esw, int nvports) { - struct mlx5_eswitch_rep *rep; - int vport; - - for (vport = nvports - 1; vport >= 0; vport--) { - rep = &esw->offloads.vport_reps[vport]; - if (!rep->valid) - continue; - rep->unload(esw, rep); - } - + esw_offloads_unload_reps(esw, nvports); esw_destroy_vport_rx_group(esw); esw_destroy_offloads_table(esw); esw_destroy_offloads_fdb_tables(esw); -- cgit v1.2.3-59-g8ed1b From 4c66df01f5a46b191df0d036fc76cc9350280bc3 Mon Sep 17 00:00:00 2001 From: Mark Bloch Date: Fri, 25 Aug 2017 12:13:59 +0000 Subject: net/mlx5: E-Switch, Simplify representor load/unload callback API In the load() callback for loading representors we don't really need struct mlx5_eswitch but struct mlx5_core_dev, pass it directly. In the unload() callback for unloading representors we don't need the struct mlx5_eswitch argument, remove it. Signed-off-by: Mark Bloch Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 14 +++++++------- drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 5 ++--- drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 6 +++--- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 4661ef12c18c..6d2219f3acf6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -967,7 +967,7 @@ static const struct mlx5e_profile mlx5e_rep_profile = { /* e-Switch vport representors */ static int -mlx5e_nic_rep_load(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep) +mlx5e_nic_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) { struct mlx5e_priv *priv = netdev_priv(rep->netdev); struct mlx5e_rep_priv *rpriv = priv->ppriv; @@ -992,7 +992,7 @@ err_remove_sqs: } static void -mlx5e_nic_rep_unload(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep) +mlx5e_nic_rep_unload(struct mlx5_eswitch_rep *rep) { struct mlx5e_priv *priv = netdev_priv(rep->netdev); struct mlx5e_rep_priv *rpriv = priv->ppriv; @@ -1008,7 +1008,7 @@ mlx5e_nic_rep_unload(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep) } static int -mlx5e_vport_rep_load(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep) +mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) { struct mlx5e_rep_priv *rpriv; struct net_device *netdev; @@ -1019,7 +1019,7 @@ mlx5e_vport_rep_load(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep) if (!rpriv) return -ENOMEM; - netdev = mlx5e_create_netdev(esw->dev, &mlx5e_rep_profile, rpriv); + netdev = mlx5e_create_netdev(dev, &mlx5e_rep_profile, rpriv); if (!netdev) { pr_warn("Failed to create representor netdev for vport %d\n", rep->vport); @@ -1044,7 +1044,7 @@ mlx5e_vport_rep_load(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep) goto err_detach_netdev; } - upriv = netdev_priv(mlx5_eswitch_get_uplink_netdev(esw)); + upriv = netdev_priv(mlx5_eswitch_get_uplink_netdev(dev->priv.eswitch)); err = tc_setup_cb_egdev_register(netdev, mlx5e_setup_tc_block_cb, upriv); if (err) @@ -1076,7 +1076,7 @@ err_destroy_netdev: } static void -mlx5e_vport_rep_unload(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep) +mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep) { struct net_device *netdev = rep->netdev; struct mlx5e_priv *priv = netdev_priv(netdev); @@ -1085,7 +1085,7 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep) struct mlx5e_priv *upriv; unregister_netdev(rep->netdev); - upriv = netdev_priv(mlx5_eswitch_get_uplink_netdev(esw)); + upriv = netdev_priv(mlx5_eswitch_get_uplink_netdev(priv->mdev->priv.eswitch)); tc_setup_cb_egdev_unregister(netdev, mlx5e_setup_tc_block_cb, upriv); mlx5e_rep_neigh_cleanup(rpriv); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index 9722c2a96090..23808a65889c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -139,10 +139,9 @@ struct mlx5_esw_sq { }; struct mlx5_eswitch_rep { - int (*load)(struct mlx5_eswitch *esw, + int (*load)(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep); - void (*unload)(struct mlx5_eswitch *esw, - struct mlx5_eswitch_rep *rep); + void (*unload)(struct mlx5_eswitch_rep *rep); u16 vport; u8 hw_id[ETH_ALEN]; struct net_device *netdev; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 26fbc50ddc6d..aa20f51c0a99 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -777,7 +777,7 @@ static void esw_offloads_unload_reps(struct mlx5_eswitch *esw, int nvports) if (!rep->valid) continue; - rep->unload(esw, rep); + rep->unload(rep); } } @@ -792,7 +792,7 @@ static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports) if (!rep->valid) continue; - err = rep->load(esw, rep); + err = rep->load(esw->dev, rep); if (err) goto err_reps; } @@ -1193,7 +1193,7 @@ void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, rep = &offloads->vport_reps[vport_index]; if (esw->mode == SRIOV_OFFLOADS && esw->vports[vport_index].enabled) - rep->unload(esw, rep); + rep->unload(rep); rep->valid = false; } -- cgit v1.2.3-59-g8ed1b From f7a68945a5aab7498fb7a3e5b13e2ae6c2955e55 Mon Sep 17 00:00:00 2001 From: Mark Bloch Date: Thu, 7 Dec 2017 15:31:50 +0000 Subject: net/mlx5: E-Switch, Move mlx5e only logic outside E-Switch In our pursuit to cleanup e-switch sub-module from mlx5e specific code, we move the functions that insert/remove the flow steering rules that allow mlx5e representors to send packets directly to VFs into the EN driver code. Signed-off-by: Mark Bloch Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 57 +++++++++++++++++++++- drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 9 ++-- .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 55 +-------------------- 3 files changed, 59 insertions(+), 62 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 6d2219f3acf6..19edaa155062 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -190,6 +190,59 @@ int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr) return 0; } +static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw, + struct mlx5_eswitch_rep *rep) +{ + struct mlx5_esw_sq *esw_sq, *tmp; + + if (esw->mode != SRIOV_OFFLOADS) + return; + + list_for_each_entry_safe(esw_sq, tmp, &rep->vport_sqs_list, list) { + mlx5_del_flow_rules(esw_sq->send_to_vport_rule); + list_del(&esw_sq->list); + kfree(esw_sq); + } +} + +static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw, + struct mlx5_eswitch_rep *rep, + u16 *sqns_array, int sqns_num) +{ + struct mlx5_flow_handle *flow_rule; + struct mlx5_esw_sq *esw_sq; + int err; + int i; + + if (esw->mode != SRIOV_OFFLOADS) + return 0; + + for (i = 0; i < sqns_num; i++) { + esw_sq = kzalloc(sizeof(*esw_sq), GFP_KERNEL); + if (!esw_sq) { + err = -ENOMEM; + goto out_err; + } + + /* Add re-inject rule to the PF/representor sqs */ + flow_rule = mlx5_eswitch_add_send_to_vport_rule(esw, + rep->vport, + sqns_array[i]); + if (IS_ERR(flow_rule)) { + err = PTR_ERR(flow_rule); + kfree(esw_sq); + goto out_err; + } + esw_sq->send_to_vport_rule = flow_rule; + list_add(&esw_sq->list, &rep->vport_sqs_list); + } + return 0; + +out_err: + mlx5e_sqs2vport_stop(esw, rep); + return err; +} + int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv) { struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; @@ -210,7 +263,7 @@ int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv) sqs[num_sqs++] = c->sq[tc].sqn; } - err = mlx5_eswitch_sqs2vport_start(esw, rep, sqs, num_sqs); + err = mlx5e_sqs2vport_start(esw, rep, sqs, num_sqs); kfree(sqs); out: @@ -225,7 +278,7 @@ void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv) struct mlx5e_rep_priv *rpriv = priv->ppriv; struct mlx5_eswitch_rep *rep = rpriv->rep; - mlx5_eswitch_sqs2vport_stop(esw, rep); + mlx5e_sqs2vport_stop(esw, rep); } static void mlx5e_rep_neigh_update_init_interval(struct mlx5e_rep_priv *rpriv) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index 23808a65889c..21b506fd2b67 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -222,6 +222,9 @@ int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw, int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, int vport, struct ifla_vf_stats *vf_stats); +struct mlx5_flow_handle * +mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport, + u32 sqn); struct mlx5_flow_spec; struct mlx5_esw_flow_attr; @@ -258,12 +261,6 @@ struct mlx5_esw_flow_attr { struct mlx5e_tc_flow_parse_attr *parse_attr; }; -int mlx5_eswitch_sqs2vport_start(struct mlx5_eswitch *esw, - struct mlx5_eswitch_rep *rep, - u16 *sqns_array, int sqns_num); -void mlx5_eswitch_sqs2vport_stop(struct mlx5_eswitch *esw, - struct mlx5_eswitch_rep *rep); - int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode); int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode); int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index aa20f51c0a99..90a30c51d92e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -302,7 +302,7 @@ out: return err; } -static struct mlx5_flow_handle * +struct mlx5_flow_handle * mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport, u32 sqn) { struct mlx5_flow_act flow_act = {0}; @@ -339,59 +339,6 @@ out: return flow_rule; } -void mlx5_eswitch_sqs2vport_stop(struct mlx5_eswitch *esw, - struct mlx5_eswitch_rep *rep) -{ - struct mlx5_esw_sq *esw_sq, *tmp; - - if (esw->mode != SRIOV_OFFLOADS) - return; - - list_for_each_entry_safe(esw_sq, tmp, &rep->vport_sqs_list, list) { - mlx5_del_flow_rules(esw_sq->send_to_vport_rule); - list_del(&esw_sq->list); - kfree(esw_sq); - } -} - -int mlx5_eswitch_sqs2vport_start(struct mlx5_eswitch *esw, - struct mlx5_eswitch_rep *rep, - u16 *sqns_array, int sqns_num) -{ - struct mlx5_flow_handle *flow_rule; - struct mlx5_esw_sq *esw_sq; - int err; - int i; - - if (esw->mode != SRIOV_OFFLOADS) - return 0; - - for (i = 0; i < sqns_num; i++) { - esw_sq = kzalloc(sizeof(*esw_sq), GFP_KERNEL); - if (!esw_sq) { - err = -ENOMEM; - goto out_err; - } - - /* Add re-inject rule to the PF/representor sqs */ - flow_rule = mlx5_eswitch_add_send_to_vport_rule(esw, - rep->vport, - sqns_array[i]); - if (IS_ERR(flow_rule)) { - err = PTR_ERR(flow_rule); - kfree(esw_sq); - goto out_err; - } - esw_sq->send_to_vport_rule = flow_rule; - list_add(&esw_sq->list, &rep->vport_sqs_list); - } - return 0; - -out_err: - mlx5_eswitch_sqs2vport_stop(esw, rep); - return err; -} - static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw) { struct mlx5_flow_act flow_act = {0}; -- cgit v1.2.3-59-g8ed1b From 159fe63922450183931429ef0b6c7548d49e5bcc Mon Sep 17 00:00:00 2001 From: Mark Bloch Date: Thu, 7 Dec 2017 15:36:59 +0000 Subject: net/mlx5: E-Switch, Create a dedicated send to vport rule deletion function In order for representors to send packets directly to VFs we use an E-Switch function which insert special rules into the HW. For symmetry create an E-Switch function that deletes these rules as well. Signed-off-by: Mark Bloch Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 1 + drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 19edaa155062..01bf4e3c8afa 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -199,7 +199,7 @@ static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw, return; list_for_each_entry_safe(esw_sq, tmp, &rep->vport_sqs_list, list) { - mlx5_del_flow_rules(esw_sq->send_to_vport_rule); + mlx5_eswitch_del_send_to_vport_rule(esw_sq->send_to_vport_rule); list_del(&esw_sq->list); kfree(esw_sq); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index 21b506fd2b67..9ed401225225 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -225,6 +225,7 @@ int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, struct mlx5_flow_handle * mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport, u32 sqn); +void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle *rule); struct mlx5_flow_spec; struct mlx5_esw_flow_attr; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 90a30c51d92e..121609b823c6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -339,6 +339,11 @@ out: return flow_rule; } +void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle *rule) +{ + mlx5_del_flow_rules(rule); +} + static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw) { struct mlx5_flow_act flow_act = {0}; -- cgit v1.2.3-59-g8ed1b From 5ed99fb421d4d5cd4cba613c1ab115585aa277d2 Mon Sep 17 00:00:00 2001 From: Mark Bloch Date: Thu, 7 Dec 2017 20:55:10 +0000 Subject: net/mlx5e: Move ethernet representors data into separate struct Ethernet representors have a need to store data which is applicable only for them. Create a priv void pointer in struct mlx5_eswitch_rep and move mlx5e to store the relevant data there. As part of this change we also initialize rep_if in mlx5e_rep_register_vf_vports() as otherwise the E-Switch code will copy a priv value which is garbage. We also rename mlx5_eswitch_get_uplink_netdev() to mlx5_eswitch_get_uplink_priv() and make it return void *. This way E-Switch code doesn't need to deal with net devices and we leave the task of getting it to mlx5e. Signed-off-by: Mark Bloch Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 58 ++++++++++++++-------- drivers/net/ethernet/mellanox/mlx5/core/en_rep.h | 9 ++++ drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 14 ++++-- drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 7 +-- .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 7 ++- 5 files changed, 60 insertions(+), 35 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 01bf4e3c8afa..3c74f0599ad3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -194,11 +194,13 @@ static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep) { struct mlx5_esw_sq *esw_sq, *tmp; + struct mlx5e_rep_priv *rpriv; if (esw->mode != SRIOV_OFFLOADS) return; - list_for_each_entry_safe(esw_sq, tmp, &rep->vport_sqs_list, list) { + rpriv = mlx5e_rep_to_rep_priv(rep); + list_for_each_entry_safe(esw_sq, tmp, &rpriv->vport_sqs_list, list) { mlx5_eswitch_del_send_to_vport_rule(esw_sq->send_to_vport_rule); list_del(&esw_sq->list); kfree(esw_sq); @@ -210,6 +212,7 @@ static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw, u16 *sqns_array, int sqns_num) { struct mlx5_flow_handle *flow_rule; + struct mlx5e_rep_priv *rpriv; struct mlx5_esw_sq *esw_sq; int err; int i; @@ -217,6 +220,7 @@ static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw, if (esw->mode != SRIOV_OFFLOADS) return 0; + rpriv = mlx5e_rep_to_rep_priv(rep); for (i = 0; i < sqns_num; i++) { esw_sq = kzalloc(sizeof(*esw_sq), GFP_KERNEL); if (!esw_sq) { @@ -234,7 +238,7 @@ static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw, goto out_err; } esw_sq->send_to_vport_rule = flow_rule; - list_add(&esw_sq->list, &rep->vport_sqs_list); + list_add(&esw_sq->list, &rpriv->vport_sqs_list); } return 0; @@ -291,7 +295,7 @@ static void mlx5e_rep_neigh_update_init_interval(struct mlx5e_rep_priv *rpriv) #endif unsigned long ipv4_interval = NEIGH_VAR(&arp_tbl.parms, DELAY_PROBE_TIME); - struct net_device *netdev = rpriv->rep->netdev; + struct net_device *netdev = rpriv->netdev; struct mlx5e_priv *priv = netdev_priv(netdev); rpriv->neigh_update.min_interval = min_t(unsigned long, ipv6_interval, ipv4_interval); @@ -312,7 +316,7 @@ static void mlx5e_rep_neigh_stats_work(struct work_struct *work) { struct mlx5e_rep_priv *rpriv = container_of(work, struct mlx5e_rep_priv, neigh_update.neigh_stats_work.work); - struct net_device *netdev = rpriv->rep->netdev; + struct net_device *netdev = rpriv->netdev; struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_neigh_hash_entry *nhe; @@ -408,7 +412,7 @@ static int mlx5e_rep_netevent_event(struct notifier_block *nb, struct mlx5e_rep_priv *rpriv = container_of(nb, struct mlx5e_rep_priv, neigh_update.netevent_nb); struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update; - struct net_device *netdev = rpriv->rep->netdev; + struct net_device *netdev = rpriv->netdev; struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_neigh_hash_entry *nhe = NULL; struct mlx5e_neigh m_neigh = {}; @@ -536,7 +540,7 @@ out_err: static void mlx5e_rep_neigh_cleanup(struct mlx5e_rep_priv *rpriv) { struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update; - struct mlx5e_priv *priv = netdev_priv(rpriv->rep->netdev); + struct mlx5e_priv *priv = netdev_priv(rpriv->netdev); unregister_netevent_notifier(&neigh_update->netevent_nb); @@ -957,7 +961,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv) err = PTR_ERR(flow_rule); goto err_destroy_direct_tirs; } - rep->vport_rx_rule = flow_rule; + rpriv->vport_rx_rule = flow_rule; err = mlx5e_tc_init(priv); if (err) @@ -966,7 +970,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv) return 0; err_del_flow_rule: - mlx5_del_flow_rules(rep->vport_rx_rule); + mlx5_del_flow_rules(rpriv->vport_rx_rule); err_destroy_direct_tirs: mlx5e_destroy_direct_tirs(priv); err_destroy_direct_rqts: @@ -977,10 +981,9 @@ err_destroy_direct_rqts: static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv) { struct mlx5e_rep_priv *rpriv = priv->ppriv; - struct mlx5_eswitch_rep *rep = rpriv->rep; mlx5e_tc_cleanup(priv); - mlx5_del_flow_rules(rep->vport_rx_rule); + mlx5_del_flow_rules(rpriv->vport_rx_rule); mlx5e_destroy_direct_tirs(priv); mlx5e_destroy_direct_rqts(priv); } @@ -1022,8 +1025,8 @@ static const struct mlx5e_profile mlx5e_rep_profile = { static int mlx5e_nic_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) { - struct mlx5e_priv *priv = netdev_priv(rep->netdev); - struct mlx5e_rep_priv *rpriv = priv->ppriv; + struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep); + struct mlx5e_priv *priv = netdev_priv(rpriv->netdev); int err; @@ -1047,8 +1050,8 @@ err_remove_sqs: static void mlx5e_nic_rep_unload(struct mlx5_eswitch_rep *rep) { - struct mlx5e_priv *priv = netdev_priv(rep->netdev); - struct mlx5e_rep_priv *rpriv = priv->ppriv; + struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep); + struct mlx5e_priv *priv = netdev_priv(rpriv->netdev); if (test_bit(MLX5E_STATE_OPENED, &priv->state)) mlx5e_remove_sqs_fwd_rules(priv); @@ -1063,6 +1066,7 @@ mlx5e_nic_rep_unload(struct mlx5_eswitch_rep *rep) static int mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) { + struct mlx5e_rep_priv *uplink_rpriv; struct mlx5e_rep_priv *rpriv; struct net_device *netdev; struct mlx5e_priv *upriv; @@ -1080,8 +1084,10 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) return -EINVAL; } - rep->netdev = netdev; + rpriv->netdev = netdev; rpriv->rep = rep; + rep->priv = rpriv; + INIT_LIST_HEAD(&rpriv->vport_sqs_list); err = mlx5e_attach_netdev(netdev_priv(netdev)); if (err) { @@ -1097,7 +1103,8 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) goto err_detach_netdev; } - upriv = netdev_priv(mlx5_eswitch_get_uplink_netdev(dev->priv.eswitch)); + uplink_rpriv = mlx5_eswitch_get_uplink_priv(dev->priv.eswitch); + upriv = netdev_priv(uplink_rpriv->netdev); err = tc_setup_cb_egdev_register(netdev, mlx5e_setup_tc_block_cb, upriv); if (err) @@ -1131,14 +1138,16 @@ err_destroy_netdev: static void mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep) { - struct net_device *netdev = rep->netdev; + struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep); + struct net_device *netdev = rpriv->netdev; struct mlx5e_priv *priv = netdev_priv(netdev); - struct mlx5e_rep_priv *rpriv = priv->ppriv; + struct mlx5e_rep_priv *uplink_rpriv; void *ppriv = priv->ppriv; struct mlx5e_priv *upriv; - unregister_netdev(rep->netdev); - upriv = netdev_priv(mlx5_eswitch_get_uplink_netdev(priv->mdev->priv.eswitch)); + unregister_netdev(netdev); + uplink_rpriv = mlx5_eswitch_get_uplink_priv(priv->mdev->priv.eswitch); + upriv = netdev_priv(uplink_rpriv->netdev); tc_setup_cb_egdev_unregister(netdev, mlx5e_setup_tc_block_cb, upriv); mlx5e_rep_neigh_cleanup(rpriv); @@ -1155,7 +1164,7 @@ static void mlx5e_rep_register_vf_vports(struct mlx5e_priv *priv) int vport; for (vport = 1; vport < total_vfs; vport++) { - struct mlx5_eswitch_rep rep; + struct mlx5_eswitch_rep rep = {}; rep.load = mlx5e_vport_rep_load; rep.unload = mlx5e_vport_rep_unload; @@ -1178,11 +1187,16 @@ void mlx5e_register_vport_reps(struct mlx5e_priv *priv) { struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_eswitch *esw = mdev->priv.eswitch; + struct mlx5e_rep_priv *rpriv; struct mlx5_eswitch_rep rep; + rpriv = priv->ppriv; + rpriv->netdev = priv->netdev; + rep.load = mlx5e_nic_rep_load; rep.unload = mlx5e_nic_rep_unload; - rep.netdev = priv->netdev; + rep.priv = rpriv; + INIT_LIST_HEAD(&rpriv->vport_sqs_list); mlx5_eswitch_register_vport_rep(esw, 0, &rep); /* UPLINK PF vport*/ mlx5e_rep_register_vf_vports(priv); /* VFs vports */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h index 5659ed9f51e6..8db68369367e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h @@ -56,8 +56,17 @@ struct mlx5e_neigh_update_table { struct mlx5e_rep_priv { struct mlx5_eswitch_rep *rep; struct mlx5e_neigh_update_table neigh_update; + struct net_device *netdev; + struct mlx5_flow_handle *vport_rx_rule; + struct list_head vport_sqs_list; }; +static inline +struct mlx5e_rep_priv *mlx5e_rep_to_rep_priv(struct mlx5_eswitch_rep *rep) +{ + return (struct mlx5e_rep_priv *)rep->priv; +} + struct mlx5e_neigh { struct net_device *dev; union { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 55979ec2e88a..f462496cce7a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -617,7 +617,8 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv, FLOW_DISSECTOR_KEY_ENC_PORTS, f->mask); struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; - struct net_device *up_dev = mlx5_eswitch_get_uplink_netdev(esw); + struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); + struct net_device *up_dev = uplink_rpriv->netdev; struct mlx5e_priv *up_priv = netdev_priv(up_dev); /* Full udp dst port must be given */ @@ -1507,6 +1508,7 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv, int *out_ttl) { struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; + struct mlx5e_rep_priv *uplink_rpriv; struct rtable *rt; struct neighbour *n = NULL; @@ -1520,9 +1522,10 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv, #else return -EOPNOTSUPP; #endif + uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); /* if the egress device isn't on the same HW e-switch, we use the uplink */ if (!switchdev_port_same_parent_id(priv->netdev, rt->dst.dev)) - *out_dev = mlx5_eswitch_get_uplink_netdev(esw); + *out_dev = uplink_rpriv->netdev; else *out_dev = rt->dst.dev; @@ -1543,6 +1546,7 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv, struct neighbour **out_n, int *out_ttl) { + struct mlx5e_rep_priv *uplink_rpriv; struct neighbour *n = NULL; struct dst_entry *dst; @@ -1557,9 +1561,10 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv, *out_ttl = ip6_dst_hoplimit(dst); + uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); /* if the egress device isn't on the same HW e-switch, we use the uplink */ if (!switchdev_port_same_parent_id(priv->netdev, dst->dev)) - *out_dev = mlx5_eswitch_get_uplink_netdev(esw); + *out_dev = uplink_rpriv->netdev; else *out_dev = dst->dev; #else @@ -1859,7 +1864,8 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow) { struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; - struct net_device *up_dev = mlx5_eswitch_get_uplink_netdev(esw); + struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); + struct net_device *up_dev = uplink_rpriv->netdev; unsigned short family = ip_tunnel_info_af(tun_info); struct mlx5e_priv *up_priv = netdev_priv(up_dev); struct mlx5_esw_flow_attr *attr = flow->esw_attr; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index 9ed401225225..3a21ea4e4d24 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -142,12 +142,9 @@ struct mlx5_eswitch_rep { int (*load)(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep); void (*unload)(struct mlx5_eswitch_rep *rep); + void *priv; u16 vport; u8 hw_id[ETH_ALEN]; - struct net_device *netdev; - - struct mlx5_flow_handle *vport_rx_rule; - struct list_head vport_sqs_list; u16 vlan; u32 vlan_refcount; bool valid; @@ -274,7 +271,7 @@ void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep); void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, int vport_index); -struct net_device *mlx5_eswitch_get_uplink_netdev(struct mlx5_eswitch *esw); +void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw); int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw, struct mlx5_esw_flow_attr *attr); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 121609b823c6..07f26c1986fc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -1130,9 +1130,8 @@ void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw, rep->load = __rep->load; rep->unload = __rep->unload; - rep->netdev = __rep->netdev; + rep->priv = __rep->priv; - INIT_LIST_HEAD(&rep->vport_sqs_list); rep->valid = true; } @@ -1150,12 +1149,12 @@ void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, rep->valid = false; } -struct net_device *mlx5_eswitch_get_uplink_netdev(struct mlx5_eswitch *esw) +void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw) { #define UPLINK_REP_INDEX 0 struct mlx5_esw_offload *offloads = &esw->offloads; struct mlx5_eswitch_rep *rep; rep = &offloads->vport_reps[UPLINK_REP_INDEX]; - return rep->netdev; + return rep->priv; } -- cgit v1.2.3-59-g8ed1b From a4b97ab4211fd0cf1011623c79fe2204dc023b96 Mon Sep 17 00:00:00 2001 From: Mark Bloch Date: Thu, 7 Dec 2017 21:25:57 +0000 Subject: net/mlx5: E-Switch, Create generic header struct to be used by representors Now that we don't store type dependent data in struct mlx5_eswitch_rep we can create a generic interface, and representor type. struct mlx5_eswitch_rep will store an array of interfaces, each interface is used by a different representor type. Once we moved to a more generic interface, rdma driver representors can be added and utilize the same mechanism as the Ethernet driver representors use. Signed-off-by: Mark Bloch Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 29 ++++----- drivers/net/ethernet/mellanox/mlx5/core/en_rep.h | 2 +- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 9 +-- drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 22 +++++-- .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 70 +++++++++++++++------- 5 files changed, 88 insertions(+), 44 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 3c74f0599ad3..5b2b673c0b13 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -1086,7 +1086,7 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) rpriv->netdev = netdev; rpriv->rep = rep; - rep->priv = rpriv; + rep->rep_if[REP_ETH].priv = rpriv; INIT_LIST_HEAD(&rpriv->vport_sqs_list); err = mlx5e_attach_netdev(netdev_priv(netdev)); @@ -1103,7 +1103,7 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) goto err_detach_netdev; } - uplink_rpriv = mlx5_eswitch_get_uplink_priv(dev->priv.eswitch); + uplink_rpriv = mlx5_eswitch_get_uplink_priv(dev->priv.eswitch, REP_ETH); upriv = netdev_priv(uplink_rpriv->netdev); err = tc_setup_cb_egdev_register(netdev, mlx5e_setup_tc_block_cb, upriv); @@ -1146,7 +1146,8 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep) struct mlx5e_priv *upriv; unregister_netdev(netdev); - uplink_rpriv = mlx5_eswitch_get_uplink_priv(priv->mdev->priv.eswitch); + uplink_rpriv = mlx5_eswitch_get_uplink_priv(priv->mdev->priv.eswitch, + REP_ETH); upriv = netdev_priv(uplink_rpriv->netdev); tc_setup_cb_egdev_unregister(netdev, mlx5e_setup_tc_block_cb, upriv); @@ -1164,11 +1165,11 @@ static void mlx5e_rep_register_vf_vports(struct mlx5e_priv *priv) int vport; for (vport = 1; vport < total_vfs; vport++) { - struct mlx5_eswitch_rep rep = {}; + struct mlx5_eswitch_rep_if rep_if = {}; - rep.load = mlx5e_vport_rep_load; - rep.unload = mlx5e_vport_rep_unload; - mlx5_eswitch_register_vport_rep(esw, vport, &rep); + rep_if.load = mlx5e_vport_rep_load; + rep_if.unload = mlx5e_vport_rep_unload; + mlx5_eswitch_register_vport_rep(esw, vport, &rep_if, REP_ETH); } } @@ -1180,24 +1181,24 @@ static void mlx5e_rep_unregister_vf_vports(struct mlx5e_priv *priv) int vport; for (vport = 1; vport < total_vfs; vport++) - mlx5_eswitch_unregister_vport_rep(esw, vport); + mlx5_eswitch_unregister_vport_rep(esw, vport, REP_ETH); } void mlx5e_register_vport_reps(struct mlx5e_priv *priv) { struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_eswitch *esw = mdev->priv.eswitch; + struct mlx5_eswitch_rep_if rep_if; struct mlx5e_rep_priv *rpriv; - struct mlx5_eswitch_rep rep; rpriv = priv->ppriv; rpriv->netdev = priv->netdev; - rep.load = mlx5e_nic_rep_load; - rep.unload = mlx5e_nic_rep_unload; - rep.priv = rpriv; + rep_if.load = mlx5e_nic_rep_load; + rep_if.unload = mlx5e_nic_rep_unload; + rep_if.priv = rpriv; INIT_LIST_HEAD(&rpriv->vport_sqs_list); - mlx5_eswitch_register_vport_rep(esw, 0, &rep); /* UPLINK PF vport*/ + mlx5_eswitch_register_vport_rep(esw, 0, &rep_if, REP_ETH); /* UPLINK PF vport*/ mlx5e_rep_register_vf_vports(priv); /* VFs vports */ } @@ -1208,7 +1209,7 @@ void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv) struct mlx5_eswitch *esw = mdev->priv.eswitch; mlx5e_rep_unregister_vf_vports(priv); /* VFs vports */ - mlx5_eswitch_unregister_vport_rep(esw, 0); /* UPLINK PF*/ + mlx5_eswitch_unregister_vport_rep(esw, 0, REP_ETH); /* UPLINK PF*/ } void *mlx5e_alloc_nic_rep_priv(struct mlx5_core_dev *mdev) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h index 8db68369367e..e4473a9ebd50 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h @@ -64,7 +64,7 @@ struct mlx5e_rep_priv { static inline struct mlx5e_rep_priv *mlx5e_rep_to_rep_priv(struct mlx5_eswitch_rep *rep) { - return (struct mlx5e_rep_priv *)rep->priv; + return (struct mlx5e_rep_priv *)rep->rep_if[REP_ETH].priv; } struct mlx5e_neigh { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index f462496cce7a..259e91e2d09a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -617,7 +617,7 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv, FLOW_DISSECTOR_KEY_ENC_PORTS, f->mask); struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; - struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); + struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); struct net_device *up_dev = uplink_rpriv->netdev; struct mlx5e_priv *up_priv = netdev_priv(up_dev); @@ -1522,7 +1522,7 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv, #else return -EOPNOTSUPP; #endif - uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); + uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); /* if the egress device isn't on the same HW e-switch, we use the uplink */ if (!switchdev_port_same_parent_id(priv->netdev, rt->dst.dev)) *out_dev = uplink_rpriv->netdev; @@ -1561,7 +1561,7 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv, *out_ttl = ip6_dst_hoplimit(dst); - uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); + uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); /* if the egress device isn't on the same HW e-switch, we use the uplink */ if (!switchdev_port_same_parent_id(priv->netdev, dst->dev)) *out_dev = uplink_rpriv->netdev; @@ -1864,7 +1864,8 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow) { struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; - struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); + struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, + REP_ETH); struct net_device *up_dev = uplink_rpriv->netdev; unsigned short family = ip_tunnel_info_af(tun_info); struct mlx5e_priv *up_priv = netdev_priv(up_dev); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index 3a21ea4e4d24..91175965df7f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -45,6 +45,11 @@ enum { SRIOV_OFFLOADS }; +enum { + REP_ETH, + NUM_REP_TYPES, +}; + #ifdef CONFIG_MLX5_ESWITCH #define MLX5_MAX_UC_PER_VPORT(dev) \ @@ -138,16 +143,21 @@ struct mlx5_esw_sq { struct list_head list; }; -struct mlx5_eswitch_rep { +struct mlx5_eswitch_rep; +struct mlx5_eswitch_rep_if { int (*load)(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep); void (*unload)(struct mlx5_eswitch_rep *rep); void *priv; + bool valid; +}; + +struct mlx5_eswitch_rep { + struct mlx5_eswitch_rep_if rep_if[NUM_REP_TYPES]; u16 vport; u8 hw_id[ETH_ALEN]; u16 vlan; u32 vlan_refcount; - bool valid; }; struct mlx5_esw_offload { @@ -268,10 +278,12 @@ int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap); int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap); void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw, int vport_index, - struct mlx5_eswitch_rep *rep); + struct mlx5_eswitch_rep_if *rep_if, + u8 rep_type); void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, - int vport_index); -void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw); + int vport_index, + u8 rep_type); +void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type); int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw, struct mlx5_esw_flow_attr *attr); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 07f26c1986fc..99f583a15cc3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -130,7 +130,7 @@ static int esw_set_global_vlan_pop(struct mlx5_eswitch *esw, u8 val) esw_debug(esw->dev, "%s applying global %s policy\n", __func__, val ? "pop" : "none"); for (vf_vport = 1; vf_vport < esw->enabled_vports; vf_vport++) { rep = &esw->offloads.vport_reps[vf_vport]; - if (!rep->valid) + if (!rep->rep_if[REP_ETH].valid) continue; err = __mlx5_eswitch_set_vport_vlan(esw, rep->vport, 0, 0, val); @@ -719,21 +719,31 @@ int esw_offloads_init_reps(struct mlx5_eswitch *esw) return 0; } -static void esw_offloads_unload_reps(struct mlx5_eswitch *esw, int nvports) +static void esw_offloads_unload_reps_type(struct mlx5_eswitch *esw, int nvports, + u8 rep_type) { struct mlx5_eswitch_rep *rep; int vport; for (vport = nvports - 1; vport >= 0; vport--) { rep = &esw->offloads.vport_reps[vport]; - if (!rep->valid) + if (!rep->rep_if[rep_type].valid) continue; - rep->unload(rep); + rep->rep_if[rep_type].unload(rep); } } -static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports) +static void esw_offloads_unload_reps(struct mlx5_eswitch *esw, int nvports) +{ + u8 rep_type = NUM_REP_TYPES; + + while (rep_type-- > 0) + esw_offloads_unload_reps_type(esw, nvports, rep_type); +} + +static int esw_offloads_load_reps_type(struct mlx5_eswitch *esw, int nvports, + u8 rep_type) { struct mlx5_eswitch_rep *rep; int vport; @@ -741,10 +751,10 @@ static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports) for (vport = 0; vport < nvports; vport++) { rep = &esw->offloads.vport_reps[vport]; - if (!rep->valid) + if (!rep->rep_if[rep_type].valid) continue; - err = rep->load(esw->dev, rep); + err = rep->rep_if[rep_type].load(esw->dev, rep); if (err) goto err_reps; } @@ -752,7 +762,26 @@ static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports) return 0; err_reps: - esw_offloads_unload_reps(esw, vport); + esw_offloads_unload_reps_type(esw, vport, rep_type); + return err; +} + +static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports) +{ + u8 rep_type = 0; + int err; + + for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++) { + err = esw_offloads_load_reps_type(esw, nvports, rep_type); + if (err) + goto err_reps; + } + + return err; + +err_reps: + while (rep_type-- > 0) + esw_offloads_unload_reps_type(esw, nvports, rep_type); return err; } @@ -1121,22 +1150,23 @@ int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap) void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw, int vport_index, - struct mlx5_eswitch_rep *__rep) + struct mlx5_eswitch_rep_if *__rep_if, + u8 rep_type) { struct mlx5_esw_offload *offloads = &esw->offloads; - struct mlx5_eswitch_rep *rep; + struct mlx5_eswitch_rep_if *rep_if; - rep = &offloads->vport_reps[vport_index]; + rep_if = &offloads->vport_reps[vport_index].rep_if[rep_type]; - rep->load = __rep->load; - rep->unload = __rep->unload; - rep->priv = __rep->priv; + rep_if->load = __rep_if->load; + rep_if->unload = __rep_if->unload; + rep_if->priv = __rep_if->priv; - rep->valid = true; + rep_if->valid = true; } void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, - int vport_index) + int vport_index, u8 rep_type) { struct mlx5_esw_offload *offloads = &esw->offloads; struct mlx5_eswitch_rep *rep; @@ -1144,17 +1174,17 @@ void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, rep = &offloads->vport_reps[vport_index]; if (esw->mode == SRIOV_OFFLOADS && esw->vports[vport_index].enabled) - rep->unload(rep); + rep->rep_if[rep_type].unload(rep); - rep->valid = false; + rep->rep_if[rep_type].valid = false; } -void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw) +void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type) { #define UPLINK_REP_INDEX 0 struct mlx5_esw_offload *offloads = &esw->offloads; struct mlx5_eswitch_rep *rep; rep = &offloads->vport_reps[UPLINK_REP_INDEX]; - return rep->priv; + return rep->rep_if[rep_type].priv; } -- cgit v1.2.3-59-g8ed1b From 2c47bf80e8b70a284b6926f3379109eed7d03ac7 Mon Sep 17 00:00:00 2001 From: Mark Bloch Date: Thu, 7 Dec 2017 21:39:52 +0000 Subject: net/mlx5e: E-Switch, Move send-to-vport rule struct to en_rep Move struct mlx5_esw_sq which keeps send-to-vport rule to from the eswitch code to mlx5e and rename it to better reflect where it belongs Signed-off-by: Mark Bloch Reviewed-by: Or Gerlitz Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 22 +++++++++++----------- drivers/net/ethernet/mellanox/mlx5/core/en_rep.h | 5 +++++ drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 5 ----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 5b2b673c0b13..c6a77f8e99a4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -193,17 +193,17 @@ int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr) static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep) { - struct mlx5_esw_sq *esw_sq, *tmp; + struct mlx5e_rep_sq *rep_sq, *tmp; struct mlx5e_rep_priv *rpriv; if (esw->mode != SRIOV_OFFLOADS) return; rpriv = mlx5e_rep_to_rep_priv(rep); - list_for_each_entry_safe(esw_sq, tmp, &rpriv->vport_sqs_list, list) { - mlx5_eswitch_del_send_to_vport_rule(esw_sq->send_to_vport_rule); - list_del(&esw_sq->list); - kfree(esw_sq); + list_for_each_entry_safe(rep_sq, tmp, &rpriv->vport_sqs_list, list) { + mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule); + list_del(&rep_sq->list); + kfree(rep_sq); } } @@ -213,7 +213,7 @@ static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw, { struct mlx5_flow_handle *flow_rule; struct mlx5e_rep_priv *rpriv; - struct mlx5_esw_sq *esw_sq; + struct mlx5e_rep_sq *rep_sq; int err; int i; @@ -222,8 +222,8 @@ static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw, rpriv = mlx5e_rep_to_rep_priv(rep); for (i = 0; i < sqns_num; i++) { - esw_sq = kzalloc(sizeof(*esw_sq), GFP_KERNEL); - if (!esw_sq) { + rep_sq = kzalloc(sizeof(*rep_sq), GFP_KERNEL); + if (!rep_sq) { err = -ENOMEM; goto out_err; } @@ -234,11 +234,11 @@ static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw, sqns_array[i]); if (IS_ERR(flow_rule)) { err = PTR_ERR(flow_rule); - kfree(esw_sq); + kfree(rep_sq); goto out_err; } - esw_sq->send_to_vport_rule = flow_rule; - list_add(&esw_sq->list, &rpriv->vport_sqs_list); + rep_sq->send_to_vport_rule = flow_rule; + list_add(&rep_sq->list, &rpriv->vport_sqs_list); } return 0; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h index e4473a9ebd50..b9b481f2833a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h @@ -133,6 +133,11 @@ struct mlx5e_encap_entry { int encap_size; }; +struct mlx5e_rep_sq { + struct mlx5_flow_handle *send_to_vport_rule; + struct list_head list; +}; + void *mlx5e_alloc_nic_rep_priv(struct mlx5_core_dev *mdev); void mlx5e_register_vport_reps(struct mlx5e_priv *priv); void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index 91175965df7f..3b481182f13a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -138,11 +138,6 @@ struct mlx5_eswitch_fdb { }; }; -struct mlx5_esw_sq { - struct mlx5_flow_handle *send_to_vport_rule; - struct list_head list; -}; - struct mlx5_eswitch_rep; struct mlx5_eswitch_rep_if { int (*load)(struct mlx5_core_dev *dev, -- cgit v1.2.3-59-g8ed1b From 18a89ab7668146a13c53685846a2f0598061e20f Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Thu, 26 Oct 2017 16:11:25 +0300 Subject: net/mlx5e: E-Switch, Use the name of static array instead of its address Using the address of a static array is the same as using its name (in this specific use-case), but it's confusing and makes the code less readable. Fixes: 1bd27b11c1df ("net/mlx5: Introduce E-switch QoS management") Fixes: bd77bf1cb595 ("net/mlx5: Add SRIOV VF max rate configuration support") Signed-off-by: Gal Pressman Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 6d4cbdb69823..cdf65ed8714c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1290,7 +1290,7 @@ static int esw_create_tsar(struct mlx5_eswitch *esw) err = mlx5_create_scheduling_element_cmd(dev, SCHEDULING_HIERARCHY_E_SWITCH, - &tsar_ctx, + tsar_ctx, &esw->qos.root_tsar_id); if (err) { esw_warn(esw->dev, "E-Switch create TSAR failed (%d)\n", err); @@ -1333,20 +1333,20 @@ static int esw_vport_enable_qos(struct mlx5_eswitch *esw, int vport_num, if (vport->qos.enabled) return -EEXIST; - MLX5_SET(scheduling_context, &sched_ctx, element_type, + MLX5_SET(scheduling_context, sched_ctx, element_type, SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT); - vport_elem = MLX5_ADDR_OF(scheduling_context, &sched_ctx, + vport_elem = MLX5_ADDR_OF(scheduling_context, sched_ctx, element_attributes); MLX5_SET(vport_element, vport_elem, vport_number, vport_num); - MLX5_SET(scheduling_context, &sched_ctx, parent_element_id, + MLX5_SET(scheduling_context, sched_ctx, parent_element_id, esw->qos.root_tsar_id); - MLX5_SET(scheduling_context, &sched_ctx, max_average_bw, + MLX5_SET(scheduling_context, sched_ctx, max_average_bw, initial_max_rate); - MLX5_SET(scheduling_context, &sched_ctx, bw_share, initial_bw_share); + MLX5_SET(scheduling_context, sched_ctx, bw_share, initial_bw_share); err = mlx5_create_scheduling_element_cmd(dev, SCHEDULING_HIERARCHY_E_SWITCH, - &sched_ctx, + sched_ctx, &vport->qos.esw_tsar_ix); if (err) { esw_warn(esw->dev, "E-Switch create TSAR vport element failed (vport=%d,err=%d)\n", @@ -1392,22 +1392,22 @@ static int esw_vport_qos_config(struct mlx5_eswitch *esw, int vport_num, if (!vport->qos.enabled) return -EIO; - MLX5_SET(scheduling_context, &sched_ctx, element_type, + MLX5_SET(scheduling_context, sched_ctx, element_type, SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT); - vport_elem = MLX5_ADDR_OF(scheduling_context, &sched_ctx, + vport_elem = MLX5_ADDR_OF(scheduling_context, sched_ctx, element_attributes); MLX5_SET(vport_element, vport_elem, vport_number, vport_num); - MLX5_SET(scheduling_context, &sched_ctx, parent_element_id, + MLX5_SET(scheduling_context, sched_ctx, parent_element_id, esw->qos.root_tsar_id); - MLX5_SET(scheduling_context, &sched_ctx, max_average_bw, + MLX5_SET(scheduling_context, sched_ctx, max_average_bw, max_rate); - MLX5_SET(scheduling_context, &sched_ctx, bw_share, bw_share); + MLX5_SET(scheduling_context, sched_ctx, bw_share, bw_share); bitmask |= MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_MAX_AVERAGE_BW; bitmask |= MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_BW_SHARE; err = mlx5_modify_scheduling_element_cmd(dev, SCHEDULING_HIERARCHY_E_SWITCH, - &sched_ctx, + sched_ctx, vport->qos.esw_tsar_ix, bitmask); if (err) { -- cgit v1.2.3-59-g8ed1b From 4484e2994887cf57815c8e55ac1f9eaf0036928e Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Wed, 29 Nov 2017 12:08:15 +0200 Subject: net/mlx5: Fix ingress/egress naming mistake The functions names do not represent their actions, switch the mistaken ingress/egress naming. Fixes: fba53f7b5719 ("net/mlx5: Introduce mlx5_flow_steering structure") Signed-off-by: Gal Pressman Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index c70fd663a633..5e786e29f93a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -2406,7 +2406,7 @@ out_err: return PTR_ERR(prio); } -static int init_ingress_acl_root_ns(struct mlx5_flow_steering *steering) +static int init_egress_acl_root_ns(struct mlx5_flow_steering *steering) { struct fs_prio *prio; @@ -2420,7 +2420,7 @@ static int init_ingress_acl_root_ns(struct mlx5_flow_steering *steering) return PTR_ERR_OR_ZERO(prio); } -static int init_egress_acl_root_ns(struct mlx5_flow_steering *steering) +static int init_ingress_acl_root_ns(struct mlx5_flow_steering *steering) { struct fs_prio *prio; -- cgit v1.2.3-59-g8ed1b From 9b93ab981e3bf62ff95a8cbb6faf652cd400decd Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Tue, 28 Nov 2017 11:58:51 +0200 Subject: net/mlx5: Separate ingress/egress namespaces for each vport Each vport has its own root flow table for the ACL flow tables and root flow table is per namespace, therefore we should create a namespace for each vport. Fixes: efdc810ba39d ("net/mlx5: Flow steering, Add vport ACL support") Signed-off-by: Gal Pressman Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 10 +- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 145 ++++++++++++++++++---- drivers/net/ethernet/mellanox/mlx5/core/fs_core.h | 4 +- include/linux/mlx5/fs.h | 4 + 4 files changed, 133 insertions(+), 30 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index cdf65ed8714c..7649e36653d9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -867,9 +867,10 @@ static int esw_vport_enable_egress_acl(struct mlx5_eswitch *esw, esw_debug(dev, "Create vport[%d] egress ACL log_max_size(%d)\n", vport->vport, MLX5_CAP_ESW_EGRESS_ACL(dev, log_max_ft_size)); - root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_EGRESS); + root_ns = mlx5_get_flow_vport_acl_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_EGRESS, + vport->vport); if (!root_ns) { - esw_warn(dev, "Failed to get E-Switch egress flow namespace\n"); + esw_warn(dev, "Failed to get E-Switch egress flow namespace for vport (%d)\n", vport->vport); return -EOPNOTSUPP; } @@ -984,9 +985,10 @@ static int esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw, esw_debug(dev, "Create vport[%d] ingress ACL log_max_size(%d)\n", vport->vport, MLX5_CAP_ESW_INGRESS_ACL(dev, log_max_ft_size)); - root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_INGRESS); + root_ns = mlx5_get_flow_vport_acl_namespace(dev, MLX5_FLOW_NAMESPACE_ESW_INGRESS, + vport->vport); if (!root_ns) { - esw_warn(dev, "Failed to get E-Switch ingress flow namespace\n"); + esw_warn(dev, "Failed to get E-Switch ingress flow namespace for vport (%d)\n", vport->vport); return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 5e786e29f93a..45e75b1010f7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -2014,16 +2014,6 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev, return &steering->fdb_root_ns->ns; else return NULL; - case MLX5_FLOW_NAMESPACE_ESW_EGRESS: - if (steering->esw_egress_root_ns) - return &steering->esw_egress_root_ns->ns; - else - return NULL; - case MLX5_FLOW_NAMESPACE_ESW_INGRESS: - if (steering->esw_ingress_root_ns) - return &steering->esw_ingress_root_ns->ns; - else - return NULL; case MLX5_FLOW_NAMESPACE_SNIFFER_RX: if (steering->sniffer_rx_root_ns) return &steering->sniffer_rx_root_ns->ns; @@ -2054,6 +2044,33 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev, } EXPORT_SYMBOL(mlx5_get_flow_namespace); +struct mlx5_flow_namespace *mlx5_get_flow_vport_acl_namespace(struct mlx5_core_dev *dev, + enum mlx5_flow_namespace_type type, + int vport) +{ + struct mlx5_flow_steering *steering = dev->priv.steering; + + if (!steering || vport >= MLX5_TOTAL_VPORTS(dev)) + return NULL; + + switch (type) { + case MLX5_FLOW_NAMESPACE_ESW_EGRESS: + if (steering->esw_egress_root_ns && + steering->esw_egress_root_ns[vport]) + return &steering->esw_egress_root_ns[vport]->ns; + else + return NULL; + case MLX5_FLOW_NAMESPACE_ESW_INGRESS: + if (steering->esw_ingress_root_ns && + steering->esw_ingress_root_ns[vport]) + return &steering->esw_ingress_root_ns[vport]->ns; + else + return NULL; + default: + return NULL; + } +} + static struct fs_prio *fs_create_prio(struct mlx5_flow_namespace *ns, unsigned int prio, int num_levels) { @@ -2331,13 +2348,41 @@ static void cleanup_root_ns(struct mlx5_flow_root_namespace *root_ns) clean_tree(&root_ns->ns.node); } +static void cleanup_egress_acls_root_ns(struct mlx5_core_dev *dev) +{ + struct mlx5_flow_steering *steering = dev->priv.steering; + int i; + + if (!steering->esw_egress_root_ns) + return; + + for (i = 0; i < MLX5_TOTAL_VPORTS(dev); i++) + cleanup_root_ns(steering->esw_egress_root_ns[i]); + + kfree(steering->esw_egress_root_ns); +} + +static void cleanup_ingress_acls_root_ns(struct mlx5_core_dev *dev) +{ + struct mlx5_flow_steering *steering = dev->priv.steering; + int i; + + if (!steering->esw_ingress_root_ns) + return; + + for (i = 0; i < MLX5_TOTAL_VPORTS(dev); i++) + cleanup_root_ns(steering->esw_ingress_root_ns[i]); + + kfree(steering->esw_ingress_root_ns); +} + void mlx5_cleanup_fs(struct mlx5_core_dev *dev) { struct mlx5_flow_steering *steering = dev->priv.steering; cleanup_root_ns(steering->root_ns); - cleanup_root_ns(steering->esw_egress_root_ns); - cleanup_root_ns(steering->esw_ingress_root_ns); + cleanup_egress_acls_root_ns(dev); + cleanup_ingress_acls_root_ns(dev); cleanup_root_ns(steering->fdb_root_ns); cleanup_root_ns(steering->sniffer_rx_root_ns); cleanup_root_ns(steering->sniffer_tx_root_ns); @@ -2406,34 +2451,86 @@ out_err: return PTR_ERR(prio); } -static int init_egress_acl_root_ns(struct mlx5_flow_steering *steering) +static int init_egress_acl_root_ns(struct mlx5_flow_steering *steering, int vport) { struct fs_prio *prio; - steering->esw_egress_root_ns = create_root_ns(steering, FS_FT_ESW_EGRESS_ACL); - if (!steering->esw_egress_root_ns) + steering->esw_egress_root_ns[vport] = create_root_ns(steering, FS_FT_ESW_EGRESS_ACL); + if (!steering->esw_egress_root_ns[vport]) return -ENOMEM; /* create 1 prio*/ - prio = fs_create_prio(&steering->esw_egress_root_ns->ns, 0, - MLX5_TOTAL_VPORTS(steering->dev)); + prio = fs_create_prio(&steering->esw_egress_root_ns[vport]->ns, 0, 1); return PTR_ERR_OR_ZERO(prio); } -static int init_ingress_acl_root_ns(struct mlx5_flow_steering *steering) +static int init_ingress_acl_root_ns(struct mlx5_flow_steering *steering, int vport) { struct fs_prio *prio; - steering->esw_ingress_root_ns = create_root_ns(steering, FS_FT_ESW_INGRESS_ACL); - if (!steering->esw_ingress_root_ns) + steering->esw_ingress_root_ns[vport] = create_root_ns(steering, FS_FT_ESW_INGRESS_ACL); + if (!steering->esw_ingress_root_ns[vport]) return -ENOMEM; /* create 1 prio*/ - prio = fs_create_prio(&steering->esw_ingress_root_ns->ns, 0, - MLX5_TOTAL_VPORTS(steering->dev)); + prio = fs_create_prio(&steering->esw_ingress_root_ns[vport]->ns, 0, 1); return PTR_ERR_OR_ZERO(prio); } +static int init_egress_acls_root_ns(struct mlx5_core_dev *dev) +{ + struct mlx5_flow_steering *steering = dev->priv.steering; + int err; + int i; + + steering->esw_egress_root_ns = kcalloc(MLX5_TOTAL_VPORTS(dev), + sizeof(*steering->esw_egress_root_ns), + GFP_KERNEL); + if (!steering->esw_egress_root_ns) + return -ENOMEM; + + for (i = 0; i < MLX5_TOTAL_VPORTS(dev); i++) { + err = init_egress_acl_root_ns(steering, i); + if (err) + goto cleanup_root_ns; + } + + return 0; + +cleanup_root_ns: + for (i--; i >= 0; i--) + cleanup_root_ns(steering->esw_egress_root_ns[i]); + kfree(steering->esw_egress_root_ns); + return err; +} + +static int init_ingress_acls_root_ns(struct mlx5_core_dev *dev) +{ + struct mlx5_flow_steering *steering = dev->priv.steering; + int err; + int i; + + steering->esw_ingress_root_ns = kcalloc(MLX5_TOTAL_VPORTS(dev), + sizeof(*steering->esw_ingress_root_ns), + GFP_KERNEL); + if (!steering->esw_ingress_root_ns) + return -ENOMEM; + + for (i = 0; i < MLX5_TOTAL_VPORTS(dev); i++) { + err = init_ingress_acl_root_ns(steering, i); + if (err) + goto cleanup_root_ns; + } + + return 0; + +cleanup_root_ns: + for (i--; i >= 0; i--) + cleanup_root_ns(steering->esw_ingress_root_ns[i]); + kfree(steering->esw_ingress_root_ns); + return err; +} + int mlx5_init_fs(struct mlx5_core_dev *dev) { struct mlx5_flow_steering *steering; @@ -2476,12 +2573,12 @@ int mlx5_init_fs(struct mlx5_core_dev *dev) goto err; } if (MLX5_CAP_ESW_EGRESS_ACL(dev, ft_support)) { - err = init_egress_acl_root_ns(steering); + err = init_egress_acls_root_ns(dev); if (err) goto err; } if (MLX5_CAP_ESW_INGRESS_ACL(dev, ft_support)) { - err = init_ingress_acl_root_ns(steering); + err = init_ingress_acls_root_ns(dev); if (err) goto err; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h index 397d24a621a4..3e571045626f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h @@ -71,8 +71,8 @@ struct mlx5_flow_steering { struct kmem_cache *ftes_cache; struct mlx5_flow_root_namespace *root_ns; struct mlx5_flow_root_namespace *fdb_root_ns; - struct mlx5_flow_root_namespace *esw_egress_root_ns; - struct mlx5_flow_root_namespace *esw_ingress_root_ns; + struct mlx5_flow_root_namespace **esw_egress_root_ns; + struct mlx5_flow_root_namespace **esw_ingress_root_ns; struct mlx5_flow_root_namespace *sniffer_tx_root_ns; struct mlx5_flow_root_namespace *sniffer_rx_root_ns; }; diff --git a/include/linux/mlx5/fs.h b/include/linux/mlx5/fs.h index b25e7baa273e..a0b48afcb422 100644 --- a/include/linux/mlx5/fs.h +++ b/include/linux/mlx5/fs.h @@ -95,6 +95,10 @@ struct mlx5_flow_destination { struct mlx5_flow_namespace * mlx5_get_flow_namespace(struct mlx5_core_dev *dev, enum mlx5_flow_namespace_type type); +struct mlx5_flow_namespace * +mlx5_get_flow_vport_acl_namespace(struct mlx5_core_dev *dev, + enum mlx5_flow_namespace_type type, + int vport); struct mlx5_flow_table * mlx5_create_auto_grouped_flow_table(struct mlx5_flow_namespace *ns, -- cgit v1.2.3-59-g8ed1b