Merge tag 'for-6.3/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device...
[platform/kernel/linux-starfive.git] / include / net / tc_act / tc_police.h
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 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
192 #endif /* __NET_TC_POLICE_H */