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

net: flow_offload: add tc police action parameters

The current police offload action entry is missing exceed/notexceed
actions and parameters that can be configured by tc police action.
Add the missing parameters as a pre-step for offloading police actions
to hardware.

Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
Signed-off-by: Roi Dayan <roid@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jianbo Liu and committed by
David S. Miller
b8cd5831 b42a738e

+85
+9
include/net/flow_offload.h
··· 148 148 FLOW_ACTION_MPLS_MANGLE, 149 149 FLOW_ACTION_GATE, 150 150 FLOW_ACTION_PPPOE_PUSH, 151 + FLOW_ACTION_JUMP, 152 + FLOW_ACTION_PIPE, 151 153 NUM_FLOW_ACTIONS, 152 154 }; 153 155 ··· 237 235 struct { /* FLOW_ACTION_POLICE */ 238 236 u32 burst; 239 237 u64 rate_bytes_ps; 238 + u64 peakrate_bytes_ps; 239 + u32 avrate; 240 + u16 overhead; 240 241 u64 burst_pkt; 241 242 u64 rate_pkt_ps; 242 243 u32 mtu; 244 + struct { 245 + enum flow_action_id act_id; 246 + u32 extval; 247 + } exceed, notexceed; 243 248 } police; 244 249 struct { /* FLOW_ACTION_CT */ 245 250 int action;
+30
include/net/tc_act/tc_police.h
··· 159 159 return params->tcfp_mtu; 160 160 } 161 161 162 + static 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 + 172 + static 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 + 182 + static 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 192 #endif /* __NET_TC_POLICE_H */
+46
net/sched/act_police.c
··· 419 419 return tcf_idr_search(tn, a, index); 420 420 } 421 421 422 + static 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 + 422 444 static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data, 423 445 u32 *index_inc, bool bind) 424 446 { 425 447 if (bind) { 426 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 456 entry->id = FLOW_ACTION_POLICE; 429 457 entry->police.burst = tcf_police_burst(act); 430 458 entry->police.rate_bytes_ps = 431 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 463 entry->police.burst_pkt = tcf_police_burst_pkt(act); 433 464 entry->police.rate_pkt_ps = 434 465 tcf_police_rate_pkt_ps(act); 435 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 482 *index_inc = 1; 437 483 } else { 438 484 struct flow_offload_action *fl_action = entry_data;