History

Merge branch 'flow_offload-tc-police-parameters'

Jianbo Liu says: ==================== flow_offload: add tc police parameters As a preparation for more advanced police offload in mlx5 (e.g., jumping to another chain when bandwidth is not exceeded), extend the flow offload API with more tc-police parameters. Adjust existing drivers to reject unsupported configurations. Changes since v2: * Rename index to extval in exceed and notexceed acts. * Add policer validate functions for all drivers. Changes since v1: * Add one more strict validation for the control of drop/ok. ====================

David S. Miller committed 4 years ago

Commit c4eb0582 parents b42a738 d97b4b114 files · +454 −38Browse files

Unified · Split

14 files
  1. drivers/net/dsa/sja1105/sja1105_flower.c +42 −5
  2. drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c +49 −10
  3. drivers/net/ethernet/freescale/enetc/enetc_qos.c +43 −4
  4. drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c +43 −0
  5. drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +44 −4
  6. drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +43 −4
  7. drivers/net/ethernet/mscc/ocelot_flower.c +8 −6
  8. drivers/net/ethernet/mscc/ocelot_net.c +5 −5
  9. drivers/net/ethernet/mscc/ocelot_police.c +41 −0
  10. drivers/net/ethernet/mscc/ocelot_police.h +5 −0
  11. drivers/net/ethernet/netronome/nfp/flower/qos_conf.c +40 −0
  12. include/net/flow_offload.h +15 −0
  13. include/net/tc_act/tc_police.h +30 −0
  14. net/sched/act_police.c +46 −0
