Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-mlx5-refactor-esw-qos-to-support-generalized-operations'

Tariq Toukan says:

====================
net/mlx5: Refactor esw QoS to support generalized operations

This patch series from the team to mlx5 core driver consists of one main
QoS part followed by small misc patches.

This main part (patches 1 to 11) by Carolina refactors the QoS handling
to generalize operations on scheduling groups and vports. These changes
are necessary to support new features that will extend group
functionality, introduce new group types, and support deeper
hierarchies.

Additionally, this refactor updates the terminology from "group" to
"node" to better reflect the hardware’s rate hierarchy and its use
of scheduling element nodes.

Simplify group scheduling element creation:
- net/mlx5: Refactor QoS group scheduling element creation

Refactor to support generalized operations for QoS:
- net/mlx5: Introduce node type to rate group structure
- net/mlx5: Add parent group support in rate group structure
- net/mlx5: Restrict domain list insertion to root TSAR ancestors
- net/mlx5: Rename vport QoS group reference to parent
- net/mlx5: Introduce node struct and rename group terminology to node
- net/mlx5: Refactor vport scheduling element creation function
- net/mlx5: Refactor vport QoS to use scheduling node structure
- net/mlx5: Remove vport QoS enabled flag

Support generalized operations for QoS elements:
- net/mlx5: Simplify QoS scheduling element configuration
- net/mlx5: Generalize QoS operations for nodes and vports

On top, patch 12 by Moshe handles FW request to move to drop mode.

In patch 13, Benjamin Poirier removes an empty eswitch flow table when
not used, which improves packet processing performance.

Patches 14 and 15 by Moshe are small field renamings as preparation for
future fields addition to these structures.

Series generated against:
commit c531f2269a53 ("net: bcmasp: enable SW timestamping")
====================

