162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __NET_TC_POLICE_H 362306a36Sopenharmony_ci#define __NET_TC_POLICE_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <net/act_api.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_cistruct tcf_police_params { 862306a36Sopenharmony_ci int tcfp_result; 962306a36Sopenharmony_ci u32 tcfp_ewma_rate; 1062306a36Sopenharmony_ci s64 tcfp_burst; 1162306a36Sopenharmony_ci u32 tcfp_mtu; 1262306a36Sopenharmony_ci s64 tcfp_mtu_ptoks; 1362306a36Sopenharmony_ci s64 tcfp_pkt_burst; 1462306a36Sopenharmony_ci struct psched_ratecfg rate; 1562306a36Sopenharmony_ci bool rate_present; 1662306a36Sopenharmony_ci struct psched_ratecfg peak; 1762306a36Sopenharmony_ci bool peak_present; 1862306a36Sopenharmony_ci struct psched_pktrate ppsrate; 1962306a36Sopenharmony_ci bool pps_present; 2062306a36Sopenharmony_ci struct rcu_head rcu; 2162306a36Sopenharmony_ci}; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistruct tcf_police { 2462306a36Sopenharmony_ci struct tc_action common; 2562306a36Sopenharmony_ci struct tcf_police_params __rcu *params; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci spinlock_t tcfp_lock ____cacheline_aligned_in_smp; 2862306a36Sopenharmony_ci s64 tcfp_toks; 2962306a36Sopenharmony_ci s64 tcfp_ptoks; 3062306a36Sopenharmony_ci s64 tcfp_pkttoks; 3162306a36Sopenharmony_ci s64 tcfp_t_c; 3262306a36Sopenharmony_ci}; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define to_police(pc) ((struct tcf_police *)pc) 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci/* old policer structure from before tc actions */ 3762306a36Sopenharmony_cistruct tc_police_compat { 3862306a36Sopenharmony_ci u32 index; 3962306a36Sopenharmony_ci int action; 4062306a36Sopenharmony_ci u32 limit; 4162306a36Sopenharmony_ci u32 burst; 4262306a36Sopenharmony_ci u32 mtu; 4362306a36Sopenharmony_ci struct tc_ratespec rate; 4462306a36Sopenharmony_ci struct tc_ratespec peakrate; 4562306a36Sopenharmony_ci}; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistatic inline bool is_tcf_police(const struct tc_action *act) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci#ifdef CONFIG_NET_CLS_ACT 5062306a36Sopenharmony_ci if (act->ops && act->ops->id == TCA_ID_POLICE) 5162306a36Sopenharmony_ci return true; 5262306a36Sopenharmony_ci#endif 5362306a36Sopenharmony_ci return false; 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistatic inline u64 tcf_police_rate_bytes_ps(const struct tc_action *act) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci struct tcf_police *police = to_police(act); 5962306a36Sopenharmony_ci struct tcf_police_params *params; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci params = rcu_dereference_protected(police->params, 6262306a36Sopenharmony_ci lockdep_is_held(&police->tcf_lock)); 6362306a36Sopenharmony_ci return params->rate.rate_bytes_ps; 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistatic inline u32 tcf_police_burst(const struct tc_action *act) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci struct tcf_police *police = to_police(act); 6962306a36Sopenharmony_ci struct tcf_police_params *params; 7062306a36Sopenharmony_ci u32 burst; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci params = rcu_dereference_protected(police->params, 7362306a36Sopenharmony_ci lockdep_is_held(&police->tcf_lock)); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci /* 7662306a36Sopenharmony_ci * "rate" bytes "burst" nanoseconds 7762306a36Sopenharmony_ci * ------------ * ------------------- 7862306a36Sopenharmony_ci * 1 second 2^6 ticks 7962306a36Sopenharmony_ci * 8062306a36Sopenharmony_ci * ------------------------------------ 8162306a36Sopenharmony_ci * NSEC_PER_SEC nanoseconds 8262306a36Sopenharmony_ci * ------------------------ 8362306a36Sopenharmony_ci * 2^6 ticks 8462306a36Sopenharmony_ci * 8562306a36Sopenharmony_ci * "rate" bytes "burst" nanoseconds 2^6 ticks 8662306a36Sopenharmony_ci * = ------------ * ------------------- * ------------------------ 8762306a36Sopenharmony_ci * 1 second 2^6 ticks NSEC_PER_SEC nanoseconds 8862306a36Sopenharmony_ci * 8962306a36Sopenharmony_ci * "rate" * "burst" 9062306a36Sopenharmony_ci * = ---------------- bytes/nanosecond 9162306a36Sopenharmony_ci * NSEC_PER_SEC^2 9262306a36Sopenharmony_ci * 9362306a36Sopenharmony_ci * 9462306a36Sopenharmony_ci * "rate" * "burst" 9562306a36Sopenharmony_ci * = ---------------- bytes/second 9662306a36Sopenharmony_ci * NSEC_PER_SEC 9762306a36Sopenharmony_ci */ 9862306a36Sopenharmony_ci burst = div_u64(params->tcfp_burst * params->rate.rate_bytes_ps, 9962306a36Sopenharmony_ci NSEC_PER_SEC); 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci return burst; 10262306a36Sopenharmony_ci} 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistatic inline u64 tcf_police_rate_pkt_ps(const struct tc_action *act) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci struct tcf_police *police = to_police(act); 10762306a36Sopenharmony_ci struct tcf_police_params *params; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci params = rcu_dereference_protected(police->params, 11062306a36Sopenharmony_ci lockdep_is_held(&police->tcf_lock)); 11162306a36Sopenharmony_ci return params->ppsrate.rate_pkts_ps; 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic inline u32 tcf_police_burst_pkt(const struct tc_action *act) 11562306a36Sopenharmony_ci{ 11662306a36Sopenharmony_ci struct tcf_police *police = to_police(act); 11762306a36Sopenharmony_ci struct tcf_police_params *params; 11862306a36Sopenharmony_ci u32 burst; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci params = rcu_dereference_protected(police->params, 12162306a36Sopenharmony_ci lockdep_is_held(&police->tcf_lock)); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci /* 12462306a36Sopenharmony_ci * "rate" pkts "burst" nanoseconds 12562306a36Sopenharmony_ci * ------------ * ------------------- 12662306a36Sopenharmony_ci * 1 second 2^6 ticks 12762306a36Sopenharmony_ci * 12862306a36Sopenharmony_ci * ------------------------------------ 12962306a36Sopenharmony_ci * NSEC_PER_SEC nanoseconds 13062306a36Sopenharmony_ci * ------------------------ 13162306a36Sopenharmony_ci * 2^6 ticks 13262306a36Sopenharmony_ci * 13362306a36Sopenharmony_ci * "rate" pkts "burst" nanoseconds 2^6 ticks 13462306a36Sopenharmony_ci * = ------------ * ------------------- * ------------------------ 13562306a36Sopenharmony_ci * 1 second 2^6 ticks NSEC_PER_SEC nanoseconds 13662306a36Sopenharmony_ci * 13762306a36Sopenharmony_ci * "rate" * "burst" 13862306a36Sopenharmony_ci * = ---------------- pkts/nanosecond 13962306a36Sopenharmony_ci * NSEC_PER_SEC^2 14062306a36Sopenharmony_ci * 14162306a36Sopenharmony_ci * 14262306a36Sopenharmony_ci * "rate" * "burst" 14362306a36Sopenharmony_ci * = ---------------- pkts/second 14462306a36Sopenharmony_ci * NSEC_PER_SEC 14562306a36Sopenharmony_ci */ 14662306a36Sopenharmony_ci burst = div_u64(params->tcfp_pkt_burst * params->ppsrate.rate_pkts_ps, 14762306a36Sopenharmony_ci NSEC_PER_SEC); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci return burst; 15062306a36Sopenharmony_ci} 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_cistatic inline u32 tcf_police_tcfp_mtu(const struct tc_action *act) 15362306a36Sopenharmony_ci{ 15462306a36Sopenharmony_ci struct tcf_police *police = to_police(act); 15562306a36Sopenharmony_ci struct tcf_police_params *params; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci params = rcu_dereference_protected(police->params, 15862306a36Sopenharmony_ci lockdep_is_held(&police->tcf_lock)); 15962306a36Sopenharmony_ci return params->tcfp_mtu; 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cistatic inline u64 tcf_police_peakrate_bytes_ps(const struct tc_action *act) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci struct tcf_police *police = to_police(act); 16562306a36Sopenharmony_ci struct tcf_police_params *params; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci params = rcu_dereference_protected(police->params, 16862306a36Sopenharmony_ci lockdep_is_held(&police->tcf_lock)); 16962306a36Sopenharmony_ci return params->peak.rate_bytes_ps; 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistatic inline u32 tcf_police_tcfp_ewma_rate(const struct tc_action *act) 17362306a36Sopenharmony_ci{ 17462306a36Sopenharmony_ci struct tcf_police *police = to_police(act); 17562306a36Sopenharmony_ci struct tcf_police_params *params; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci params = rcu_dereference_protected(police->params, 17862306a36Sopenharmony_ci lockdep_is_held(&police->tcf_lock)); 17962306a36Sopenharmony_ci return params->tcfp_ewma_rate; 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_cistatic inline u16 tcf_police_rate_overhead(const struct tc_action *act) 18362306a36Sopenharmony_ci{ 18462306a36Sopenharmony_ci struct tcf_police *police = to_police(act); 18562306a36Sopenharmony_ci struct tcf_police_params *params; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci params = rcu_dereference_protected(police->params, 18862306a36Sopenharmony_ci lockdep_is_held(&police->tcf_lock)); 18962306a36Sopenharmony_ci return params->rate.overhead; 19062306a36Sopenharmony_ci} 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci#endif /* __NET_TC_POLICE_H */ 193