aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/act_police.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/act_police.c')
-rw-r--r--net/sched/act_police.c105
1 files changed, 64 insertions, 41 deletions
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index a9de23297d47..823463adbd21 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -22,8 +22,23 @@
22#include <net/act_api.h> 22#include <net/act_api.h>
23#include <net/netlink.h> 23#include <net/netlink.h>
24 24
25#define L2T(p, L) qdisc_l2t((p)->tcfp_R_tab, L) 25struct tcf_police {
26#define L2T_P(p, L) qdisc_l2t((p)->tcfp_P_tab, L) 26 struct tcf_common common;
27 int tcfp_result;
28 u32 tcfp_ewma_rate;
29 s64 tcfp_burst;
30 u32 tcfp_mtu;
31 s64 tcfp_toks;
32 s64 tcfp_ptoks;
33 s64 tcfp_mtu_ptoks;
34 s64 tcfp_t_c;
35 struct psched_ratecfg rate;
36 bool rate_present;
37 struct psched_ratecfg peak;
38 bool peak_present;
39};
40#define to_police(pc) \
41 container_of(pc, struct tcf_police, common)
27 42
28#define POL_TAB_MASK 15 43#define POL_TAB_MASK 15
29static struct tcf_common *tcf_police_ht[POL_TAB_MASK + 1]; 44static struct tcf_common *tcf_police_ht[POL_TAB_MASK + 1];
@@ -108,10 +123,6 @@ static void tcf_police_destroy(struct tcf_police *p)
108 write_unlock_bh(&police_lock); 123 write_unlock_bh(&police_lock);
109 gen_kill_estimator(&p->tcf_bstats, 124 gen_kill_estimator(&p->tcf_bstats,
110 &p->tcf_rate_est); 125 &p->tcf_rate_est);
111 if (p->tcfp_R_tab)
112 qdisc_put_rtab(p->tcfp_R_tab);
113 if (p->tcfp_P_tab)
114 qdisc_put_rtab(p->tcfp_P_tab);
115 /* 126 /*
116 * gen_estimator est_timer() might access p->tcf_lock 127 * gen_estimator est_timer() might access p->tcf_lock
117 * or bstats, wait a RCU grace period before freeing p 128 * or bstats, wait a RCU grace period before freeing p
@@ -130,8 +141,9 @@ static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {
130 [TCA_POLICE_RESULT] = { .type = NLA_U32 }, 141 [TCA_POLICE_RESULT] = { .type = NLA_U32 },
131}; 142};
132 143
133static int tcf_act_police_locate(struct nlattr *nla, struct nlattr *est, 144static int tcf_act_police_locate(struct net *net, struct nlattr *nla,
134 struct tc_action *a, int ovr, int bind) 145 struct nlattr *est, struct tc_action *a,
146 int ovr, int bind)
135{ 147{
136 unsigned int h; 148 unsigned int h;
137 int ret = 0, err; 149 int ret = 0, err;
@@ -211,26 +223,36 @@ override:
211 } 223 }
212 224
213 /* No failure allowed after this point */ 225 /* No failure allowed after this point */
214 if (R_tab != NULL) { 226 police->tcfp_mtu = parm->mtu;
215 qdisc_put_rtab(police->tcfp_R_tab); 227 if (police->tcfp_mtu == 0) {
216 police->tcfp_R_tab = R_tab; 228 police->tcfp_mtu = ~0;
229 if (R_tab)
230 police->tcfp_mtu = 255 << R_tab->rate.cell_log;
231 }
232 if (R_tab) {
233 police->rate_present = true;
234 psched_ratecfg_precompute(&police->rate, R_tab->rate.rate);
235 qdisc_put_rtab(R_tab);
236 } else {
237 police->rate_present = false;
217 } 238 }
218 if (P_tab != NULL) { 239 if (P_tab) {
219 qdisc_put_rtab(police->tcfp_P_tab); 240 police->peak_present = true;
220 police->tcfp_P_tab = P_tab; 241 psched_ratecfg_precompute(&police->peak, P_tab->rate.rate);
242 qdisc_put_rtab(P_tab);
243 } else {
244 police->peak_present = false;
221 } 245 }
222 246
223 if (tb[TCA_POLICE_RESULT]) 247 if (tb[TCA_POLICE_RESULT])
224 police->tcfp_result = nla_get_u32(tb[TCA_POLICE_RESULT]); 248 police->tcfp_result = nla_get_u32(tb[TCA_POLICE_RESULT]);
225 police->tcfp_toks = police->tcfp_burst = parm->burst; 249 police->tcfp_burst = PSCHED_TICKS2NS(parm->burst);
226 police->tcfp_mtu = parm->mtu; 250 police->tcfp_toks = police->tcfp_burst;
227 if (police->tcfp_mtu == 0) { 251 if (police->peak_present) {
228 police->tcfp_mtu = ~0; 252 police->tcfp_mtu_ptoks = (s64) psched_l2t_ns(&police->peak,
229 if (police->tcfp_R_tab) 253 police->tcfp_mtu);
230 police->tcfp_mtu = 255<<police->tcfp_R_tab->rate.cell_log; 254 police->tcfp_ptoks = police->tcfp_mtu_ptoks;
231 } 255 }
232 if (police->tcfp_P_tab)
233 police->tcfp_ptoks = L2T_P(police, police->tcfp_mtu);
234 police->tcf_action = parm->action; 256 police->tcf_action = parm->action;
235 257
236 if (tb[TCA_POLICE_AVRATE]) 258 if (tb[TCA_POLICE_AVRATE])
@@ -240,7 +262,7 @@ override:
240 if (ret != ACT_P_CREATED) 262 if (ret != ACT_P_CREATED)
241 return ret; 263 return ret;
242 264
243 police->tcfp_t_c = psched_get_time(); 265 police->tcfp_t_c = ktime_to_ns(ktime_get());
244 police->tcf_index = parm->index ? parm->index : 266 police->tcf_index = parm->index ? parm->index :
245 tcf_hash_new_index(&police_idx_gen, &police_hash_info); 267 tcf_hash_new_index(&police_idx_gen, &police_hash_info);
246 h = tcf_hash(police->tcf_index, POL_TAB_MASK); 268 h = tcf_hash(police->tcf_index, POL_TAB_MASK);
@@ -286,9 +308,9 @@ static int tcf_act_police(struct sk_buff *skb, const struct tc_action *a,
286 struct tcf_result *res) 308 struct tcf_result *res)
287{ 309{
288 struct tcf_police *police = a->priv; 310 struct tcf_police *police = a->priv;
289 psched_time_t now; 311 s64 now;
290 long toks; 312 s64 toks;
291 long ptoks = 0; 313 s64 ptoks = 0;
292 314
293 spin_lock(&police->tcf_lock); 315 spin_lock(&police->tcf_lock);
294 316
@@ -304,24 +326,25 @@ static int tcf_act_police(struct sk_buff *skb, const struct tc_action *a,
304 } 326 }
305 327
306 if (qdisc_pkt_len(skb) <= police->tcfp_mtu) { 328 if (qdisc_pkt_len(skb) <= police->tcfp_mtu) {
307 if (police->tcfp_R_tab == NULL) { 329 if (!police->rate_present) {
308 spin_unlock(&police->tcf_lock); 330 spin_unlock(&police->tcf_lock);
309 return police->tcfp_result; 331 return police->tcfp_result;
310 } 332 }
311 333
312 now = psched_get_time(); 334 now = ktime_to_ns(ktime_get());
313 toks = psched_tdiff_bounded(now, police->tcfp_t_c, 335 toks = min_t(s64, now - police->tcfp_t_c,
314 police->tcfp_burst); 336 police->tcfp_burst);
315 if (police->tcfp_P_tab) { 337 if (police->peak_present) {
316 ptoks = toks + police->tcfp_ptoks; 338 ptoks = toks + police->tcfp_ptoks;
317 if (ptoks > (long)L2T_P(police, police->tcfp_mtu)) 339 if (ptoks > police->tcfp_mtu_ptoks)
318 ptoks = (long)L2T_P(police, police->tcfp_mtu); 340 ptoks = police->tcfp_mtu_ptoks;
319 ptoks -= L2T_P(police, qdisc_pkt_len(skb)); 341 ptoks -= (s64) psched_l2t_ns(&police->peak,
342 qdisc_pkt_len(skb));
320 } 343 }
321 toks += police->tcfp_toks; 344 toks += police->tcfp_toks;
322 if (toks > (long)police->tcfp_burst) 345 if (toks > police->tcfp_burst)
323 toks = police->tcfp_burst; 346 toks = police->tcfp_burst;
324 toks -= L2T(police, qdisc_pkt_len(skb)); 347 toks -= (s64) psched_l2t_ns(&police->rate, qdisc_pkt_len(skb));
325 if ((toks|ptoks) >= 0) { 348 if ((toks|ptoks) >= 0) {
326 police->tcfp_t_c = now; 349 police->tcfp_t_c = now;
327 police->tcfp_toks = toks; 350 police->tcfp_toks = toks;
@@ -347,15 +370,15 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
347 .index = police->tcf_index, 370 .index = police->tcf_index,
348 .action = police->tcf_action, 371 .action = police->tcf_action,
349 .mtu = police->tcfp_mtu, 372 .mtu = police->tcfp_mtu,
350 .burst = police->tcfp_burst, 373 .burst = PSCHED_NS2TICKS(police->tcfp_burst),
351 .refcnt = police->tcf_refcnt - ref, 374 .refcnt = police->tcf_refcnt - ref,
352 .bindcnt = police->tcf_bindcnt - bind, 375 .bindcnt = police->tcf_bindcnt - bind,
353 }; 376 };
354 377
355 if (police->tcfp_R_tab) 378 if (police->rate_present)
356 opt.rate = police->tcfp_R_tab->rate; 379 opt.rate.rate = psched_ratecfg_getrate(&police->rate);
357 if (police->tcfp_P_tab) 380 if (police->peak_present)
358 opt.peakrate = police->tcfp_P_tab->rate; 381 opt.peakrate.rate = psched_ratecfg_getrate(&police->peak);
359 if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt)) 382 if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt))
360 goto nla_put_failure; 383 goto nla_put_failure;
361 if (police->tcfp_result && 384 if (police->tcfp_result &&