Link: https://patch.msgid.link/20241016173617.217736-1-tariqt@nvidia.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+436 -399
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c
··· 318 318 } 319 319 320 320 actions[num_actions++] = smfs_rule->count_action; 321 - actions[num_actions++] = attr->modify_hdr->action.dr_action; 321 + actions[num_actions++] = attr->modify_hdr->fs_dr_action.dr_action; 322 322 actions[num_actions++] = fs_smfs->fwd_action; 323 323 324 324 nat = (attr->ft == fs_smfs->ct_nat); ··· 379 379 struct mlx5dr_rule *rule; 380 380 381 381 actions[0] = smfs_rule->count_action; 382 - actions[1] = attr->modify_hdr->action.dr_action; 382 + actions[1] = attr->modify_hdr->fs_dr_action.dr_action; 383 383 actions[2] = fs_smfs->fwd_action; 384 384 385 385 rule = mlx5_smfs_rule_create(smfs_rule->smfs_matcher->dr_matcher, spec,
+27 -26
drivers/net/ethernet/mellanox/mlx5/core/esw/diag/qos_tracepoint.h
··· 9 9 10 10 #include <linux/tracepoint.h> 11 11 #include "eswitch.h" 12 + #include "qos.h" 12 13 13 14 TRACE_EVENT(mlx5_esw_vport_qos_destroy, 14 15 TP_PROTO(const struct mlx5_core_dev *dev, const struct mlx5_vport *vport), ··· 20 19 ), 21 20 TP_fast_assign(__assign_str(devname); 22 21 __entry->vport_id = vport->vport; 23 - __entry->sched_elem_ix = vport->qos.esw_sched_elem_ix; 22 + __entry->sched_elem_ix = mlx5_esw_qos_vport_get_sched_elem_ix(vport); 24 23 ), 25 24 TP_printk("(%s) vport=%hu sched_elem_ix=%u\n", 26 25 __get_str(devname), __entry->vport_id, __entry->sched_elem_ix ··· 36 35 __field(unsigned int, sched_elem_ix) 37 36 __field(unsigned int, bw_share) 38 37 __field(unsigned int, max_rate) 39 - __field(void *, group) 38 + __field(void *, parent) 40 39 ), 41 40 TP_fast_assign(__assign_str(devname); 42 41 __entry->vport_id = vport->vport; 43 - __entry->sched_elem_ix = vport->qos.esw_sched_elem_ix; 42 + __entry->sched_elem_ix = mlx5_esw_qos_vport_get_sched_elem_ix(vport); 44 43 __entry->bw_share = bw_share; 45 44 __entry->max_rate = max_rate; 46 - __entry->group = vport->qos.group; 45 + __entry->parent = mlx5_esw_qos_vport_get_parent(vport); 47 46 ), 48 - TP_printk("(%s) vport=%hu sched_elem_ix=%u bw_share=%u, max_rate=%u group=%p\n", 47 + TP_printk("(%s) vport=%hu sched_elem_ix=%u bw_share=%u, max_rate=%u parent=%p\n", 49 48 __get_str(devname), __entry->vport_id, __entry->sched_elem_ix, 50 - __entry->bw_share, __entry->max_rate, __entry->group 49 + __entry->bw_share, __entry->max_rate, __entry->parent 51 50 ) 52 51 ); 53 52 ··· 63 62 TP_ARGS(dev, vport, bw_share, max_rate) 64 63 ); 65 64 66 - DECLARE_EVENT_CLASS(mlx5_esw_group_qos_template, 65 + DECLARE_EVENT_CLASS(mlx5_esw_node_qos_template, 67 66 TP_PROTO(const struct mlx5_core_dev *dev, 68 - const struct mlx5_esw_rate_group *group, 67 + const struct mlx5_esw_sched_node *node, 69 68 unsigned int tsar_ix), 70 - TP_ARGS(dev, group, tsar_ix), 69 + TP_ARGS(dev, node, tsar_ix), 71 70 TP_STRUCT__entry(__string(devname, dev_name(dev->device)) 72 - __field(const void *, group) 71 + __field(const void *, node) 73 72 __field(unsigned int, tsar_ix) 74 73 ), 75 74 TP_fast_assign(__assign_str(devname); 76 - __entry->group = group; 75 + __entry->node = node; 77 76 __entry->tsar_ix = tsar_ix; 78 77 ), 79 - TP_printk("(%s) group=%p tsar_ix=%u\n", 80 - __get_str(devname), __entry->group, __entry->tsar_ix 78 + TP_printk("(%s) node=%p tsar_ix=%u\n", 79 + __get_str(devname), __entry->node, __entry->tsar_ix 81 80 ) 82 81 ); 83 82 84 - DEFINE_EVENT(mlx5_esw_group_qos_template, mlx5_esw_group_qos_create, 83 + DEFINE_EVENT(mlx5_esw_node_qos_template, mlx5_esw_node_qos_create, 85 84 TP_PROTO(const struct mlx5_core_dev *dev, 86 - const struct mlx5_esw_rate_group *group, 85 + const struct mlx5_esw_sched_node *node, 87 86 unsigned int tsar_ix), 88 - TP_ARGS(dev, group, tsar_ix) 87 + TP_ARGS(dev, node, tsar_ix) 89 88 ); 90 89 91 - DEFINE_EVENT(mlx5_esw_group_qos_template, mlx5_esw_group_qos_destroy, 90 + DEFINE_EVENT(mlx5_esw_node_qos_template, mlx5_esw_node_qos_destroy, 92 91 TP_PROTO(const struct mlx5_core_dev *dev, 93 - const struct mlx5_esw_rate_group *group, 92 + const struct mlx5_esw_sched_node *node, 94 93 unsigned int tsar_ix), 95 - TP_ARGS(dev, group, tsar_ix) 94 + TP_ARGS(dev, node, tsar_ix) 96 95 ); 97 96 98 - TRACE_EVENT(mlx5_esw_group_qos_config, 97 + TRACE_EVENT(mlx5_esw_node_qos_config, 99 98 TP_PROTO(const struct mlx5_core_dev *dev, 100 - const struct mlx5_esw_rate_group *group, 99 + const struct mlx5_esw_sched_node *node, 101 100 unsigned int tsar_ix, u32 bw_share, u32 max_rate), 102 - TP_ARGS(dev, group, tsar_ix, bw_share, max_rate), 101 + TP_ARGS(dev, node, tsar_ix, bw_share, max_rate), 103 102 TP_STRUCT__entry(__string(devname, dev_name(dev->device)) 104 - __field(const void *, group) 103 + __field(const void *, node) 105 104 __field(unsigned int, tsar_ix) 106 105 __field(unsigned int, bw_share) 107 106 __field(unsigned int, max_rate) 108 107 ), 109 108 TP_fast_assign(__assign_str(devname); 110 - __entry->group = group; 109 + __entry->node = node; 111 110 __entry->tsar_ix = tsar_ix; 112 111 __entry->bw_share = bw_share; 113 112 __entry->max_rate = max_rate; 114 113 ), 115 - TP_printk("(%s) group=%p tsar_ix=%u bw_share=%u max_rate=%u\n", 116 - __get_str(devname), __entry->group, __entry->tsar_ix, 114 + TP_printk("(%s) node=%p tsar_ix=%u bw_share=%u max_rate=%u\n", 115 + __get_str(devname), __entry->node, __entry->tsar_ix, 117 116 __entry->bw_share, __entry->max_rate 118 117 ) 119 118 );
+13 -14
drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c
··· 176 176 177 177 static int esw_create_legacy_table(struct mlx5_eswitch *esw) 178 178 { 179 - int err; 180 - 181 179 memset(&esw->fdb_table.legacy, 0, sizeof(struct legacy_fdb)); 182 180 atomic64_set(&esw->user_count, 0); 183 181 184 - err = esw_create_legacy_vepa_table(esw); 185 - if (err) 186 - return err; 187 - 188 - err = esw_create_legacy_fdb_table(esw); 189 - if (err) 190 - esw_destroy_legacy_vepa_table(esw); 191 - 192 - return err; 182 + return esw_create_legacy_fdb_table(esw); 193 183 } 194 184 195 185 static void esw_cleanup_vepa_rules(struct mlx5_eswitch *esw) ··· 249 259 250 260 if (!setting) { 251 261 esw_cleanup_vepa_rules(esw); 262 + esw_destroy_legacy_vepa_table(esw); 252 263 return 0; 253 264 } 254 265 255 266 if (esw->fdb_table.legacy.vepa_uplink_rule) 256 267 return 0; 257 268 269 + err = esw_create_legacy_vepa_table(esw); 270 + if (err) 271 + return err; 272 + 258 273 spec = kvzalloc(sizeof(*spec), GFP_KERNEL); 259 - if (!spec) 260 - return -ENOMEM; 274 + if (!spec) { 275 + err = -ENOMEM; 276 + goto out; 277 + } 261 278 262 279 /* Uplink rule forward uplink traffic to FDB */ 263 280 misc = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters); ··· 300 303 301 304 out: 302 305 kvfree(spec); 303 - if (err) 306 + if (err) { 304 307 esw_cleanup_vepa_rules(esw); 308 + esw_destroy_legacy_vepa_table(esw); 309 + } 305 310 return err; 306 311 } 307 312
+349 -322
drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
··· 11 11 /* Minimum supported BW share value by the HW is 1 Mbit/sec */ 12 12 #define MLX5_MIN_BW_SHARE 1 13 13 14 - /* Holds rate groups associated with an E-Switch. */ 14 + /* Holds rate nodes associated with an E-Switch. */ 15 15 struct mlx5_qos_domain { 16 16 /* Serializes access to all qos changes in the qos domain. */ 17 17 struct mutex lock; 18 - /* List of all mlx5_esw_rate_groups. */ 19 - struct list_head groups; 18 + /* List of all mlx5_esw_sched_nodes. */ 19 + struct list_head nodes; 20 20 }; 21 21 22 22 static void esw_qos_lock(struct mlx5_eswitch *esw) ··· 43 43 return NULL; 44 44 45 45 mutex_init(&qos_domain->lock); 46 - INIT_LIST_HEAD(&qos_domain->groups); 46 + INIT_LIST_HEAD(&qos_domain->nodes); 47 47 48 48 return qos_domain; 49 49 } ··· 61 61 esw->qos.domain = NULL; 62 62 } 63 63 64 - struct mlx5_esw_rate_group { 65 - u32 tsar_ix; 64 + enum sched_node_type { 65 + SCHED_NODE_TYPE_VPORTS_TSAR, 66 + SCHED_NODE_TYPE_VPORT, 67 + }; 68 + 69 + static const char * const sched_node_type_str[] = { 70 + [SCHED_NODE_TYPE_VPORTS_TSAR] = "vports TSAR", 71 + [SCHED_NODE_TYPE_VPORT] = "vport", 72 + }; 73 + 74 + struct mlx5_esw_sched_node { 75 + u32 ix; 66 76 /* Bandwidth parameters. */ 67 77 u32 max_rate; 68 78 u32 min_rate; 69 - /* A computed value indicating relative min_rate between group members. */ 79 + /* A computed value indicating relative min_rate between node's children. */ 70 80 u32 bw_share; 71 - /* Membership in the qos domain 'groups' list. */ 72 - struct list_head parent_entry; 73 - /* The eswitch this group belongs to. */ 81 + /* The parent node in the rate hierarchy. */ 82 + struct mlx5_esw_sched_node *parent; 83 + /* Entry in the parent node's children list. */ 84 + struct list_head entry; 85 + /* The type of this node in the rate hierarchy. */ 86 + enum sched_node_type type; 87 + /* The eswitch this node belongs to. */ 74 88 struct mlx5_eswitch *esw; 75 - /* Vport members of this group.*/ 76 - struct list_head members; 89 + /* The children nodes of this node, empty list for leaf nodes. */ 90 + struct list_head children; 91 + /* Valid only if this node is associated with a vport. */ 92 + struct mlx5_vport *vport; 77 93 }; 78 94 79 - static void esw_qos_vport_set_group(struct mlx5_vport *vport, struct mlx5_esw_rate_group *group) 95 + static void 96 + esw_qos_node_set_parent(struct mlx5_esw_sched_node *node, struct mlx5_esw_sched_node *parent) 80 97 { 81 - list_del_init(&vport->qos.group_entry); 82 - vport->qos.group = group; 83 - list_add_tail(&vport->qos.group_entry, &group->members); 98 + list_del_init(&node->entry); 99 + node->parent = parent; 100 + list_add_tail(&node->entry, &parent->children); 101 + node->esw = parent->esw; 84 102 } 85 103 86 - static int esw_qos_sched_elem_config(struct mlx5_core_dev *dev, u32 sched_elem_ix, 87 - u32 max_rate, u32 bw_share) 104 + u32 mlx5_esw_qos_vport_get_sched_elem_ix(const struct mlx5_vport *vport) 105 + { 106 + if (!vport->qos.sched_node) 107 + return 0; 108 + 109 + return vport->qos.sched_node->ix; 110 + } 111 + 112 + struct mlx5_esw_sched_node * 113 + mlx5_esw_qos_vport_get_parent(const struct mlx5_vport *vport) 114 + { 115 + if (!vport->qos.sched_node) 116 + return NULL; 117 + 118 + return vport->qos.sched_node->parent; 119 + } 120 + 121 + static void esw_qos_sched_elem_config_warn(struct mlx5_esw_sched_node *node, int err) 122 + { 123 + if (node->vport) { 124 + esw_warn(node->esw->dev, 125 + "E-Switch modify %s scheduling element failed (vport=%d,err=%d)\n", 126 + sched_node_type_str[node->type], node->vport->vport, err); 127 + return; 128 + } 129 + 130 + esw_warn(node->esw->dev, 131 + "E-Switch modify %s scheduling element failed (err=%d)\n", 132 + sched_node_type_str[node->type], err); 133 + } 134 + 135 + static int esw_qos_sched_elem_config(struct mlx5_esw_sched_node *node, u32 max_rate, u32 bw_share, 136 + struct netlink_ext_ack *extack) 88 137 { 89 138 u32 sched_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {}; 139 + struct mlx5_core_dev *dev = node->esw->dev; 90 140 u32 bitmask = 0; 141 + int err; 91 142 92 143 if (!MLX5_CAP_GEN(dev, qos) || !MLX5_CAP_QOS(dev, esw_scheduling)) 93 144 return -EOPNOTSUPP; ··· 148 97 bitmask |= MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_MAX_AVERAGE_BW; 149 98 bitmask |= MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_BW_SHARE; 150 99 151 - return mlx5_modify_scheduling_element_cmd(dev, 152 - SCHEDULING_HIERARCHY_E_SWITCH, 153 - sched_ctx, 154 - sched_elem_ix, 155 - bitmask); 156 - } 157 - 158 - static int esw_qos_group_config(struct mlx5_esw_rate_group *group, 159 - u32 max_rate, u32 bw_share, struct netlink_ext_ack *extack) 160 - { 161 - struct mlx5_core_dev *dev = group->esw->dev; 162 - int err; 163 - 164 - err = esw_qos_sched_elem_config(dev, group->tsar_ix, max_rate, bw_share); 165 - if (err) 166 - NL_SET_ERR_MSG_MOD(extack, "E-Switch modify group TSAR element failed"); 167 - 168 - trace_mlx5_esw_group_qos_config(dev, group, group->tsar_ix, bw_share, max_rate); 169 - 170 - return err; 171 - } 172 - 173 - static int esw_qos_vport_config(struct mlx5_vport *vport, 174 - u32 max_rate, u32 bw_share, 175 - struct netlink_ext_ack *extack) 176 - { 177 - struct mlx5_core_dev *dev = vport->qos.group->esw->dev; 178 - int err; 179 - 180 - err = esw_qos_sched_elem_config(dev, vport->qos.esw_sched_elem_ix, max_rate, bw_share); 100 + err = mlx5_modify_scheduling_element_cmd(dev, 101 + SCHEDULING_HIERARCHY_E_SWITCH, 102 + sched_ctx, 103 + node->ix, 104 + bitmask); 181 105 if (err) { 182 - esw_warn(dev, 183 - "E-Switch modify vport scheduling element failed (vport=%d,err=%d)\n", 184 - vport->vport, err); 185 - NL_SET_ERR_MSG_MOD(extack, "E-Switch modify vport scheduling element failed"); 106 + esw_qos_sched_elem_config_warn(node, err); 107 + NL_SET_ERR_MSG_MOD(extack, "E-Switch modify scheduling element failed"); 108 + 186 109 return err; 187 110 } 188 111 189 - trace_mlx5_esw_vport_qos_config(dev, vport, bw_share, max_rate); 112 + if (node->type == SCHED_NODE_TYPE_VPORTS_TSAR) 113 + trace_mlx5_esw_node_qos_config(dev, node, node->ix, bw_share, max_rate); 114 + else if (node->type == SCHED_NODE_TYPE_VPORT) 115 + trace_mlx5_esw_vport_qos_config(dev, node->vport, bw_share, max_rate); 190 116 191 117 return 0; 192 118 } 193 119 194 - static u32 esw_qos_calculate_group_min_rate_divider(struct mlx5_esw_rate_group *group) 120 + static u32 esw_qos_calculate_min_rate_divider(struct mlx5_eswitch *esw, 121 + struct mlx5_esw_sched_node *parent) 195 122 { 196 - u32 fw_max_bw_share = MLX5_CAP_QOS(group->esw->dev, max_tsar_bw_share); 197 - struct mlx5_vport *vport; 123 + struct list_head *nodes = parent ? &parent->children : &esw->qos.domain->nodes; 124 + u32 fw_max_bw_share = MLX5_CAP_QOS(esw->dev, max_tsar_bw_share); 125 + struct mlx5_esw_sched_node *node; 198 126 u32 max_guarantee = 0; 199 127 200 - /* Find max min_rate across all vports in this group. 128 + /* Find max min_rate across all nodes. 201 129 * This will correspond to fw_max_bw_share in the final bw_share calculation. 202 130 */ 203 - list_for_each_entry(vport, &group->members, qos.group_entry) { 204 - if (vport->qos.min_rate > max_guarantee) 205 - max_guarantee = vport->qos.min_rate; 131 + list_for_each_entry(node, nodes, entry) { 132 + if (node->esw == esw && node->ix != esw->qos.root_tsar_ix && 133 + node->min_rate > max_guarantee) 134 + max_guarantee = node->min_rate; 206 135 } 207 136 208 137 if (max_guarantee) 209 138 return max_t(u32, max_guarantee / fw_max_bw_share, 1); 210 139 211 - /* If vports max min_rate divider is 0 but their group has bw_share 212 - * configured, then set bw_share for vports to minimal value. 140 + /* If nodes max min_rate divider is 0 but their parent has bw_share 141 + * configured, then set bw_share for nodes to minimal value. 213 142 */ 214 - if (group->bw_share) 143 + 144 + if (parent && parent->bw_share) 215 145 return 1; 216 146 217 - /* A divider of 0 sets bw_share for all group vports to 0, 218 - * effectively disabling min guarantees. 219 - */ 220 - return 0; 221 - } 222 - 223 - static u32 esw_qos_calculate_min_rate_divider(struct mlx5_eswitch *esw) 224 - { 225 - u32 fw_max_bw_share = MLX5_CAP_QOS(esw->dev, max_tsar_bw_share); 226 - struct mlx5_esw_rate_group *group; 227 - u32 max_guarantee = 0; 228 - 229 - /* Find max min_rate across all esw groups. 230 - * This will correspond to fw_max_bw_share in the final bw_share calculation. 231 - */ 232 - list_for_each_entry(group, &esw->qos.domain->groups, parent_entry) { 233 - if (group->esw == esw && group->tsar_ix != esw->qos.root_tsar_ix && 234 - group->min_rate > max_guarantee) 235 - max_guarantee = group->min_rate; 236 - } 237 - 238 - if (max_guarantee) 239 - return max_t(u32, max_guarantee / fw_max_bw_share, 1); 240 - 241 - /* If no group has min_rate configured, a divider of 0 sets all 242 - * groups' bw_share to 0, effectively disabling min guarantees. 147 + /* If the node nodes has min_rate configured, a divider of 0 sets all 148 + * nodes' bw_share to 0, effectively disabling min guarantees. 243 149 */ 244 150 return 0; 245 151 } ··· 208 200 return min_t(u32, max_t(u32, DIV_ROUND_UP(min_rate, divider), MLX5_MIN_BW_SHARE), fw_max); 209 201 } 210 202 211 - static int esw_qos_normalize_group_min_rate(struct mlx5_esw_rate_group *group, 212 - struct netlink_ext_ack *extack) 203 + static int esw_qos_update_sched_node_bw_share(struct mlx5_esw_sched_node *node, 204 + u32 divider, 205 + struct netlink_ext_ack *extack) 213 206 { 214 - u32 fw_max_bw_share = MLX5_CAP_QOS(group->esw->dev, max_tsar_bw_share); 215 - u32 divider = esw_qos_calculate_group_min_rate_divider(group); 216 - struct mlx5_vport *vport; 207 + u32 fw_max_bw_share = MLX5_CAP_QOS(node->esw->dev, max_tsar_bw_share); 217 208 u32 bw_share; 218 209 int err; 219 210 220 - list_for_each_entry(vport, &group->members, qos.group_entry) { 221 - bw_share = esw_qos_calc_bw_share(vport->qos.min_rate, divider, fw_max_bw_share); 211 + bw_share = esw_qos_calc_bw_share(node->min_rate, divider, fw_max_bw_share); 222 212 223 - if (bw_share == vport->qos.bw_share) 224 - continue; 213 + if (bw_share == node->bw_share) 214 + return 0; 225 215 226 - err = esw_qos_vport_config(vport, vport->qos.max_rate, bw_share, extack); 227 - if (err) 228 - return err; 216 + err = esw_qos_sched_elem_config(node, node->max_rate, bw_share, extack); 217 + if (err) 218 + return err; 229 219 230 - vport->qos.bw_share = bw_share; 231 - } 220 + node->bw_share = bw_share; 232 221 233 - return 0; 222 + return err; 234 223 } 235 224 236 - static int esw_qos_normalize_min_rate(struct mlx5_eswitch *esw, struct netlink_ext_ack *extack) 225 + static int esw_qos_normalize_min_rate(struct mlx5_eswitch *esw, 226 + struct mlx5_esw_sched_node *parent, 227 + struct netlink_ext_ack *extack) 237 228 { 238 - u32 fw_max_bw_share = MLX5_CAP_QOS(esw->dev, max_tsar_bw_share); 239 - u32 divider = esw_qos_calculate_min_rate_divider(esw); 240 - struct mlx5_esw_rate_group *group; 241 - u32 bw_share; 242 - int err; 229 + struct list_head *nodes = parent ? &parent->children : &esw->qos.domain->nodes; 230 + u32 divider = esw_qos_calculate_min_rate_divider(esw, parent); 231 + struct mlx5_esw_sched_node *node; 243 232 244 - list_for_each_entry(group, &esw->qos.domain->groups, parent_entry) { 245 - if (group->esw != esw || group->tsar_ix == esw->qos.root_tsar_ix) 246 - continue; 247 - bw_share = esw_qos_calc_bw_share(group->min_rate, divider, fw_max_bw_share); 233 + list_for_each_entry(node, nodes, entry) { 234 + int err; 248 235 249 - if (bw_share == group->bw_share) 236 + if (node->esw != esw || node->ix == esw->qos.root_tsar_ix) 250 237 continue; 251 238 252 - err = esw_qos_group_config(group, group->max_rate, bw_share, extack); 239 + err = esw_qos_update_sched_node_bw_share(node, divider, extack); 253 240 if (err) 254 241 return err; 255 242 256 - group->bw_share = bw_share; 243 + if (list_empty(&node->children)) 244 + continue; 257 245 258 - /* All the group's vports need to be set with default bw_share 259 - * to enable them with QOS 260 - */ 261 - err = esw_qos_normalize_group_min_rate(group, extack); 262 - 246 + err = esw_qos_normalize_min_rate(node->esw, node, extack); 263 247 if (err) 264 248 return err; 265 249 } ··· 262 262 static int esw_qos_set_vport_min_rate(struct mlx5_vport *vport, 263 263 u32 min_rate, struct netlink_ext_ack *extack) 264 264 { 265 - struct mlx5_eswitch *esw = vport->dev->priv.eswitch; 265 + struct mlx5_esw_sched_node *vport_node = vport->qos.sched_node; 266 266 u32 fw_max_bw_share, previous_min_rate; 267 267 bool min_rate_supported; 268 268 int err; 269 269 270 - esw_assert_qos_lock_held(esw); 270 + esw_assert_qos_lock_held(vport_node->esw); 271 271 fw_max_bw_share = MLX5_CAP_QOS(vport->dev, max_tsar_bw_share); 272 272 min_rate_supported = MLX5_CAP_QOS(vport->dev, esw_bw_share) && 273 273 fw_max_bw_share >= MLX5_MIN_BW_SHARE; 274 274 if (min_rate && !min_rate_supported) 275 275 return -EOPNOTSUPP; 276 - if (min_rate == vport->qos.min_rate) 276 + if (min_rate == vport_node->min_rate) 277 277 return 0; 278 278 279 - previous_min_rate = vport->qos.min_rate; 280 - vport->qos.min_rate = min_rate; 281 - err = esw_qos_normalize_group_min_rate(vport->qos.group, extack); 279 + previous_min_rate = vport_node->min_rate; 280 + vport_node->min_rate = min_rate; 281 + err = esw_qos_normalize_min_rate(vport_node->parent->esw, vport_node->parent, extack); 282 282 if (err) 283 - vport->qos.min_rate = previous_min_rate; 283 + vport_node->min_rate = previous_min_rate; 284 284 285 285 return err; 286 286 } ··· 288 288 static int esw_qos_set_vport_max_rate(struct mlx5_vport *vport, 289 289 u32 max_rate, struct netlink_ext_ack *extack) 290 290 { 291 - struct mlx5_eswitch *esw = vport->dev->priv.eswitch; 291 + struct mlx5_esw_sched_node *vport_node = vport->qos.sched_node; 292 292 u32 act_max_rate = max_rate; 293 293 bool max_rate_supported; 294 294 int err; 295 295 296 - esw_assert_qos_lock_held(esw); 296 + esw_assert_qos_lock_held(vport_node->esw); 297 297 max_rate_supported = MLX5_CAP_QOS(vport->dev, esw_rate_limit); 298 298 299 299 if (max_rate && !max_rate_supported) 300 300 return -EOPNOTSUPP; 301 - if (max_rate == vport->qos.max_rate) 301 + if (max_rate == vport_node->max_rate) 302 302 return 0; 303 303 304 - /* Use parent group limit if new max rate is 0. */ 304 + /* Use parent node limit if new max rate is 0. */ 305 305 if (!max_rate) 306 - act_max_rate = vport->qos.group->max_rate; 306 + act_max_rate = vport_node->parent->max_rate; 307 307 308 - err = esw_qos_vport_config(vport, act_max_rate, vport->qos.bw_share, extack); 309 - 308 + err = esw_qos_sched_elem_config(vport_node, act_max_rate, vport_node->bw_share, extack); 310 309 if (!err) 311 - vport->qos.max_rate = max_rate; 310 + vport_node->max_rate = max_rate; 312 311 313 312 return err; 314 313 } 315 314 316 - static int esw_qos_set_group_min_rate(struct mlx5_esw_rate_group *group, 317 - u32 min_rate, struct netlink_ext_ack *extack) 315 + static int esw_qos_set_node_min_rate(struct mlx5_esw_sched_node *node, 316 + u32 min_rate, struct netlink_ext_ack *extack) 318 317 { 319 - struct mlx5_eswitch *esw = group->esw; 318 + struct mlx5_eswitch *esw = node->esw; 320 319 u32 previous_min_rate; 321 320 int err; 322 321 ··· 323 324 MLX5_CAP_QOS(esw->dev, max_tsar_bw_share) < MLX5_MIN_BW_SHARE) 324 325 return -EOPNOTSUPP; 325 326 326 - if (min_rate == group->min_rate) 327 + if (min_rate == node->min_rate) 327 328 return 0; 328 329 329 - previous_min_rate = group->min_rate; 330 - group->min_rate = min_rate; 331 - err = esw_qos_normalize_min_rate(esw, extack); 330 + previous_min_rate = node->min_rate; 331 + node->min_rate = min_rate; 332 + err = esw_qos_normalize_min_rate(esw, NULL, extack); 332 333 if (err) { 333 - NL_SET_ERR_MSG_MOD(extack, "E-Switch group min rate setting failed"); 334 + NL_SET_ERR_MSG_MOD(extack, "E-Switch node min rate setting failed"); 334 335 335 336 /* Attempt restoring previous configuration */ 336 - group->min_rate = previous_min_rate; 337 - if (esw_qos_normalize_min_rate(esw, extack)) 337 + node->min_rate = previous_min_rate; 338 + if (esw_qos_normalize_min_rate(esw, NULL, extack)) 338 339 NL_SET_ERR_MSG_MOD(extack, "E-Switch BW share restore failed"); 339 340 } 340 341 341 342 return err; 342 343 } 343 344 344 - static int esw_qos_set_group_max_rate(struct mlx5_esw_rate_group *group, 345 - u32 max_rate, struct netlink_ext_ack *extack) 345 + static int esw_qos_set_node_max_rate(struct mlx5_esw_sched_node *node, 346 + u32 max_rate, struct netlink_ext_ack *extack) 346 347 { 347 - struct mlx5_vport *vport; 348 + struct mlx5_esw_sched_node *vport_node; 348 349 int err; 349 350 350 - if (group->max_rate == max_rate) 351 + if (node->max_rate == max_rate) 351 352 return 0; 352 353 353 - err = esw_qos_group_config(group, max_rate, group->bw_share, extack); 354 + err = esw_qos_sched_elem_config(node, max_rate, node->bw_share, extack); 354 355 if (err) 355 356 return err; 356 357 357 - group->max_rate = max_rate; 358 + node->max_rate = max_rate; 358 359 359 - /* Any unlimited vports in the group should be set with the value of the group. */ 360 - list_for_each_entry(vport, &group->members, qos.group_entry) { 361 - if (vport->qos.max_rate) 360 + /* Any unlimited vports in the node should be set with the value of the node. */ 361 + list_for_each_entry(vport_node, &node->children, entry) { 362 + if (vport_node->max_rate) 362 363 continue; 363 364 364 - err = esw_qos_vport_config(vport, max_rate, vport->qos.bw_share, extack); 365 + err = esw_qos_sched_elem_config(vport_node, max_rate, vport_node->bw_share, extack); 365 366 if (err) 366 367 NL_SET_ERR_MSG_MOD(extack, 367 368 "E-Switch vport implicit rate limit setting failed"); ··· 370 371 return err; 371 372 } 372 373 373 - static int esw_qos_vport_create_sched_element(struct mlx5_vport *vport, 374 - u32 max_rate, u32 bw_share) 374 + static int esw_qos_create_node_sched_elem(struct mlx5_core_dev *dev, u32 parent_element_id, 375 + u32 *tsar_ix) 376 + { 377 + u32 tsar_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {}; 378 + void *attr; 379 + 380 + if (!mlx5_qos_element_type_supported(dev, 381 + SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR, 382 + SCHEDULING_HIERARCHY_E_SWITCH) || 383 + !mlx5_qos_tsar_type_supported(dev, 384 + TSAR_ELEMENT_TSAR_TYPE_DWRR, 385 + SCHEDULING_HIERARCHY_E_SWITCH)) 386 + return -EOPNOTSUPP; 387 + 388 + MLX5_SET(scheduling_context, tsar_ctx, element_type, 389 + SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR); 390 + MLX5_SET(scheduling_context, tsar_ctx, parent_element_id, 391 + parent_element_id); 392 + attr = MLX5_ADDR_OF(scheduling_context, tsar_ctx, element_attributes); 393 + MLX5_SET(tsar_element, attr, tsar_type, TSAR_ELEMENT_TSAR_TYPE_DWRR); 394 + 395 + return mlx5_create_scheduling_element_cmd(dev, 396 + SCHEDULING_HIERARCHY_E_SWITCH, 397 + tsar_ctx, 398 + tsar_ix); 399 + } 400 + 401 + static int 402 + esw_qos_vport_create_sched_element(struct mlx5_vport *vport, struct mlx5_esw_sched_node *parent, 403 + u32 max_rate, u32 bw_share, u32 *sched_elem_ix) 375 404 { 376 405 u32 sched_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {}; 377 - struct mlx5_esw_rate_group *group = vport->qos.group; 378 - struct mlx5_core_dev *dev = group->esw->dev; 406 + struct mlx5_core_dev *dev = parent->esw->dev; 379 407 void *attr; 380 408 int err; 381 409 ··· 415 389 SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT); 416 390 attr = MLX5_ADDR_OF(scheduling_context, sched_ctx, element_attributes); 417 391 MLX5_SET(vport_element, attr, vport_number, vport->vport); 418 - MLX5_SET(scheduling_context, sched_ctx, parent_element_id, group->tsar_ix); 392 + MLX5_SET(scheduling_context, sched_ctx, parent_element_id, parent->ix); 419 393 MLX5_SET(scheduling_context, sched_ctx, max_average_bw, max_rate); 420 394 MLX5_SET(scheduling_context, sched_ctx, bw_share, bw_share); 421 395 422 396 err = mlx5_create_scheduling_element_cmd(dev, 423 397 SCHEDULING_HIERARCHY_E_SWITCH, 424 398 sched_ctx, 425 - &vport->qos.esw_sched_elem_ix); 399 + sched_elem_ix); 426 400 if (err) { 427 401 esw_warn(dev, 428 402 "E-Switch create vport scheduling element failed (vport=%d,err=%d)\n", ··· 433 407 return 0; 434 408 } 435 409 436 - static int esw_qos_update_group_scheduling_element(struct mlx5_vport *vport, 437 - struct mlx5_esw_rate_group *curr_group, 438 - struct mlx5_esw_rate_group *new_group, 439 - struct netlink_ext_ack *extack) 410 + static int esw_qos_update_node_scheduling_element(struct mlx5_vport *vport, 411 + struct mlx5_esw_sched_node *curr_node, 412 + struct mlx5_esw_sched_node *new_node, 413 + struct netlink_ext_ack *extack) 440 414 { 415 + struct mlx5_esw_sched_node *vport_node = vport->qos.sched_node; 441 416 u32 max_rate; 442 417 int err; 443 418 444 - err = mlx5_destroy_scheduling_element_cmd(curr_group->esw->dev, 419 + err = mlx5_destroy_scheduling_element_cmd(curr_node->esw->dev, 445 420 SCHEDULING_HIERARCHY_E_SWITCH, 446 - vport->qos.esw_sched_elem_ix); 421 + vport_node->ix); 447 422 if (err) { 448 423 NL_SET_ERR_MSG_MOD(extack, "E-Switch destroy vport scheduling element failed"); 449 424 return err; 450 425 } 451 426 452 - esw_qos_vport_set_group(vport, new_group); 453 - /* Use new group max rate if vport max rate is unlimited. */ 454 - max_rate = vport->qos.max_rate ? vport->qos.max_rate : new_group->max_rate; 455 - err = esw_qos_vport_create_sched_element(vport, max_rate, vport->qos.bw_share); 427 + /* Use new node max rate if vport max rate is unlimited. */ 428 + max_rate = vport_node->max_rate ? vport_node->max_rate : new_node->max_rate; 429 + err = esw_qos_vport_create_sched_element(vport, new_node, max_rate, 430 + vport_node->bw_share, 431 + &vport_node->ix); 456 432 if (err) { 457 - NL_SET_ERR_MSG_MOD(extack, "E-Switch vport group set failed."); 433 + NL_SET_ERR_MSG_MOD(extack, "E-Switch vport node set failed."); 458 434 goto err_sched; 459 435 } 436 + 437 + esw_qos_node_set_parent(vport->qos.sched_node, new_node); 460 438 461 439 return 0; 462 440 463 441 err_sched: 464 - esw_qos_vport_set_group(vport, curr_group); 465 - max_rate = vport->qos.max_rate ? vport->qos.max_rate : curr_group->max_rate; 466 - if (esw_qos_vport_create_sched_element(vport, max_rate, vport->qos.bw_share)) 467 - esw_warn(curr_group->esw->dev, "E-Switch vport group restore failed (vport=%d)\n", 442 + max_rate = vport_node->max_rate ? vport_node->max_rate : curr_node->max_rate; 443 + if (esw_qos_vport_create_sched_element(vport, curr_node, max_rate, 444 + vport_node->bw_share, 445 + &vport_node->ix)) 446 + esw_warn(curr_node->esw->dev, "E-Switch vport node restore failed (vport=%d)\n", 468 447 vport->vport); 469 448 470 449 return err; 471 450 } 472 451 473 - static int esw_qos_vport_update_group(struct mlx5_vport *vport, 474 - struct mlx5_esw_rate_group *group, 475 - struct netlink_ext_ack *extack) 452 + static int esw_qos_vport_update_node(struct mlx5_vport *vport, 453 + struct mlx5_esw_sched_node *node, 454 + struct netlink_ext_ack *extack) 476 455 { 456 + struct mlx5_esw_sched_node *vport_node = vport->qos.sched_node; 477 457 struct mlx5_eswitch *esw = vport->dev->priv.eswitch; 478 - struct mlx5_esw_rate_group *new_group, *curr_group; 458 + struct mlx5_esw_sched_node *new_node, *curr_node; 479 459 int err; 480 460 481 461 esw_assert_qos_lock_held(esw); 482 - curr_group = vport->qos.group; 483 - new_group = group ?: esw->qos.group0; 484 - if (curr_group == new_group) 462 + curr_node = vport_node->parent; 463 + new_node = node ?: esw->qos.node0; 464 + if (curr_node == new_node) 485 465 return 0; 486 466 487 - err = esw_qos_update_group_scheduling_element(vport, curr_group, new_group, extack); 467 + err = esw_qos_update_node_scheduling_element(vport, curr_node, new_node, extack); 488 468 if (err) 489 469 return err; 490 470 491 - /* Recalculate bw share weights of old and new groups */ 492 - if (vport->qos.bw_share || new_group->bw_share) { 493 - esw_qos_normalize_group_min_rate(curr_group, extack); 494 - esw_qos_normalize_group_min_rate(new_group, extack); 471 + /* Recalculate bw share weights of old and new nodes */ 472 + if (vport_node->bw_share || new_node->bw_share) { 473 + esw_qos_normalize_min_rate(curr_node->esw, curr_node, extack); 474 + esw_qos_normalize_min_rate(new_node->esw, new_node, extack); 495 475 } 496 476 497 477 return 0; 498 478 } 499 479 500 - static struct mlx5_esw_rate_group * 501 - __esw_qos_alloc_rate_group(struct mlx5_eswitch *esw, u32 tsar_ix) 480 + static struct mlx5_esw_sched_node * 481 + __esw_qos_alloc_node(struct mlx5_eswitch *esw, u32 tsar_ix, enum sched_node_type type, 482 + struct mlx5_esw_sched_node *parent) 502 483 { 503 - struct mlx5_esw_rate_group *group; 484 + struct list_head *parent_children; 485 + struct mlx5_esw_sched_node *node; 504 486 505 - group = kzalloc(sizeof(*group), GFP_KERNEL); 506 - if (!group) 487 + node = kzalloc(sizeof(*node), GFP_KERNEL); 488 + if (!node) 507 489 return NULL; 508 490 509 - group->esw = esw; 510 - group->tsar_ix = tsar_ix; 511 - INIT_LIST_HEAD(&group->members); 512 - list_add_tail(&group->parent_entry, &esw->qos.domain->groups); 513 - return group; 491 + node->esw = esw; 492 + node->ix = tsar_ix; 493 + node->type = type; 494 + node->parent = parent; 495 + INIT_LIST_HEAD(&node->children); 496 + parent_children = parent ? &parent->children : &esw->qos.domain->nodes; 497 + list_add_tail(&node->entry, parent_children); 498 + 499 + return node; 514 500 } 515 501 516 - static void __esw_qos_free_rate_group(struct mlx5_esw_rate_group *group) 502 + static void __esw_qos_free_node(struct mlx5_esw_sched_node *node) 517 503 { 518 - list_del(&group->parent_entry); 519 - kfree(group); 504 + list_del(&node->entry); 505 + kfree(node); 520 506 } 521 507 522 - static struct mlx5_esw_rate_group * 523 - __esw_qos_create_rate_group(struct mlx5_eswitch *esw, struct netlink_ext_ack *extack) 508 + static struct mlx5_esw_sched_node * 509 + __esw_qos_create_vports_sched_node(struct mlx5_eswitch *esw, struct mlx5_esw_sched_node *parent, 510 + struct netlink_ext_ack *extack) 524 511 { 525 - u32 tsar_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {}; 526 - struct mlx5_esw_rate_group *group; 527 - int tsar_ix, err; 528 - void *attr; 512 + struct mlx5_esw_sched_node *node; 513 + u32 tsar_ix; 514 + int err; 529 515 530 - MLX5_SET(scheduling_context, tsar_ctx, element_type, 531 - SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR); 532 - MLX5_SET(scheduling_context, tsar_ctx, parent_element_id, 533 - esw->qos.root_tsar_ix); 534 - attr = MLX5_ADDR_OF(scheduling_context, tsar_ctx, element_attributes); 535 - MLX5_SET(tsar_element, attr, tsar_type, TSAR_ELEMENT_TSAR_TYPE_DWRR); 536 - err = mlx5_create_scheduling_element_cmd(esw->dev, 537 - SCHEDULING_HIERARCHY_E_SWITCH, 538 - tsar_ctx, 539 - &tsar_ix); 516 + err = esw_qos_create_node_sched_elem(esw->dev, esw->qos.root_tsar_ix, &tsar_ix); 540 517 if (err) { 541 - NL_SET_ERR_MSG_MOD(extack, "E-Switch create TSAR for group failed"); 518 + NL_SET_ERR_MSG_MOD(extack, "E-Switch create TSAR for node failed"); 542 519 return ERR_PTR(err); 543 520 } 544 521 545 - group = __esw_qos_alloc_rate_group(esw, tsar_ix); 546 - if (!group) { 547 - NL_SET_ERR_MSG_MOD(extack, "E-Switch alloc group failed"); 522 + node = __esw_qos_alloc_node(esw, tsar_ix, SCHED_NODE_TYPE_VPORTS_TSAR, parent); 523 + if (!node) { 524 + NL_SET_ERR_MSG_MOD(extack, "E-Switch alloc node failed"); 548 525 err = -ENOMEM; 549 - goto err_alloc_group; 526 + goto err_alloc_node; 550 527 } 551 528 552 - err = esw_qos_normalize_min_rate(esw, extack); 529 + err = esw_qos_normalize_min_rate(esw, NULL, extack); 553 530 if (err) { 554 - NL_SET_ERR_MSG_MOD(extack, "E-Switch groups normalization failed"); 531 + NL_SET_ERR_MSG_MOD(extack, "E-Switch nodes normalization failed"); 555 532 goto err_min_rate; 556 533 } 557 - trace_mlx5_esw_group_qos_create(esw->dev, group, group->tsar_ix); 534 + trace_mlx5_esw_node_qos_create(esw->dev, node, node->ix); 558 535 559 - return group; 536 + return node; 560 537 561 538 err_min_rate: 562 - __esw_qos_free_rate_group(group); 563 - err_alloc_group: 539 + __esw_qos_free_node(node); 540 + err_alloc_node: 564 541 if (mlx5_destroy_scheduling_element_cmd(esw->dev, 565 542 SCHEDULING_HIERARCHY_E_SWITCH, 566 543 tsar_ix)) 567 - NL_SET_ERR_MSG_MOD(extack, "E-Switch destroy TSAR for group failed"); 544 + NL_SET_ERR_MSG_MOD(extack, "E-Switch destroy TSAR for node failed"); 568 545 return ERR_PTR(err); 569 546 } 570 547 571 548 static int esw_qos_get(struct mlx5_eswitch *esw, struct netlink_ext_ack *extack); 572 549 static void esw_qos_put(struct mlx5_eswitch *esw); 573 550 574 - static struct mlx5_esw_rate_group * 575 - esw_qos_create_rate_group(struct mlx5_eswitch *esw, struct netlink_ext_ack *extack) 551 + static struct mlx5_esw_sched_node * 552 + esw_qos_create_vports_sched_node(struct mlx5_eswitch *esw, struct netlink_ext_ack *extack) 576 553 { 577 - struct mlx5_esw_rate_group *group; 554 + struct mlx5_esw_sched_node *node; 578 555 int err; 579 556 580 557 esw_assert_qos_lock_held(esw); ··· 588 559 if (err) 589 560 return ERR_PTR(err); 590 561 591 - group = __esw_qos_create_rate_group(esw, extack); 592 - if (IS_ERR(group)) 562 + node = __esw_qos_create_vports_sched_node(esw, NULL, extack); 563 + if (IS_ERR(node)) 593 564 esw_qos_put(esw); 594 565 595 - return group; 566 + return node; 596 567 } 597 568 598 - static int __esw_qos_destroy_rate_group(struct mlx5_esw_rate_group *group, 599 - struct netlink_ext_ack *extack) 569 + static int __esw_qos_destroy_node(struct mlx5_esw_sched_node *node, struct netlink_ext_ack *extack) 600 570 { 601 - struct mlx5_eswitch *esw = group->esw; 571 + struct mlx5_eswitch *esw = node->esw; 602 572 int err; 603 573 604 - trace_mlx5_esw_group_qos_destroy(esw->dev, group, group->tsar_ix); 574 + trace_mlx5_esw_node_qos_destroy(esw->dev, node, node->ix); 605 575 606 576 err = mlx5_destroy_scheduling_element_cmd(esw->dev, 607 577 SCHEDULING_HIERARCHY_E_SWITCH, 608 - group->tsar_ix); 578 + node->ix); 609 579 if (err) 610 580 NL_SET_ERR_MSG_MOD(extack, "E-Switch destroy TSAR_ID failed"); 611 - __esw_qos_free_rate_group(group); 581 + __esw_qos_free_node(node); 612 582 613 - err = esw_qos_normalize_min_rate(esw, extack); 583 + err = esw_qos_normalize_min_rate(esw, NULL, extack); 614 584 if (err) 615 - NL_SET_ERR_MSG_MOD(extack, "E-Switch groups normalization failed"); 585 + NL_SET_ERR_MSG_MOD(extack, "E-Switch nodes normalization failed"); 616 586 617 587 618 588 return err; ··· 619 591 620 592 static int esw_qos_create(struct mlx5_eswitch *esw, struct netlink_ext_ack *extack) 621 593 { 622 - u32 tsar_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {}; 623 594 struct mlx5_core_dev *dev = esw->dev; 624 - void *attr; 625 595 int err; 626 596 627 597 if (!MLX5_CAP_GEN(dev, qos) || !MLX5_CAP_QOS(dev, esw_scheduling)) 628 598 return -EOPNOTSUPP; 629 599 630 - if (!mlx5_qos_element_type_supported(dev, 631 - SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR, 632 - SCHEDULING_HIERARCHY_E_SWITCH) || 633 - !mlx5_qos_tsar_type_supported(dev, 634 - TSAR_ELEMENT_TSAR_TYPE_DWRR, 635 - SCHEDULING_HIERARCHY_E_SWITCH)) 636 - return -EOPNOTSUPP; 637 - 638 - MLX5_SET(scheduling_context, tsar_ctx, element_type, 639 - SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR); 640 - 641 - attr = MLX5_ADDR_OF(scheduling_context, tsar_ctx, element_attributes); 642 - MLX5_SET(tsar_element, attr, tsar_type, TSAR_ELEMENT_TSAR_TYPE_DWRR); 643 - 644 - err = mlx5_create_scheduling_element_cmd(dev, 645 - SCHEDULING_HIERARCHY_E_SWITCH, 646 - tsar_ctx, 647 - &esw->qos.root_tsar_ix); 600 + err = esw_qos_create_node_sched_elem(esw->dev, 0, &esw->qos.root_tsar_ix); 648 601 if (err) { 649 602 esw_warn(dev, "E-Switch create root TSAR failed (%d)\n", err); 650 603 return err; 651 604 } 652 605 653 606 if (MLX5_CAP_QOS(dev, log_esw_max_sched_depth)) { 654 - esw->qos.group0 = __esw_qos_create_rate_group(esw, extack); 607 + esw->qos.node0 = __esw_qos_create_vports_sched_node(esw, NULL, extack); 655 608 } else { 656 - /* The eswitch doesn't support scheduling groups. 657 - * Create a software-only group0 using the root TSAR to attach vport QoS to. 609 + /* The eswitch doesn't support scheduling nodes. 610 + * Create a software-only node0 using the root TSAR to attach vport QoS to. 658 611 */ 659 - if (!__esw_qos_alloc_rate_group(esw, esw->qos.root_tsar_ix)) 660 - esw->qos.group0 = ERR_PTR(-ENOMEM); 612 + if (!__esw_qos_alloc_node(esw, 613 + esw->qos.root_tsar_ix, 614 + SCHED_NODE_TYPE_VPORTS_TSAR, 615 + NULL)) 616 + esw->qos.node0 = ERR_PTR(-ENOMEM); 661 617 } 662 - if (IS_ERR(esw->qos.group0)) { 663 - err = PTR_ERR(esw->qos.group0); 664 - esw_warn(dev, "E-Switch create rate group 0 failed (%d)\n", err); 665 - goto err_group0; 618 + if (IS_ERR(esw->qos.node0)) { 619 + err = PTR_ERR(esw->qos.node0); 620 + esw_warn(dev, "E-Switch create rate node 0 failed (%d)\n", err); 621 + goto err_node0; 666 622 } 667 623 refcount_set(&esw->qos.refcnt, 1); 668 624 669 625 return 0; 670 626 671 - err_group0: 627 + err_node0: 672 628 if (mlx5_destroy_scheduling_element_cmd(esw->dev, SCHEDULING_HIERARCHY_E_SWITCH, 673 629 esw->qos.root_tsar_ix)) 674 630 esw_warn(esw->dev, "E-Switch destroy root TSAR failed.\n"); ··· 664 652 { 665 653 int err; 666 654 667 - if (esw->qos.group0->tsar_ix != esw->qos.root_tsar_ix) 668 - __esw_qos_destroy_rate_group(esw->qos.group0, NULL); 655 + if (esw->qos.node0->ix != esw->qos.root_tsar_ix) 656 + __esw_qos_destroy_node(esw->qos.node0, NULL); 669 657 else 670 - __esw_qos_free_rate_group(esw->qos.group0); 671 - esw->qos.group0 = NULL; 658 + __esw_qos_free_node(esw->qos.node0); 659 + esw->qos.node0 = NULL; 672 660 673 661 err = mlx5_destroy_scheduling_element_cmd(esw->dev, 674 662 SCHEDULING_HIERARCHY_E_SWITCH, ··· 703 691 u32 max_rate, u32 bw_share, struct netlink_ext_ack *extack) 704 692 { 705 693 struct mlx5_eswitch *esw = vport->dev->priv.eswitch; 694 + u32 sched_elem_ix; 706 695 int err; 707 696 708 697 esw_assert_qos_lock_held(esw); 709 - if (vport->qos.enabled) 698 + if (vport->qos.sched_node) 710 699 return 0; 711 700 712 701 err = esw_qos_get(esw, extack); 713 702 if (err) 714 703 return err; 715 704 716 - INIT_LIST_HEAD(&vport->qos.group_entry); 717 - esw_qos_vport_set_group(vport, esw->qos.group0); 718 - 719 - err = esw_qos_vport_create_sched_element(vport, max_rate, bw_share); 705 + err = esw_qos_vport_create_sched_element(vport, esw->qos.node0, max_rate, bw_share, 706 + &sched_elem_ix); 720 707 if (err) 721 708 goto err_out; 722 709 723 - vport->qos.enabled = true; 710 + vport->qos.sched_node = __esw_qos_alloc_node(esw, sched_elem_ix, SCHED_NODE_TYPE_VPORT, 711 + esw->qos.node0); 712 + if (!vport->qos.sched_node) { 713 + err = -ENOMEM; 714 + goto err_alloc; 715 + } 716 + 717 + vport->qos.sched_node->vport = vport; 718 + 724 719 trace_mlx5_esw_vport_qos_create(vport->dev, vport, bw_share, max_rate); 725 720 726 721 return 0; 727 722 723 + err_alloc: 724 + if (mlx5_destroy_scheduling_element_cmd(esw->dev, 725 + SCHEDULING_HIERARCHY_E_SWITCH, sched_elem_ix)) 726 + esw_warn(esw->dev, "E-Switch destroy vport scheduling element failed.\n"); 728 727 err_out: 729 728 esw_qos_put(esw); 730 729 ··· 745 722 void mlx5_esw_qos_vport_disable(struct mlx5_vport *vport) 746 723 { 747 724 struct mlx5_eswitch *esw = vport->dev->priv.eswitch; 725 + struct mlx5_esw_sched_node *vport_node; 748 726 struct mlx5_core_dev *dev; 749 727 int err; 750 728 751 729 lockdep_assert_held(&esw->state_lock); 752 730 esw_qos_lock(esw); 753 - if (!vport->qos.enabled) 731 + vport_node = vport->qos.sched_node; 732 + if (!vport_node) 754 733 goto unlock; 755 - WARN(vport->qos.group != esw->qos.group0, 756 - "Disabling QoS on port before detaching it from group"); 734 + WARN(vport_node->parent != esw->qos.node0, 735 + "Disabling QoS on port before detaching it from node"); 757 736 758 - dev = vport->qos.group->esw->dev; 737 + dev = vport_node->esw->dev; 738 + trace_mlx5_esw_vport_qos_destroy(dev, vport); 739 + 759 740 err = mlx5_destroy_scheduling_element_cmd(dev, 760 741 SCHEDULING_HIERARCHY_E_SWITCH, 761 - vport->qos.esw_sched_elem_ix); 742 + vport_node->ix); 762 743 if (err) 763 744 esw_warn(dev, 764 745 "E-Switch destroy vport scheduling element failed (vport=%d,err=%d)\n", 765 746 vport->vport, err); 766 747 748 + __esw_qos_free_node(vport_node); 767 749 memset(&vport->qos, 0, sizeof(vport->qos)); 768 - trace_mlx5_esw_vport_qos_destroy(dev, vport); 769 750 770 751 esw_qos_put(esw); 771 752 unlock: ··· 800 773 bool enabled; 801 774 802 775 esw_qos_lock(esw); 803 - enabled = vport->qos.enabled; 776 + enabled = !!vport->qos.sched_node; 804 777 if (enabled) { 805 - *max_rate = vport->qos.max_rate; 806 - *min_rate = vport->qos.min_rate; 778 + *max_rate = vport->qos.sched_node->max_rate; 779 + *min_rate = vport->qos.sched_node->min_rate; 807 780 } 808 781 esw_qos_unlock(esw); 809 782 return enabled; ··· 897 870 } 898 871 899 872 esw_qos_lock(esw); 900 - if (!vport->qos.enabled) { 873 + if (!vport->qos.sched_node) { 901 874 /* Eswitch QoS wasn't enabled yet. Enable it and vport QoS. */ 902 - err = esw_qos_vport_enable(vport, rate_mbps, vport->qos.bw_share, NULL); 875 + err = esw_qos_vport_enable(vport, rate_mbps, 0, NULL); 903 876 } else { 904 - struct mlx5_core_dev *dev = vport->qos.group->esw->dev; 877 + struct mlx5_core_dev *dev = vport->qos.sched_node->parent->esw->dev; 905 878 906 879 MLX5_SET(scheduling_context, ctx, max_average_bw, rate_mbps); 907 880 bitmask = MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_MAX_AVERAGE_BW; 908 881 err = mlx5_modify_scheduling_element_cmd(dev, 909 882 SCHEDULING_HIERARCHY_E_SWITCH, 910 883 ctx, 911 - vport->qos.esw_sched_elem_ix, 884 + vport->qos.sched_node->ix, 912 885 bitmask); 913 886 } 914 887 esw_qos_unlock(esw); ··· 1017 990 int mlx5_esw_devlink_rate_node_tx_share_set(struct devlink_rate *rate_node, void *priv, 1018 991 u64 tx_share, struct netlink_ext_ack *extack) 1019 992 { 1020 - struct mlx5_esw_rate_group *group = priv; 1021 - struct mlx5_eswitch *esw = group->esw; 993 + struct mlx5_esw_sched_node *node = priv; 994 + struct mlx5_eswitch *esw = node->esw; 1022 995 int err; 1023 996 1024 997 err = esw_qos_devlink_rate_to_mbps(esw->dev, "tx_share", &tx_share, extack); ··· 1026 999 return err; 1027 1000 1028 1001 esw_qos_lock(esw); 1029 - err = esw_qos_set_group_min_rate(group, tx_share, extack); 1002 + err = esw_qos_set_node_min_rate(node, tx_share, extack); 1030 1003 esw_qos_unlock(esw); 1031 1004 return err; 1032 1005 } ··· 1034 1007 int mlx5_esw_devlink_rate_node_tx_max_set(struct devlink_rate *rate_node, void *priv, 1035 1008 u64 tx_max, struct netlink_ext_ack *extack) 1036 1009 { 1037 - struct mlx5_esw_rate_group *group = priv; 1038 - struct mlx5_eswitch *esw = group->esw; 1010 + struct mlx5_esw_sched_node *node = priv; 1011 + struct mlx5_eswitch *esw = node->esw; 1039 1012 int err; 1040 1013 1041 1014 err = esw_qos_devlink_rate_to_mbps(esw->dev, "tx_max", &tx_max, extack); ··· 1043 1016 return err; 1044 1017 1045 1018 esw_qos_lock(esw); 1046 - err = esw_qos_set_group_max_rate(group, tx_max, extack); 1019 + err = esw_qos_set_node_max_rate(node, tx_max, extack); 1047 1020 esw_qos_unlock(esw); 1048 1021 return err; 1049 1022 } ··· 1051 1024 int mlx5_esw_devlink_rate_node_new(struct devlink_rate *rate_node, void **priv, 1052 1025 struct netlink_ext_ack *extack) 1053 1026 { 1054 - struct mlx5_esw_rate_group *group; 1027 + struct mlx5_esw_sched_node *node; 1055 1028 struct mlx5_eswitch *esw; 1056 1029 int err = 0; 1057 1030 ··· 1067 1040 goto unlock; 1068 1041 } 1069 1042 1070 - group = esw_qos_create_rate_group(esw, extack); 1071 - if (IS_ERR(group)) { 1072 - err = PTR_ERR(group); 1043 + node = esw_qos_create_vports_sched_node(esw, extack); 1044 + if (IS_ERR(node)) { 1045 + err = PTR_ERR(node); 1073 1046 goto unlock; 1074 1047 } 1075 1048 1076 - *priv = group; 1049 + *priv = node; 1077 1050 unlock: 1078 1051 esw_qos_unlock(esw); 1079 1052 return err; ··· 1082 1055 int mlx5_esw_devlink_rate_node_del(struct devlink_rate *rate_node, void *priv, 1083 1056 struct netlink_ext_ack *extack) 1084 1057 { 1085 - struct mlx5_esw_rate_group *group = priv; 1086 - struct mlx5_eswitch *esw = group->esw; 1058 + struct mlx5_esw_sched_node *node = priv; 1059 + struct mlx5_eswitch *esw = node->esw; 1087 1060 int err; 1088 1061 1089 1062 esw_qos_lock(esw); 1090 - err = __esw_qos_destroy_rate_group(group, extack); 1063 + err = __esw_qos_destroy_node(node, extack); 1091 1064 esw_qos_put(esw); 1092 1065 esw_qos_unlock(esw); 1093 1066 return err; 1094 1067 } 1095 1068 1096 - int mlx5_esw_qos_vport_update_group(struct mlx5_vport *vport, 1097 - struct mlx5_esw_rate_group *group, 1098 - struct netlink_ext_ack *extack) 1069 + int mlx5_esw_qos_vport_update_node(struct mlx5_vport *vport, 1070 + struct mlx5_esw_sched_node *node, 1071 + struct netlink_ext_ack *extack) 1099 1072 { 1100 1073 struct mlx5_eswitch *esw = vport->dev->priv.eswitch; 1101 1074 int err = 0; 1102 1075 1103 - if (group && group->esw != esw) { 1076 + if (node && node->esw != esw) { 1104 1077 NL_SET_ERR_MSG_MOD(extack, "Cross E-Switch scheduling is not supported"); 1105 1078 return -EOPNOTSUPP; 1106 1079 } 1107 1080 1108 1081 esw_qos_lock(esw); 1109 - if (!vport->qos.enabled && !group) 1082 + if (!vport->qos.sched_node && !node) 1110 1083 goto unlock; 1111 1084 1112 1085 err = esw_qos_vport_enable(vport, 0, 0, extack); 1113 1086 if (!err) 1114 - err = esw_qos_vport_update_group(vport, group, extack); 1087 + err = esw_qos_vport_update_node(vport, node, extack); 1115 1088 unlock: 1116 1089 esw_qos_unlock(esw); 1117 1090 return err; ··· 1122 1095 void *priv, void *parent_priv, 1123 1096 struct netlink_ext_ack *extack) 1124 1097 { 1125 - struct mlx5_esw_rate_group *group; 1098 + struct mlx5_esw_sched_node *node; 1126 1099 struct mlx5_vport *vport = priv; 1127 1100 1128 1101 if (!parent) 1129 - return mlx5_esw_qos_vport_update_group(vport, NULL, extack); 1102 + return mlx5_esw_qos_vport_update_node(vport, NULL, extack); 1130 1103 1131 - group = parent_priv; 1132 - return mlx5_esw_qos_vport_update_group(vport, group, extack); 1104 + node = parent_priv; 1105 + return mlx5_esw_qos_vport_update_node(vport, node, extack); 1133 1106 }
+3
drivers/net/ethernet/mellanox/mlx5/core/esw/qos.h
··· 13 13 bool mlx5_esw_qos_get_vport_rate(struct mlx5_vport *vport, u32 *max_rate, u32 *min_rate); 14 14 void mlx5_esw_qos_vport_disable(struct mlx5_vport *vport); 15 15 16 + u32 mlx5_esw_qos_vport_get_sched_elem_ix(const struct mlx5_vport *vport); 17 + struct mlx5_esw_sched_node *mlx5_esw_qos_vport_get_parent(const struct mlx5_vport *vport); 18 + 16 19 int mlx5_esw_devlink_rate_leaf_tx_share_set(struct devlink_rate *rate_leaf, void *priv, 17 20 u64 tx_share, struct netlink_ext_ack *extack); 18 21 int mlx5_esw_devlink_rate_leaf_tx_max_set(struct devlink_rate *rate_leaf, void *priv,
+2
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
··· 1061 1061 unsigned long i; 1062 1062 1063 1063 mlx5_esw_for_each_vf_vport(esw, i, vport, esw->esw_funcs.num_vfs) { 1064 + kfree(vport->qos.sched_node); 1064 1065 memset(&vport->qos, 0, sizeof(vport->qos)); 1065 1066 memset(&vport->info, 0, sizeof(vport->info)); 1066 1067 vport->info.link_state = MLX5_VPORT_ADMIN_STATE_AUTO; ··· 1074 1073 unsigned long i; 1075 1074 1076 1075 mlx5_esw_for_each_ec_vf_vport(esw, i, vport, esw->esw_funcs.num_ec_vfs) { 1076 + kfree(vport->qos.sched_node); 1077 1077 memset(&vport->qos, 0, sizeof(vport->qos)); 1078 1078 memset(&vport->info, 0, sizeof(vport->info)); 1079 1079 vport->info.link_state = MLX5_VPORT_ADMIN_STATE_AUTO;
+9 -16
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
··· 214 214 215 215 /* Protected with the E-Switch qos domain lock. */ 216 216 struct { 217 - /* Initially false, set to true whenever any QoS features are used. */ 218 - bool enabled; 219 - u32 esw_sched_elem_ix; 220 - u32 min_rate; 221 - u32 max_rate; 222 - /* A computed value indicating relative min_rate between vports in a group. */ 223 - u32 bw_share; 224 - struct mlx5_esw_rate_group *group; 225 - struct list_head group_entry; 217 + /* Vport scheduling element node. */ 218 + struct mlx5_esw_sched_node *sched_node; 226 219 } qos; 227 220 228 221 u16 vport; ··· 363 370 refcount_t refcnt; 364 371 u32 root_tsar_ix; 365 372 struct mlx5_qos_domain *domain; 366 - /* Contains all vports with QoS enabled but no explicit group. 367 - * Cannot be NULL if QoS is enabled, but may be a fake group 368 - * referencing the root TSAR if the esw doesn't support groups. 373 + /* Contains all vports with QoS enabled but no explicit node. 374 + * Cannot be NULL if QoS is enabled, but may be a fake node 375 + * referencing the root TSAR if the esw doesn't support nodes. 369 376 */ 370 - struct mlx5_esw_rate_group *group0; 377 + struct mlx5_esw_sched_node *node0; 371 378 } qos; 372 379 373 380 struct mlx5_esw_bridge_offloads *br_offloads; ··· 427 434 u16 vport_num, bool setting); 428 435 int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw, u16 vport, 429 436 u32 max_rate, u32 min_rate); 430 - int mlx5_esw_qos_vport_update_group(struct mlx5_vport *vport, 431 - struct mlx5_esw_rate_group *group, 432 - struct netlink_ext_ack *extack); 437 + int mlx5_esw_qos_vport_update_node(struct mlx5_vport *vport, 438 + struct mlx5_esw_sched_node *node, 439 + struct netlink_ext_ack *extack); 433 440 int mlx5_eswitch_set_vepa(struct mlx5_eswitch *esw, u8 setting); 434 441 int mlx5_eswitch_get_vepa(struct mlx5_eswitch *esw, u8 *setting); 435 442 int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
+2 -2
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
··· 63 63 enum mlx5_flow_namespace_type ns_type; 64 64 enum mlx5_flow_resource_owner owner; 65 65 union { 66 - struct mlx5_fs_dr_action action; 66 + struct mlx5_fs_dr_action fs_dr_action; 67 67 u32 id; 68 68 }; 69 69 }; ··· 73 73 int reformat_type; /* from mlx5_ifc */ 74 74 enum mlx5_flow_resource_owner owner; 75 75 union { 76 - struct mlx5_fs_dr_action action; 76 + struct mlx5_fs_dr_action fs_dr_action; 77 77 u32 id; 78 78 }; 79 79 };
+8 -1
drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
··· 35 35 enum { 36 36 MLX5_FW_RST_STATE_IDLE = 0, 37 37 MLX5_FW_RST_STATE_TOGGLE_REQ = 4, 38 + MLX5_FW_RST_STATE_DROP_MODE = 5, 38 39 }; 39 40 40 41 enum { ··· 617 616 struct mlx5_fw_reset *fw_reset; 618 617 struct mlx5_core_dev *dev; 619 618 unsigned long timeout; 619 + int poll_freq = 20; 620 620 bool reset_action; 621 621 u8 rst_state; 622 622 int err; ··· 653 651 reset_action = true; 654 652 break; 655 653 } 656 - msleep(20); 654 + if (rst_state == MLX5_FW_RST_STATE_DROP_MODE) { 655 + mlx5_core_info(dev, "Sync Reset Drop mode ack\n"); 656 + mlx5_set_fw_rst_ack(dev); 657 + poll_freq = 1000; 658 + } 659 + msleep(poll_freq); 657 660 } while (!time_after(jiffies, timeout)); 658 661 659 662 if (!reset_action) {
+20 -15
drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c
··· 256 256 { 257 257 struct mlx5dr_domain *domain = ns->fs_dr_domain.dr_domain; 258 258 struct mlx5dr_action_dest *term_actions; 259 + struct mlx5_pkt_reformat *pkt_reformat; 259 260 struct mlx5dr_match_parameters params; 260 261 struct mlx5_core_dev *dev = ns->dev; 261 262 struct mlx5dr_action **fs_dr_actions; ··· 333 332 if (fte->act_dests.action.action & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT) { 334 333 bool is_decap; 335 334 336 - if (fte->act_dests.action.pkt_reformat->owner == MLX5_FLOW_RESOURCE_OWNER_FW) { 335 + pkt_reformat = fte->act_dests.action.pkt_reformat; 336 + if (pkt_reformat->owner == MLX5_FLOW_RESOURCE_OWNER_FW) { 337 337 err = -EINVAL; 338 338 mlx5dr_err(domain, "FW-owned reformat can't be used in SW rule\n"); 339 339 goto free_actions; 340 340 } 341 341 342 - is_decap = fte->act_dests.action.pkt_reformat->reformat_type == 342 + is_decap = pkt_reformat->reformat_type == 343 343 MLX5_REFORMAT_TYPE_L3_TUNNEL_TO_L2; 344 344 345 345 if (is_decap) 346 346 actions[num_actions++] = 347 - fte->act_dests.action.pkt_reformat->action.dr_action; 347 + pkt_reformat->fs_dr_action.dr_action; 348 348 else 349 349 delay_encap_set = true; 350 350 } ··· 372 370 actions[num_actions++] = tmp_action; 373 371 } 374 372 375 - if (fte->act_dests.action.action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) 376 - actions[num_actions++] = 377 - fte->act_dests.action.modify_hdr->action.dr_action; 373 + if (fte->act_dests.action.action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) { 374 + struct mlx5_modify_hdr *modify_hdr = fte->act_dests.action.modify_hdr; 375 + 376 + actions[num_actions++] = modify_hdr->fs_dr_action.dr_action; 377 + } 378 378 379 379 if (fte->act_dests.action.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) { 380 380 tmp_action = create_action_push_vlan(domain, &fte->act_dests.action.vlan[0]); ··· 399 395 } 400 396 401 397 if (delay_encap_set) 402 - actions[num_actions++] = 403 - fte->act_dests.action.pkt_reformat->action.dr_action; 398 + actions[num_actions++] = pkt_reformat->fs_dr_action.dr_action; 404 399 405 400 /* The order of the actions below is not important */ 406 401 ··· 461 458 term_actions[num_term_actions].dest = tmp_action; 462 459 463 460 if (dst->dest_attr.vport.flags & 464 - MLX5_FLOW_DEST_VPORT_REFORMAT_ID) 461 + MLX5_FLOW_DEST_VPORT_REFORMAT_ID) { 462 + pkt_reformat = dst->dest_attr.vport.pkt_reformat; 465 463 term_actions[num_term_actions].reformat = 466 - dst->dest_attr.vport.pkt_reformat->action.dr_action; 464 + pkt_reformat->fs_dr_action.dr_action; 465 + } 467 466 468 467 num_term_actions++; 469 468 break; ··· 676 671 } 677 672 678 673 pkt_reformat->owner = MLX5_FLOW_RESOURCE_OWNER_SW; 679 - pkt_reformat->action.dr_action = action; 674 + pkt_reformat->fs_dr_action.dr_action = action; 680 675 681 676 return 0; 682 677 } ··· 684 679 static void mlx5_cmd_dr_packet_reformat_dealloc(struct mlx5_flow_root_namespace *ns, 685 680 struct mlx5_pkt_reformat *pkt_reformat) 686 681 { 687 - mlx5dr_action_destroy(pkt_reformat->action.dr_action); 682 + mlx5dr_action_destroy(pkt_reformat->fs_dr_action.dr_action); 688 683 } 689 684 690 685 static int mlx5_cmd_dr_modify_header_alloc(struct mlx5_flow_root_namespace *ns, ··· 707 702 } 708 703 709 704 modify_hdr->owner = MLX5_FLOW_RESOURCE_OWNER_SW; 710 - modify_hdr->action.dr_action = action; 705 + modify_hdr->fs_dr_action.dr_action = action; 711 706 712 707 return 0; 713 708 } ··· 715 710 static void mlx5_cmd_dr_modify_header_dealloc(struct mlx5_flow_root_namespace *ns, 716 711 struct mlx5_modify_hdr *modify_hdr) 717 712 { 718 - mlx5dr_action_destroy(modify_hdr->action.dr_action); 713 + mlx5dr_action_destroy(modify_hdr->fs_dr_action.dr_action); 719 714 } 720 715 721 716 static int ··· 841 836 case MLX5_REFORMAT_TYPE_L2_TO_L2_TUNNEL: 842 837 case MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL: 843 838 case MLX5_REFORMAT_TYPE_INSERT_HDR: 844 - return mlx5dr_action_get_pkt_reformat_id(pkt_reformat->action.dr_action); 839 + return mlx5dr_action_get_pkt_reformat_id(pkt_reformat->fs_dr_action.dr_action); 845 840 } 846 841 return -EOPNOTSUPP; 847 842 }