diff options
-rw-r--r-- | net/sched/act_police.c | 99 |
1 files changed, 53 insertions, 46 deletions
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 378a6494ba5a..823463adbd21 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -26,20 +26,20 @@ struct tcf_police { | |||
26 | struct tcf_common common; | 26 | struct tcf_common common; |
27 | int tcfp_result; | 27 | int tcfp_result; |
28 | u32 tcfp_ewma_rate; | 28 | u32 tcfp_ewma_rate; |
29 | u32 tcfp_burst; | 29 | s64 tcfp_burst; |
30 | u32 tcfp_mtu; | 30 | u32 tcfp_mtu; |
31 | u32 tcfp_toks; | 31 | s64 tcfp_toks; |
32 | u32 tcfp_ptoks; | 32 | s64 tcfp_ptoks; |
33 | psched_time_t tcfp_t_c; | 33 | s64 tcfp_mtu_ptoks; |
34 | struct qdisc_rate_table *tcfp_R_tab; | 34 | s64 tcfp_t_c; |
35 | struct qdisc_rate_table *tcfp_P_tab; | 35 | struct psched_ratecfg rate; |
36 | bool rate_present; | ||
37 | struct psched_ratecfg peak; | ||
38 | bool peak_present; | ||
36 | }; | 39 | }; |
37 | #define to_police(pc) \ | 40 | #define to_police(pc) \ |
38 | container_of(pc, struct tcf_police, common) | 41 | container_of(pc, struct tcf_police, common) |
39 | 42 | ||
40 | #define L2T(p, L) qdisc_l2t((p)->tcfp_R_tab, L) | ||
41 | #define L2T_P(p, L) qdisc_l2t((p)->tcfp_P_tab, L) | ||
42 | |||
43 | #define POL_TAB_MASK 15 | 43 | #define POL_TAB_MASK 15 |
44 | static struct tcf_common *tcf_police_ht[POL_TAB_MASK + 1]; | 44 | static struct tcf_common *tcf_police_ht[POL_TAB_MASK + 1]; |
45 | static u32 police_idx_gen; | 45 | static u32 police_idx_gen; |
@@ -123,10 +123,6 @@ static void tcf_police_destroy(struct tcf_police *p) | |||
123 | write_unlock_bh(&police_lock); | 123 | write_unlock_bh(&police_lock); |
124 | gen_kill_estimator(&p->tcf_bstats, | 124 | gen_kill_estimator(&p->tcf_bstats, |
125 | &p->tcf_rate_est); | 125 | &p->tcf_rate_est); |
126 | if (p->tcfp_R_tab) | ||
127 | qdisc_put_rtab(p->tcfp_R_tab); | ||
128 | if (p->tcfp_P_tab) | ||
129 | qdisc_put_rtab(p->tcfp_P_tab); | ||
130 | /* | 126 | /* |
131 | * gen_estimator est_timer() might access p->tcf_lock | 127 | * gen_estimator est_timer() might access p->tcf_lock |
132 | * or bstats, wait a RCU grace period before freeing p | 128 | * or bstats, wait a RCU grace period before freeing p |
@@ -227,26 +223,36 @@ override: | |||
227 | } | 223 | } |
228 | 224 | ||
229 | /* No failure allowed after this point */ | 225 | /* No failure allowed after this point */ |
230 | if (R_tab != NULL) { | 226 | police->tcfp_mtu = parm->mtu; |
231 | qdisc_put_rtab(police->tcfp_R_tab); | 227 | if (police->tcfp_mtu == 0) { |
232 | 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; | ||
233 | } | 238 | } |
234 | if (P_tab != NULL) { | 239 | if (P_tab) { |
235 | qdisc_put_rtab(police->tcfp_P_tab); | 240 | police->peak_present = true; |
236 | 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; | ||
237 | } | 245 | } |
238 | 246 | ||
239 | if (tb[TCA_POLICE_RESULT]) | 247 | if (tb[TCA_POLICE_RESULT]) |
240 | police->tcfp_result = nla_get_u32(tb[TCA_POLICE_RESULT]); | 248 | police->tcfp_result = nla_get_u32(tb[TCA_POLICE_RESULT]); |
241 | police->tcfp_toks = police->tcfp_burst = parm->burst; | 249 | police->tcfp_burst = PSCHED_TICKS2NS(parm->burst); |
242 | police->tcfp_mtu = parm->mtu; | 250 | police->tcfp_toks = police->tcfp_burst; |
243 | if (police->tcfp_mtu == 0) { | 251 | if (police->peak_present) { |
244 | police->tcfp_mtu = ~0; | 252 | police->tcfp_mtu_ptoks = (s64) psched_l2t_ns(&police->peak, |
245 | if (police->tcfp_R_tab) | 253 | police->tcfp_mtu); |
246 | police->tcfp_mtu = 255<<police->tcfp_R_tab->rate.cell_log; | 254 | police->tcfp_ptoks = police->tcfp_mtu_ptoks; |
247 | } | 255 | } |
248 | if (police->tcfp_P_tab) | ||
249 | police->tcfp_ptoks = L2T_P(police, police->tcfp_mtu); | ||
250 | police->tcf_action = parm->action; | 256 | police->tcf_action = parm->action; |
251 | 257 | ||
252 | if (tb[TCA_POLICE_AVRATE]) | 258 | if (tb[TCA_POLICE_AVRATE]) |
@@ -256,7 +262,7 @@ override: | |||
256 | if (ret != ACT_P_CREATED) | 262 | if (ret != ACT_P_CREATED) |
257 | return ret; | 263 | return ret; |
258 | 264 | ||
259 | police->tcfp_t_c = psched_get_time(); | 265 | police->tcfp_t_c = ktime_to_ns(ktime_get()); |
260 | police->tcf_index = parm->index ? parm->index : | 266 | police->tcf_index = parm->index ? parm->index : |
261 | tcf_hash_new_index(&police_idx_gen, &police_hash_info); | 267 | tcf_hash_new_index(&police_idx_gen, &police_hash_info); |
262 | h = tcf_hash(police->tcf_index, POL_TAB_MASK); | 268 | h = tcf_hash(police->tcf_index, POL_TAB_MASK); |
@@ -302,9 +308,9 @@ static int tcf_act_police(struct sk_buff *skb, const struct tc_action *a, | |||
302 | struct tcf_result *res) | 308 | struct tcf_result *res) |
303 | { | 309 | { |
304 | struct tcf_police *police = a->priv; | 310 | struct tcf_police *police = a->priv; |
305 | psched_time_t now; | 311 | s64 now; |
306 | long toks; | 312 | s64 toks; |
307 | long ptoks = 0; | 313 | s64 ptoks = 0; |
308 | 314 | ||
309 | spin_lock(&police->tcf_lock); | 315 | spin_lock(&police->tcf_lock); |
310 | 316 | ||
@@ -320,24 +326,25 @@ static int tcf_act_police(struct sk_buff *skb, const struct tc_action *a, | |||
320 | } | 326 | } |
321 | 327 | ||
322 | if (qdisc_pkt_len(skb) <= police->tcfp_mtu) { | 328 | if (qdisc_pkt_len(skb) <= police->tcfp_mtu) { |
323 | if (police->tcfp_R_tab == NULL) { | 329 | if (!police->rate_present) { |
324 | spin_unlock(&police->tcf_lock); | 330 | spin_unlock(&police->tcf_lock); |
325 | return police->tcfp_result; | 331 | return police->tcfp_result; |
326 | } | 332 | } |
327 | 333 | ||
328 | now = psched_get_time(); | 334 | now = ktime_to_ns(ktime_get()); |
329 | toks = psched_tdiff_bounded(now, police->tcfp_t_c, | 335 | toks = min_t(s64, now - police->tcfp_t_c, |
330 | police->tcfp_burst); | 336 | police->tcfp_burst); |
331 | if (police->tcfp_P_tab) { | 337 | if (police->peak_present) { |
332 | ptoks = toks + police->tcfp_ptoks; | 338 | ptoks = toks + police->tcfp_ptoks; |
333 | if (ptoks > (long)L2T_P(police, police->tcfp_mtu)) | 339 | if (ptoks > police->tcfp_mtu_ptoks) |
334 | ptoks = (long)L2T_P(police, police->tcfp_mtu); | 340 | ptoks = police->tcfp_mtu_ptoks; |
335 | ptoks -= L2T_P(police, qdisc_pkt_len(skb)); | 341 | ptoks -= (s64) psched_l2t_ns(&police->peak, |
342 | qdisc_pkt_len(skb)); | ||
336 | } | 343 | } |
337 | toks += police->tcfp_toks; | 344 | toks += police->tcfp_toks; |
338 | if (toks > (long)police->tcfp_burst) | 345 | if (toks > police->tcfp_burst) |
339 | toks = police->tcfp_burst; | 346 | toks = police->tcfp_burst; |
340 | toks -= L2T(police, qdisc_pkt_len(skb)); | 347 | toks -= (s64) psched_l2t_ns(&police->rate, qdisc_pkt_len(skb)); |
341 | if ((toks|ptoks) >= 0) { | 348 | if ((toks|ptoks) >= 0) { |
342 | police->tcfp_t_c = now; | 349 | police->tcfp_t_c = now; |
343 | police->tcfp_toks = toks; | 350 | police->tcfp_toks = toks; |
@@ -363,15 +370,15 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
363 | .index = police->tcf_index, | 370 | .index = police->tcf_index, |
364 | .action = police->tcf_action, | 371 | .action = police->tcf_action, |
365 | .mtu = police->tcfp_mtu, | 372 | .mtu = police->tcfp_mtu, |
366 | .burst = police->tcfp_burst, | 373 | .burst = PSCHED_NS2TICKS(police->tcfp_burst), |
367 | .refcnt = police->tcf_refcnt - ref, | 374 | .refcnt = police->tcf_refcnt - ref, |
368 | .bindcnt = police->tcf_bindcnt - bind, | 375 | .bindcnt = police->tcf_bindcnt - bind, |
369 | }; | 376 | }; |
370 | 377 | ||
371 | if (police->tcfp_R_tab) | 378 | if (police->rate_present) |
372 | opt.rate = police->tcfp_R_tab->rate; | 379 | opt.rate.rate = psched_ratecfg_getrate(&police->rate); |
373 | if (police->tcfp_P_tab) | 380 | if (police->peak_present) |
374 | opt.peakrate = police->tcfp_P_tab->rate; | 381 | opt.peakrate.rate = psched_ratecfg_getrate(&police->peak); |
375 | if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt)) | 382 | if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt)) |
376 | goto nla_put_failure; | 383 | goto nla_put_failure; |
377 | if (police->tcfp_result && | 384 | if (police->tcfp_result && |