xref: /openbmc/linux/include/net/tc_act/tc_police.h (revision d58f75de)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __NET_TC_POLICE_H
3 #define __NET_TC_POLICE_H
4 
5 #include <net/act_api.h>
6 
7 struct tcf_police_params {
8 	int			tcfp_result;
9 	u32			tcfp_ewma_rate;
10 	s64			tcfp_burst;
11 	u32			tcfp_mtu;
12 	s64			tcfp_mtu_ptoks;
13 	s64			tcfp_pkt_burst;
14 	struct psched_ratecfg	rate;
15 	bool			rate_present;
16 	struct psched_ratecfg	peak;
17 	bool			peak_present;
18 	struct psched_pktrate	ppsrate;
19 	bool			pps_present;
20 	struct rcu_head rcu;
21 };
22 
23 struct tcf_police {
24 	struct tc_action	common;
25 	struct tcf_police_params __rcu *params;
26 
27 	spinlock_t		tcfp_lock ____cacheline_aligned_in_smp;
28 	s64			tcfp_toks;
29 	s64			tcfp_ptoks;
30 	s64			tcfp_pkttoks;
31 	s64			tcfp_t_c;
32 };
33 
34 #define to_police(pc) ((struct tcf_police *)pc)
35 
36 /* old policer structure from before tc actions */
37 struct tc_police_compat {
38 	u32			index;
39 	int			action;
40 	u32			limit;
41 	u32			burst;
42 	u32			mtu;
43 	struct tc_ratespec	rate;
44 	struct tc_ratespec	peakrate;
45 };
46 
47 static inline bool is_tcf_police(const struct tc_action *act)
48 {
49 #ifdef CONFIG_NET_CLS_ACT
50 	if (act->ops && act->ops->id == TCA_ID_POLICE)
51 		return true;
52 #endif
53 	return false;
54 }
55 
56 static inline u64 tcf_police_rate_bytes_ps(const struct tc_action *act)
57 {
58 	struct tcf_police *police = to_police(act);
59 	struct tcf_police_params *params;
60 
61 	params = rcu_dereference_protected(police->params,
62 					   lockdep_is_held(&police->tcf_lock));
63 	return params->rate.rate_bytes_ps;
64 }
65 
66 static inline u32 tcf_police_burst(const struct tc_action *act)
67 {
68 	struct tcf_police *police = to_police(act);
69 	struct tcf_police_params *params;
70 	u32 burst;
71 
72 	params = rcu_dereference_protected(police->params,
73 					   lockdep_is_held(&police->tcf_lock));
74 
75 	/*
76 	 *  "rate" bytes   "burst" nanoseconds
77 	 *  ------------ * -------------------
78 	 *    1 second          2^6 ticks
79 	 *
80 	 * ------------------------------------
81 	 *        NSEC_PER_SEC nanoseconds
82 	 *        ------------------------
83 	 *              2^6 ticks
84 	 *
85 	 *    "rate" bytes   "burst" nanoseconds            2^6 ticks
86 	 *  = ------------ * ------------------- * ------------------------
87 	 *      1 second          2^6 ticks        NSEC_PER_SEC nanoseconds
88 	 *
89 	 *   "rate" * "burst"
90 	 * = ---------------- bytes/nanosecond
91 	 *    NSEC_PER_SEC^2
92 	 *
93 	 *
94 	 *   "rate" * "burst"
95 	 * = ---------------- bytes/second
96 	 *     NSEC_PER_SEC
97 	 */
98 	burst = div_u64(params->tcfp_burst * params->rate.rate_bytes_ps,
99 			NSEC_PER_SEC);
100 
101 	return burst;
102 }
103 
104 static inline u64 tcf_police_rate_pkt_ps(const struct tc_action *act)
105 {
106 	struct tcf_police *police = to_police(act);
107 	struct tcf_police_params *params;
108 
109 	params = rcu_dereference_protected(police->params,
110 					   lockdep_is_held(&police->tcf_lock));
111 	return params->ppsrate.rate_pkts_ps;
112 }
113 
114 static inline u32 tcf_police_burst_pkt(const struct tc_action *act)
115 {
116 	struct tcf_police *police = to_police(act);
117 	struct tcf_police_params *params;
118 	u32 burst;
119 
120 	params = rcu_dereference_protected(police->params,
121 					   lockdep_is_held(&police->tcf_lock));
122 
123 	/*
124 	 *  "rate" pkts     "burst" nanoseconds
125 	 *  ------------ *  -------------------
126 	 *    1 second          2^6 ticks
127 	 *
128 	 * ------------------------------------
129 	 *        NSEC_PER_SEC nanoseconds
130 	 *        ------------------------
131 	 *              2^6 ticks
132 	 *
133 	 *    "rate" pkts    "burst" nanoseconds            2^6 ticks
134 	 *  = ------------ * ------------------- * ------------------------
135 	 *      1 second          2^6 ticks        NSEC_PER_SEC nanoseconds
136 	 *
137 	 *   "rate" * "burst"
138 	 * = ---------------- pkts/nanosecond
139 	 *    NSEC_PER_SEC^2
140 	 *
141 	 *
142 	 *   "rate" * "burst"
143 	 * = ---------------- pkts/second
144 	 *     NSEC_PER_SEC
145 	 */
146 	burst = div_u64(params->tcfp_pkt_burst * params->ppsrate.rate_pkts_ps,
147 			NSEC_PER_SEC);
148 
149 	return burst;
150 }
151 
152 static inline u32 tcf_police_tcfp_mtu(const struct tc_action *act)
153 {
154 	struct tcf_police *police = to_police(act);
155 	struct tcf_police_params *params;
156 
157 	params = rcu_dereference_protected(police->params,
158 					   lockdep_is_held(&police->tcf_lock));
159 	return params->tcfp_mtu;
160 }
161 
162 #endif /* __NET_TC_POLICE_H */
163