drivers/net/dsa/sja1105/sja1105_flower.c+42−5
@@ -300,6 +300,46 @@ static int sja1105_flower_parse_key(struct sja1105_private *priv, · 299 unmodified lines
300 return -EOPNOTSUPP;300 return -EOPNOTSUPP;
301}301}
302 302
303static int sja1105_policer_validate(const struct flow_action *action,
304 const struct flow_action_entry *act,
305 struct netlink_ext_ack *extack)
306{
307 if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
308 NL_SET_ERR_MSG_MOD(extack,
309 "Offload not supported when exceed action is not drop");
310 return -EOPNOTSUPP;
311 }
312
313 if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
314 act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
315 NL_SET_ERR_MSG_MOD(extack,
316 "Offload not supported when conform action is not pipe or ok");
317 return -EOPNOTSUPP;
318 }
319
320 if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
321 !flow_action_is_last_entry(action, act)) {
322 NL_SET_ERR_MSG_MOD(extack,
323 "Offload not supported when conform action is ok, but action is not last");
324 return -EOPNOTSUPP;
325 }
326
327 if (act->police.peakrate_bytes_ps ||
328 act->police.avrate || act->police.overhead) {
329 NL_SET_ERR_MSG_MOD(extack,
330 "Offload not supported when peakrate/avrate/overhead is configured");
331 return -EOPNOTSUPP;
332 }
333
334 if (act->police.rate_pkt_ps) {
335 NL_SET_ERR_MSG_MOD(extack,
336 "QoS offload not support packets per second");
337 return -EOPNOTSUPP;
338 }
339
340 return 0;
341}
342
303int sja1105_cls_flower_add(struct dsa_switch *ds, int port,343int sja1105_cls_flower_add(struct dsa_switch *ds, int port,
304 struct flow_cls_offload *cls, bool ingress)344 struct flow_cls_offload *cls, bool ingress)
305{345{
@@ -321,12 +361,9 @@ int sja1105_cls_flower_add(struct dsa_switch *ds, int port, · 15 unmodified lines
321 flow_action_for_each(i, act, &rule->action) {361 flow_action_for_each(i, act, &rule->action) {
322 switch (act->id) {362 switch (act->id) {
323 case FLOW_ACTION_POLICE:363 case FLOW_ACTION_POLICE:
324 if (act->police.rate_pkt_ps) {364 rc = sja1105_policer_validate(&rule->action, act, extack);
325 NL_SET_ERR_MSG_MOD(extack,365 if (rc)
326 "QoS offload not support packets per second");
327 rc = -EOPNOTSUPP;
328 goto out;366 goto out;
329 }
330 367
331 rc = sja1105_flower_policer(priv, port, extack, cookie,368 rc = sja1105_flower_policer(priv, port, extack, cookie,
332 &key,369 &key,
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c+49−10
@@ -8,6 +8,46 @@ · 7 unmodified lines
8#include "cxgb4_filter.h"8#include "cxgb4_filter.h"
9#include "cxgb4_tc_flower.h"9#include "cxgb4_tc_flower.h"
10 10
11static int cxgb4_policer_validate(const struct flow_action *action,
12 const struct flow_action_entry *act,
13 struct netlink_ext_ack *extack)
14{
15 if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
16 NL_SET_ERR_MSG_MOD(extack,
17 "Offload not supported when exceed action is not drop");
18 return -EOPNOTSUPP;
19 }
20
21 if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
22 act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
23 NL_SET_ERR_MSG_MOD(extack,
24 "Offload not supported when conform action is not pipe or ok");
25 return -EOPNOTSUPP;
26 }
27
28 if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
29 !flow_action_is_last_entry(action, act)) {
30 NL_SET_ERR_MSG_MOD(extack,
31 "Offload not supported when conform action is ok, but action is not last");
32 return -EOPNOTSUPP;
33 }
34
35 if (act->police.peakrate_bytes_ps ||
36 act->police.avrate || act->police.overhead) {
37 NL_SET_ERR_MSG_MOD(extack,
38 "Offload not supported when peakrate/avrate/overhead is configured");
39 return -EOPNOTSUPP;
40 }
41
42 if (act->police.rate_pkt_ps) {
43 NL_SET_ERR_MSG_MOD(extack,
44 "QoS offload not support packets per second");
45 return -EOPNOTSUPP;
46 }
47
48 return 0;
49}
50
11static int cxgb4_matchall_egress_validate(struct net_device *dev,51static int cxgb4_matchall_egress_validate(struct net_device *dev,
12 struct tc_cls_matchall_offload *cls)52 struct tc_cls_matchall_offload *cls)
13{53{
@@ -48,11 +88,10 @@ static int cxgb4_matchall_egress_validate(struct net_device *dev, · 34 unmodified lines
48 flow_action_for_each(i, entry, actions) {88 flow_action_for_each(i, entry, actions) {
49 switch (entry->id) {89 switch (entry->id) {
50 case FLOW_ACTION_POLICE:90 case FLOW_ACTION_POLICE:
51 if (entry->police.rate_pkt_ps) {91 ret = cxgb4_policer_validate(actions, entry, extack);
52 NL_SET_ERR_MSG_MOD(extack,92 if (ret)
53 "QoS offload not support packets per second");93 return ret;
54 return -EOPNOTSUPP;94
55 }
56 /* Convert bytes per second to bits per second */95 /* Convert bytes per second to bits per second */
57 if (entry->police.rate_bytes_ps * 8 > max_link_rate) {96 if (entry->police.rate_bytes_ps * 8 > max_link_rate) {
58 NL_SET_ERR_MSG_MOD(extack,97 NL_SET_ERR_MSG_MOD(extack,
@@ -150,11 +189,11 @@ static int cxgb4_matchall_alloc_tc(struct net_device *dev, · 91 unmodified lines
150 flow_action_for_each(i, entry, &cls->rule->action)189 flow_action_for_each(i, entry, &cls->rule->action)
151 if (entry->id == FLOW_ACTION_POLICE)190 if (entry->id == FLOW_ACTION_POLICE)
152 break;191 break;
153 if (entry->police.rate_pkt_ps) {192
154 NL_SET_ERR_MSG_MOD(extack,193 ret = cxgb4_policer_validate(&cls->rule->action, entry, extack);
155 "QoS offload not support packets per second");194 if (ret)
156 return -EOPNOTSUPP;195 return ret;
157 }196
158 /* Convert from bytes per second to Kbps */197 /* Convert from bytes per second to Kbps */
159 p.u.params.maxrate = div_u64(entry->police.rate_bytes_ps * 8, 1000);198 p.u.params.maxrate = div_u64(entry->police.rate_bytes_ps * 8, 1000);
160 p.u.params.channel = pi->tx_chan;199 p.u.params.channel = pi->tx_chan;
drivers/net/ethernet/freescale/enetc/enetc_qos.c+43−4
@@ -1021,6 +1021,46 @@ static struct actions_fwd *enetc_check_flow_actions(u64 acts, · 1020 unmodified lines
1021 return NULL;1021 return NULL;
1022}1022}
1023 1023
1024static int enetc_psfp_policer_validate(const struct flow_action *action,
1025 const struct flow_action_entry *act,
1026 struct netlink_ext_ack *extack)
1027{
1028 if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
1029 NL_SET_ERR_MSG_MOD(extack,
1030 "Offload not supported when exceed action is not drop");
1031 return -EOPNOTSUPP;
1032 }
1033
1034 if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
1035 act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
1036 NL_SET_ERR_MSG_MOD(extack,
1037 "Offload not supported when conform action is not pipe or ok");
1038 return -EOPNOTSUPP;
1039 }
1040
1041 if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
1042 !flow_action_is_last_entry(action, act)) {
1043 NL_SET_ERR_MSG_MOD(extack,
1044 "Offload not supported when conform action is ok, but action is not last");
1045 return -EOPNOTSUPP;
1046 }
1047
1048 if (act->police.peakrate_bytes_ps ||
1049 act->police.avrate || act->police.overhead) {
1050 NL_SET_ERR_MSG_MOD(extack,
1051 "Offload not supported when peakrate/avrate/overhead is configured");
1052 return -EOPNOTSUPP;
1053 }
1054
1055 if (act->police.rate_pkt_ps) {
1056 NL_SET_ERR_MSG_MOD(extack,
1057 "QoS offload not support packets per second");
1058 return -EOPNOTSUPP;
1059 }
1060
1061 return 0;
1062}
1063
1024static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,1064static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
1025 struct flow_cls_offload *f)1065 struct flow_cls_offload *f)
1026{1066{
@@ -1177,11 +1217,10 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv, · 150 unmodified lines
1177 1217
1178 /* Flow meter and max frame size */1218 /* Flow meter and max frame size */
1179 if (entryp) {1219 if (entryp) {
1180 if (entryp->police.rate_pkt_ps) {1220 err = enetc_psfp_policer_validate(&rule->action, entryp, extack);
1181 NL_SET_ERR_MSG_MOD(extack, "QoS offload not support packets per second");1221 if (err)
1182 err = -EOPNOTSUPP;
1183 goto free_sfi;1222 goto free_sfi;
1184 }1223
1185 if (entryp->police.burst) {1224 if (entryp->police.burst) {
1186 fmi = kzalloc(sizeof(*fmi), GFP_KERNEL);1225 fmi = kzalloc(sizeof(*fmi), GFP_KERNEL);
1187 if (!fmi) {1226 if (!fmi) {
drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c+43−0
@@ -190,6 +190,40 @@ static int otx2_tc_validate_flow(struct otx2_nic *nic, · 189 unmodified lines
190 return 0;190 return 0;
191}191}
192 192
193static int otx2_policer_validate(const struct flow_action *action,
194 const struct flow_action_entry *act,
195 struct netlink_ext_ack *extack)
196{
197 if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
198 NL_SET_ERR_MSG_MOD(extack,
199 "Offload not supported when exceed action is not drop");
200 return -EOPNOTSUPP;
201 }
202
203 if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
204 act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
205 NL_SET_ERR_MSG_MOD(extack,
206 "Offload not supported when conform action is not pipe or ok");
207 return -EOPNOTSUPP;
208 }
209
210 if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
211 !flow_action_is_last_entry(action, act)) {
212 NL_SET_ERR_MSG_MOD(extack,
213 "Offload not supported when conform action is ok, but action is not last");
214 return -EOPNOTSUPP;
215 }
216
217 if (act->police.peakrate_bytes_ps ||
218 act->police.avrate || act->police.overhead) {
219 NL_SET_ERR_MSG_MOD(extack,
220 "Offload not supported when peakrate/avrate/overhead is configured");
221 return -EOPNOTSUPP;
222 }
223
224 return 0;
225}
226
193static int otx2_tc_egress_matchall_install(struct otx2_nic *nic,227static int otx2_tc_egress_matchall_install(struct otx2_nic *nic,
194 struct tc_cls_matchall_offload *cls)228 struct tc_cls_matchall_offload *cls)
195{229{
@@ -212,6 +246,10 @@ static int otx2_tc_egress_matchall_install(struct otx2_nic *nic, · 16 unmodified lines
212 entry = &cls->rule->action.entries[0];246 entry = &cls->rule->action.entries[0];
213 switch (entry->id) {247 switch (entry->id) {
214 case FLOW_ACTION_POLICE:248 case FLOW_ACTION_POLICE:
249 err = otx2_policer_validate(&cls->rule->action, entry, extack);
250 if (err)
251 return err;
252
215 if (entry->police.rate_pkt_ps) {253 if (entry->police.rate_pkt_ps) {
216 NL_SET_ERR_MSG_MOD(extack, "QoS offload not support packets per second");254 NL_SET_ERR_MSG_MOD(extack, "QoS offload not support packets per second");
217 return -EOPNOTSUPP;255 return -EOPNOTSUPP;
@@ -315,6 +353,7 @@ static int otx2_tc_parse_actions(struct otx2_nic *nic, · 97 unmodified lines
315 u8 nr_police = 0;353 u8 nr_police = 0;
316 bool pps = false;354 bool pps = false;
317 u64 rate;355 u64 rate;
356 int err;
318 int i;357 int i;
319 358
320 if (!flow_action_has_entries(flow_action)) {359 if (!flow_action_has_entries(flow_action)) {
@@ -355,6 +394,10 @@ static int otx2_tc_parse_actions(struct otx2_nic *nic, · 34 unmodified lines
355 return -EOPNOTSUPP;394 return -EOPNOTSUPP;
356 }395 }
357 396
397 err = otx2_policer_validate(flow_action, act, extack);
398 if (err)
399 return err;
400
358 if (act->police.rate_bytes_ps > 0) {401 if (act->police.rate_bytes_ps > 0) {
359 rate = act->police.rate_bytes_ps * 8;402 rate = act->police.rate_bytes_ps * 8;
360 burst = act->police.burst;403 burst = act->police.burst;
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c+44−4
@@ -4482,6 +4482,46 @@ static int apply_police_params(struct mlx5e_priv *priv, u64 rate, · 4481 unmodified lines
4482 return err;4482 return err;
4483}4483}
4484 4484
4485static int mlx5e_policer_validate(const struct flow_action *action,
4486 const struct flow_action_entry *act,
4487 struct netlink_ext_ack *extack)
4488{
4489 if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
4490 NL_SET_ERR_MSG_MOD(extack,
4491 "Offload not supported when exceed action is not drop");
4492 return -EOPNOTSUPP;
4493 }
4494
4495 if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
4496 act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
4497 NL_SET_ERR_MSG_MOD(extack,
4498 "Offload not supported when conform action is not pipe or ok");
4499 return -EOPNOTSUPP;
4500 }
4501
4502 if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
4503 !flow_action_is_last_entry(action, act)) {
4504 NL_SET_ERR_MSG_MOD(extack,
4505 "Offload not supported when conform action is ok, but action is not last");
4506 return -EOPNOTSUPP;
4507 }
4508
4509 if (act->police.peakrate_bytes_ps ||
4510 act->police.avrate || act->police.overhead) {
4511 NL_SET_ERR_MSG_MOD(extack,
4512 "Offload not supported when peakrate/avrate/overhead is configured");
4513 return -EOPNOTSUPP;
4514 }
4515
4516 if (act->police.rate_pkt_ps) {
4517 NL_SET_ERR_MSG_MOD(extack,
4518 "QoS offload not support packets per second");
4519 return -EOPNOTSUPP;
4520 }
4521
4522 return 0;
4523}
4524
4485static int scan_tc_matchall_fdb_actions(struct mlx5e_priv *priv,4525static int scan_tc_matchall_fdb_actions(struct mlx5e_priv *priv,
4486 struct flow_action *flow_action,4526 struct flow_action *flow_action,
4487 struct netlink_ext_ack *extack)4527 struct netlink_ext_ack *extack)
@@ -4509,10 +4549,10 @@ static int scan_tc_matchall_fdb_actions(struct mlx5e_priv *priv, · 21 unmodified lines
4509 flow_action_for_each(i, act, flow_action) {4549 flow_action_for_each(i, act, flow_action) {
4510 switch (act->id) {4550 switch (act->id) {
4511 case FLOW_ACTION_POLICE:4551 case FLOW_ACTION_POLICE:
4512 if (act->police.rate_pkt_ps) {4552 err = mlx5e_policer_validate(flow_action, act, extack);
4513 NL_SET_ERR_MSG_MOD(extack, "QoS offload not support packets per second");4553 if (err)
4514 return -EOPNOTSUPP;4554 return err;
4515 }4555
4516 err = apply_police_params(priv, act->police.rate_bytes_ps, extack);4556 err = apply_police_params(priv, act->police.rate_bytes_ps, extack);
4517 if (err)4557 if (err)
4518 return err;4558 return err;
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c+43−4
@@ -15,6 +15,46 @@ · 14 unmodified lines
15#include "spectrum.h"15#include "spectrum.h"
16#include "core_acl_flex_keys.h"16#include "core_acl_flex_keys.h"
17 17
18static int mlxsw_sp_policer_validate(const struct flow_action *action,
19 const struct flow_action_entry *act,
20 struct netlink_ext_ack *extack)
21{
22 if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
23 NL_SET_ERR_MSG_MOD(extack,
24 "Offload not supported when exceed action is not drop");
25 return -EOPNOTSUPP;
26 }
27
28 if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
29 act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
30 NL_SET_ERR_MSG_MOD(extack,
31 "Offload not supported when conform action is not pipe or ok");
32 return -EOPNOTSUPP;
33 }
34
35 if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
36 !flow_action_is_last_entry(action, act)) {
37 NL_SET_ERR_MSG_MOD(extack,
38 "Offload not supported when conform action is ok, but action is not last");
39 return -EOPNOTSUPP;
40 }
41
42 if (act->police.peakrate_bytes_ps ||
43 act->police.avrate || act->police.overhead) {
44 NL_SET_ERR_MSG_MOD(extack,
45 "Offload not supported when peakrate/avrate/overhead is configured");
46 return -EOPNOTSUPP;
47 }
48
49 if (act->police.rate_pkt_ps) {
50 NL_SET_ERR_MSG_MOD(extack,
51 "QoS offload not support packets per second");
52 return -EOPNOTSUPP;
53 }
54
55 return 0;
56}
57
18static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,58static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
19 struct mlxsw_sp_flow_block *block,59 struct mlxsw_sp_flow_block *block,
20 struct mlxsw_sp_acl_rule_info *rulei,60 struct mlxsw_sp_acl_rule_info *rulei,
@@ -191,10 +231,9 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, · 170 unmodified lines
191 return -EOPNOTSUPP;231 return -EOPNOTSUPP;
192 }232 }
193 233
194 if (act->police.rate_pkt_ps) {234 err = mlxsw_sp_policer_validate(flow_action, act, extack);
195 NL_SET_ERR_MSG_MOD(extack, "QoS offload not support packets per second");235 if (err)
196 return -EOPNOTSUPP;236 return err;
197 }
198 237
199 /* The kernel might adjust the requested burst size so238 /* The kernel might adjust the requested burst size so
200 * that it is not exactly a power of two. Re-adjust it239 * that it is not exactly a power of two. Re-adjust it
drivers/net/ethernet/mscc/ocelot_flower.c+8−6
@@ -6,6 +6,7 @@ · 5 unmodified lines
6#include <net/pkt_cls.h>6#include <net/pkt_cls.h>
7#include <net/tc_act/tc_gact.h>7#include <net/tc_act/tc_gact.h>
8#include <soc/mscc/ocelot_vcap.h>8#include <soc/mscc/ocelot_vcap.h>
9#include "ocelot_police.h"
9#include "ocelot_vcap.h"10#include "ocelot_vcap.h"
10 11
11/* Arbitrarily chosen constants for encoding the VCAP block and lookup number12/* Arbitrarily chosen constants for encoding the VCAP block and lookup number
@@ -217,6 +218,7 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port, · 205 unmodified lines
217 bool ingress, struct flow_cls_offload *f,218 bool ingress, struct flow_cls_offload *f,
218 struct ocelot_vcap_filter *filter)219 struct ocelot_vcap_filter *filter)
219{220{
221 const struct flow_action *action = &f->rule->action;
220 struct netlink_ext_ack *extack = f->common.extack;222 struct netlink_ext_ack *extack = f->common.extack;
221 bool allow_missing_goto_target = false;223 bool allow_missing_goto_target = false;
222 const struct flow_action_entry *a;224 const struct flow_action_entry *a;
@@ -244,7 +246,7 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port, · 21 unmodified lines
244 filter->goto_target = -1;246 filter->goto_target = -1;
245 filter->type = OCELOT_VCAP_FILTER_DUMMY;247 filter->type = OCELOT_VCAP_FILTER_DUMMY;
246 248
247 flow_action_for_each(i, a, &f->rule->action) {249 flow_action_for_each(i, a, action) {
248 switch (a->id) {250 switch (a->id) {
249 case FLOW_ACTION_DROP:251 case FLOW_ACTION_DROP:
250 if (filter->block_id != VCAP_IS2) {252 if (filter->block_id != VCAP_IS2) {
@@ -297,11 +299,11 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port, · 46 unmodified lines
297 "Last action must be GOTO");299 "Last action must be GOTO");
298 return -EOPNOTSUPP;300 return -EOPNOTSUPP;
299 }301 }
300 if (a->police.rate_pkt_ps) {302
301 NL_SET_ERR_MSG_MOD(extack,303 err = ocelot_policer_validate(action, a, extack);
302 "QoS offload not support packets per second");304 if (err)
303 return -EOPNOTSUPP;305 return err;
304 }306
305 filter->action.police_ena = true;307 filter->action.police_ena = true;
306 308
307 pol_ix = a->hw_index + ocelot->vcap_pol.base;309 pol_ix = a->hw_index + ocelot->vcap_pol.base;
drivers/net/ethernet/mscc/ocelot_net.c+5−5
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <linux/phy/phy.h>14#include <linux/phy/phy.h>
15#include <net/pkt_cls.h>15#include <net/pkt_cls.h>
16#include "ocelot.h"16#include "ocelot.h"
17#include "ocelot_police.h"
17#include "ocelot_vcap.h"18#include "ocelot_vcap.h"
18#include "ocelot_fdma.h"19#include "ocelot_fdma.h"
19 20
@@ -258,11 +259,10 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv, · 238 unmodified lines
258 return -EEXIST;259 return -EEXIST;
259 }260 }
260 261
261 if (action->police.rate_pkt_ps) {262 err = ocelot_policer_validate(&f->rule->action, action,
262 NL_SET_ERR_MSG_MOD(extack,263 extack);
263 "QoS offload not support packets per second");264 if (err)
264 return -EOPNOTSUPP;265 return err;
265 }
266 266
267 pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8;267 pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8;
268 pol.burst = action->police.burst;268 pol.burst = action->police.burst;
drivers/net/ethernet/mscc/ocelot_police.c+41−0
@@ -154,6 +154,47 @@ int qos_policer_conf_set(struct ocelot *ocelot, int port, u32 pol_ix, · 153 unmodified lines
154 return 0;154 return 0;
155}155}
156 156
157int ocelot_policer_validate(const struct flow_action *action,
158 const struct flow_action_entry *a,
159 struct netlink_ext_ack *extack)
160{
161 if (a->police.exceed.act_id != FLOW_ACTION_DROP) {
162 NL_SET_ERR_MSG_MOD(extack,
163 "Offload not supported when exceed action is not drop");
164 return -EOPNOTSUPP;
165 }
166
167 if (a->police.notexceed.act_id != FLOW_ACTION_PIPE &&
168 a->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
169 NL_SET_ERR_MSG_MOD(extack,
170 "Offload not supported when conform action is not pipe or ok");
171 return -EOPNOTSUPP;
172 }
173
174 if (a->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
175 !flow_action_is_last_entry(action, a)) {
176 NL_SET_ERR_MSG_MOD(extack,
177 "Offload not supported when conform action is ok, but police action is not last");
178 return -EOPNOTSUPP;
179 }
180
181 if (a->police.peakrate_bytes_ps ||
182 a->police.avrate || a->police.overhead) {
183 NL_SET_ERR_MSG_MOD(extack,
184 "Offload not supported when peakrate/avrate/overhead is configured");
185 return -EOPNOTSUPP;
186 }
187
188 if (a->police.rate_pkt_ps) {
189 NL_SET_ERR_MSG_MOD(extack,
190 "Offload does not support packets per second");
191 return -EOPNOTSUPP;
192 }
193
194 return 0;
195}
196EXPORT_SYMBOL(ocelot_policer_validate);
197
157int ocelot_port_policer_add(struct ocelot *ocelot, int port,198int ocelot_port_policer_add(struct ocelot *ocelot, int port,
158 struct ocelot_policer *pol)199 struct ocelot_policer *pol)
159{200{
drivers/net/ethernet/mscc/ocelot_police.h+5−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
8#define _MSCC_OCELOT_POLICE_H_8#define _MSCC_OCELOT_POLICE_H_
9 9
10#include "ocelot.h"10#include "ocelot.h"
11#include <net/flow_offload.h>
11 12
12enum mscc_qos_rate_mode {13enum mscc_qos_rate_mode {
13 MSCC_QOS_RATE_MODE_DISABLED, /* Policer/shaper disabled */14 MSCC_QOS_RATE_MODE_DISABLED, /* Policer/shaper disabled */
@@ -33,4 +34,8 @@ struct qos_policer_conf { · 19 unmodified lines
33int qos_policer_conf_set(struct ocelot *ocelot, int port, u32 pol_ix,34int qos_policer_conf_set(struct ocelot *ocelot, int port, u32 pol_ix,
34 struct qos_policer_conf *conf);35 struct qos_policer_conf *conf);
35 36
37int ocelot_policer_validate(const struct flow_action *action,
38 const struct flow_action_entry *a,
39 struct netlink_ext_ack *extack);
40
36#endif /* _MSCC_OCELOT_POLICE_H_ */41#endif /* _MSCC_OCELOT_POLICE_H_ */
drivers/net/ethernet/netronome/nfp/flower/qos_conf.c+40−0
@@ -117,6 +117,40 @@ int nfp_flower_offload_one_police(struct nfp_app *app, bool ingress, · 116 unmodified lines
117 return 0;117 return 0;
118}118}
119 119
120static int nfp_policer_validate(const struct flow_action *action,
121 const struct flow_action_entry *act,
122 struct netlink_ext_ack *extack)
123{
124 if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
125 NL_SET_ERR_MSG_MOD(extack,
126 "Offload not supported when exceed action is not drop");
127 return -EOPNOTSUPP;
128 }
129
130 if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
131 act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
132 NL_SET_ERR_MSG_MOD(extack,
133 "Offload not supported when conform action is not pipe or ok");
134 return -EOPNOTSUPP;
135 }
136
137 if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
138 !flow_action_is_last_entry(action, act)) {
139 NL_SET_ERR_MSG_MOD(extack,
140 "Offload not supported when conform action is ok, but action is not last");
141 return -EOPNOTSUPP;
142 }
143
144 if (act->police.peakrate_bytes_ps ||
145 act->police.avrate || act->police.overhead) {
146 NL_SET_ERR_MSG_MOD(extack,
147 "Offload not supported when peakrate/avrate/overhead is configured");
148 return -EOPNOTSUPP;
149 }
150
151 return 0;
152}
153
120static int154static int
121nfp_flower_install_rate_limiter(struct nfp_app *app, struct net_device *netdev,155nfp_flower_install_rate_limiter(struct nfp_app *app, struct net_device *netdev,
122 struct tc_cls_matchall_offload *flow,156 struct tc_cls_matchall_offload *flow,
@@ -135,6 +169,7 @@ nfp_flower_install_rate_limiter(struct nfp_app *app, struct net_device *netdev, · 12 unmodified lines
135 u32 burst;169 u32 burst;
136 bool pps;170 bool pps;
137 u64 rate;171 u64 rate;
172 int err;
138 173
139 if (!nfp_netdev_is_nfp_repr(netdev)) {174 if (!nfp_netdev_is_nfp_repr(netdev)) {
140 NL_SET_ERR_MSG_MOD(extack, "unsupported offload: qos rate limit offload not supported on higher level port");175 NL_SET_ERR_MSG_MOD(extack, "unsupported offload: qos rate limit offload not supported on higher level port");
@@ -181,6 +216,11 @@ nfp_flower_install_rate_limiter(struct nfp_app *app, struct net_device *netdev, · 40 unmodified lines
181 "unsupported offload: qos rate limit offload requires police action");216 "unsupported offload: qos rate limit offload requires police action");
182 return -EOPNOTSUPP;217 return -EOPNOTSUPP;
183 }218 }
219
220 err = nfp_policer_validate(&flow->rule->action, action, extack);
221 if (err)
222 return err;
223
184 if (action->police.rate_bytes_ps > 0) {224 if (action->police.rate_bytes_ps > 0) {
185 if (bps_num++) {225 if (bps_num++) {
186 NL_SET_ERR_MSG_MOD(extack,226 NL_SET_ERR_MSG_MOD(extack,
include/net/flow_offload.h+15−0
@@ -148,6 +148,8 @@ enum flow_action_id { · 147 unmodified lines
148 FLOW_ACTION_MPLS_MANGLE,148 FLOW_ACTION_MPLS_MANGLE,
149 FLOW_ACTION_GATE,149 FLOW_ACTION_GATE,
150 FLOW_ACTION_PPPOE_PUSH,150 FLOW_ACTION_PPPOE_PUSH,
151 FLOW_ACTION_JUMP,
152 FLOW_ACTION_PIPE,
151 NUM_FLOW_ACTIONS,153 NUM_FLOW_ACTIONS,
152};154};
153 155
@@ -235,9 +237,16 @@ struct flow_action_entry { · 81 unmodified lines
235 struct { /* FLOW_ACTION_POLICE */237 struct { /* FLOW_ACTION_POLICE */
236 u32 burst;238 u32 burst;
237 u64 rate_bytes_ps;239 u64 rate_bytes_ps;
240 u64 peakrate_bytes_ps;
241 u32 avrate;
242 u16 overhead;
238 u64 burst_pkt;243 u64 burst_pkt;
239 u64 rate_pkt_ps;244 u64 rate_pkt_ps;
240 u32 mtu;245 u32 mtu;
246 struct {
247 enum flow_action_id act_id;
248 u32 extval;
249 } exceed, notexceed;
241 } police;250 } police;
242 struct { /* FLOW_ACTION_CT */251 struct { /* FLOW_ACTION_CT */
243 int action;252 int action;
@@ -302,6 +311,12 @@ static inline bool flow_offload_has_one_action(const struct flow_action *action) · 58 unmodified lines
302 return action->num_entries == 1;311 return action->num_entries == 1;
303}312}
304 313
314static inline bool flow_action_is_last_entry(const struct flow_action *action,
315 const struct flow_action_entry *entry)
316{
317 return entry == &action->entries[action->num_entries - 1];
318}
319
305#define flow_action_for_each(__i, __act, __actions) \320#define flow_action_for_each(__i, __act, __actions) \
306 for (__i = 0, __act = &(__actions)->entries[0]; \321 for (__i = 0, __act = &(__actions)->entries[0]; \
307 __i < (__actions)->num_entries; \322 __i < (__actions)->num_entries; \
include/net/tc_act/tc_police.h+30−0
@@ -159,4 +159,34 @@ static inline u32 tcf_police_tcfp_mtu(const struct tc_action *act) · 158 unmodified lines
159 return params->tcfp_mtu;159 return params->tcfp_mtu;
160}160}
161 161
162static inline u64 tcf_police_peakrate_bytes_ps(const struct tc_action *act)
163{
164 struct tcf_police *police = to_police(act);
165 struct tcf_police_params *params;
166
167 params = rcu_dereference_protected(police->params,
168 lockdep_is_held(&police->tcf_lock));
169 return params->peak.rate_bytes_ps;
170}
171
172static inline u32 tcf_police_tcfp_ewma_rate(const struct tc_action *act)
173{
174 struct tcf_police *police = to_police(act);
175 struct tcf_police_params *params;
176
177 params = rcu_dereference_protected(police->params,
178 lockdep_is_held(&police->tcf_lock));
179 return params->tcfp_ewma_rate;
180}
181
182static inline u16 tcf_police_rate_overhead(const struct tc_action *act)
183{
184 struct tcf_police *police = to_police(act);
185 struct tcf_police_params *params;
186
187 params = rcu_dereference_protected(police->params,
188 lockdep_is_held(&police->tcf_lock));
189 return params->rate.overhead;
190}
191
162#endif /* __NET_TC_POLICE_H */192#endif /* __NET_TC_POLICE_H */
net/sched/act_police.c+46−0
@@ -419,20 +419,66 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index) · 418 unmodified lines
419 return tcf_idr_search(tn, a, index);419 return tcf_idr_search(tn, a, index);
420}420}
421 421
422static int tcf_police_act_to_flow_act(int tc_act, u32 *extval)
423{
424 int act_id = -EOPNOTSUPP;
425
426 if (!TC_ACT_EXT_OPCODE(tc_act)) {
427 if (tc_act == TC_ACT_OK)
428 act_id = FLOW_ACTION_ACCEPT;
429 else if (tc_act == TC_ACT_SHOT)
430 act_id = FLOW_ACTION_DROP;
431 else if (tc_act == TC_ACT_PIPE)
432 act_id = FLOW_ACTION_PIPE;
433 } else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_GOTO_CHAIN)) {
434 act_id = FLOW_ACTION_GOTO;
435 *extval = tc_act & TC_ACT_EXT_VAL_MASK;
436 } else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_JUMP)) {
437 act_id = FLOW_ACTION_JUMP;
438 *extval = tc_act & TC_ACT_EXT_VAL_MASK;
439 }
440
441 return act_id;
442}
443
422static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,444static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,
423 u32 *index_inc, bool bind)445 u32 *index_inc, bool bind)
424{446{
425 if (bind) {447 if (bind) {
426 struct flow_action_entry *entry = entry_data;448 struct flow_action_entry *entry = entry_data;
449 struct tcf_police *police = to_police(act);
450 struct tcf_police_params *p;
451 int act_id;
452
453 p = rcu_dereference_protected(police->params,
454 lockdep_is_held(&police->tcf_lock));
427 455
428 entry->id = FLOW_ACTION_POLICE;456 entry->id = FLOW_ACTION_POLICE;
429 entry->police.burst = tcf_police_burst(act);457 entry->police.burst = tcf_police_burst(act);
430 entry->police.rate_bytes_ps =458 entry->police.rate_bytes_ps =
431 tcf_police_rate_bytes_ps(act);459 tcf_police_rate_bytes_ps(act);
460 entry->police.peakrate_bytes_ps = tcf_police_peakrate_bytes_ps(act);
461 entry->police.avrate = tcf_police_tcfp_ewma_rate(act);
462 entry->police.overhead = tcf_police_rate_overhead(act);
432 entry->police.burst_pkt = tcf_police_burst_pkt(act);463 entry->police.burst_pkt = tcf_police_burst_pkt(act);
433 entry->police.rate_pkt_ps =464 entry->police.rate_pkt_ps =
434 tcf_police_rate_pkt_ps(act);465 tcf_police_rate_pkt_ps(act);
435 entry->police.mtu = tcf_police_tcfp_mtu(act);466 entry->police.mtu = tcf_police_tcfp_mtu(act);
467
468 act_id = tcf_police_act_to_flow_act(police->tcf_action,
469 &entry->police.exceed.extval);
470 if (act_id < 0)
471 return act_id;
472
473 entry->police.exceed.act_id = act_id;
474
475 act_id = tcf_police_act_to_flow_act(p->tcfp_result,
476 &entry->police.notexceed.extval);
477 if (act_id < 0)
478 return act_id;
479
480 entry->police.notexceed.act_id = act_id;
481
436 *index_inc = 1;482 *index_inc = 1;
437 } else {483 } else {
438 struct flow_offload_action *fl_action = entry_data;484 struct flow_offload_action *fl_action = entry_data;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t