diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/act_pedit.c | 3 | ||||
-rw-r--r-- | net/sched/act_police.c | 36 | ||||
-rw-r--r-- | net/sched/sch_fq.c | 31 |
3 files changed, 43 insertions, 27 deletions
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index da3dd0f68cc2..2b372a06b432 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
@@ -201,7 +201,8 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, | |||
201 | goto out_release; | 201 | goto out_release; |
202 | } | 202 | } |
203 | } else { | 203 | } else { |
204 | return err; | 204 | ret = err; |
205 | goto out_free; | ||
205 | } | 206 | } |
206 | 207 | ||
207 | p = to_pedit(*a); | 208 | p = to_pedit(*a); |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 052855d47354..37c9b8f0e10f 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -27,10 +27,7 @@ struct tcf_police_params { | |||
27 | u32 tcfp_ewma_rate; | 27 | u32 tcfp_ewma_rate; |
28 | s64 tcfp_burst; | 28 | s64 tcfp_burst; |
29 | u32 tcfp_mtu; | 29 | u32 tcfp_mtu; |
30 | s64 tcfp_toks; | ||
31 | s64 tcfp_ptoks; | ||
32 | s64 tcfp_mtu_ptoks; | 30 | s64 tcfp_mtu_ptoks; |
33 | s64 tcfp_t_c; | ||
34 | struct psched_ratecfg rate; | 31 | struct psched_ratecfg rate; |
35 | bool rate_present; | 32 | bool rate_present; |
36 | struct psched_ratecfg peak; | 33 | struct psched_ratecfg peak; |
@@ -41,6 +38,11 @@ struct tcf_police_params { | |||
41 | struct tcf_police { | 38 | struct tcf_police { |
42 | struct tc_action common; | 39 | struct tc_action common; |
43 | struct tcf_police_params __rcu *params; | 40 | struct tcf_police_params __rcu *params; |
41 | |||
42 | spinlock_t tcfp_lock ____cacheline_aligned_in_smp; | ||
43 | s64 tcfp_toks; | ||
44 | s64 tcfp_ptoks; | ||
45 | s64 tcfp_t_c; | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | #define to_police(pc) ((struct tcf_police *)pc) | 48 | #define to_police(pc) ((struct tcf_police *)pc) |
@@ -122,6 +124,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, | |||
122 | return ret; | 124 | return ret; |
123 | } | 125 | } |
124 | ret = ACT_P_CREATED; | 126 | ret = ACT_P_CREATED; |
127 | spin_lock_init(&(to_police(*a)->tcfp_lock)); | ||
125 | } else if (!ovr) { | 128 | } else if (!ovr) { |
126 | tcf_idr_release(*a, bind); | 129 | tcf_idr_release(*a, bind); |
127 | return -EEXIST; | 130 | return -EEXIST; |
@@ -186,12 +189,9 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, | |||
186 | } | 189 | } |
187 | 190 | ||
188 | new->tcfp_burst = PSCHED_TICKS2NS(parm->burst); | 191 | new->tcfp_burst = PSCHED_TICKS2NS(parm->burst); |
189 | new->tcfp_toks = new->tcfp_burst; | 192 | if (new->peak_present) |
190 | if (new->peak_present) { | ||
191 | new->tcfp_mtu_ptoks = (s64)psched_l2t_ns(&new->peak, | 193 | new->tcfp_mtu_ptoks = (s64)psched_l2t_ns(&new->peak, |
192 | new->tcfp_mtu); | 194 | new->tcfp_mtu); |
193 | new->tcfp_ptoks = new->tcfp_mtu_ptoks; | ||
194 | } | ||
195 | 195 | ||
196 | if (tb[TCA_POLICE_AVRATE]) | 196 | if (tb[TCA_POLICE_AVRATE]) |
197 | new->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]); | 197 | new->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]); |
@@ -207,7 +207,12 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, | |||
207 | } | 207 | } |
208 | 208 | ||
209 | spin_lock_bh(&police->tcf_lock); | 209 | spin_lock_bh(&police->tcf_lock); |
210 | new->tcfp_t_c = ktime_get_ns(); | 210 | spin_lock_bh(&police->tcfp_lock); |
211 | police->tcfp_t_c = ktime_get_ns(); | ||
212 | police->tcfp_toks = new->tcfp_burst; | ||
213 | if (new->peak_present) | ||
214 | police->tcfp_ptoks = new->tcfp_mtu_ptoks; | ||
215 | spin_unlock_bh(&police->tcfp_lock); | ||
211 | police->tcf_action = parm->action; | 216 | police->tcf_action = parm->action; |
212 | rcu_swap_protected(police->params, | 217 | rcu_swap_protected(police->params, |
213 | new, | 218 | new, |
@@ -257,25 +262,28 @@ static int tcf_police_act(struct sk_buff *skb, const struct tc_action *a, | |||
257 | } | 262 | } |
258 | 263 | ||
259 | now = ktime_get_ns(); | 264 | now = ktime_get_ns(); |
260 | toks = min_t(s64, now - p->tcfp_t_c, p->tcfp_burst); | 265 | spin_lock_bh(&police->tcfp_lock); |
266 | toks = min_t(s64, now - police->tcfp_t_c, p->tcfp_burst); | ||
261 | if (p->peak_present) { | 267 | if (p->peak_present) { |
262 | ptoks = toks + p->tcfp_ptoks; | 268 | ptoks = toks + police->tcfp_ptoks; |
263 | if (ptoks > p->tcfp_mtu_ptoks) | 269 | if (ptoks > p->tcfp_mtu_ptoks) |
264 | ptoks = p->tcfp_mtu_ptoks; | 270 | ptoks = p->tcfp_mtu_ptoks; |
265 | ptoks -= (s64)psched_l2t_ns(&p->peak, | 271 | ptoks -= (s64)psched_l2t_ns(&p->peak, |
266 | qdisc_pkt_len(skb)); | 272 | qdisc_pkt_len(skb)); |
267 | } | 273 | } |
268 | toks += p->tcfp_toks; | 274 | toks += police->tcfp_toks; |
269 | if (toks > p->tcfp_burst) | 275 | if (toks > p->tcfp_burst) |
270 | toks = p->tcfp_burst; | 276 | toks = p->tcfp_burst; |
271 | toks -= (s64)psched_l2t_ns(&p->rate, qdisc_pkt_len(skb)); | 277 | toks -= (s64)psched_l2t_ns(&p->rate, qdisc_pkt_len(skb)); |
272 | if ((toks|ptoks) >= 0) { | 278 | if ((toks|ptoks) >= 0) { |
273 | p->tcfp_t_c = now; | 279 | police->tcfp_t_c = now; |
274 | p->tcfp_toks = toks; | 280 | police->tcfp_toks = toks; |
275 | p->tcfp_ptoks = ptoks; | 281 | police->tcfp_ptoks = ptoks; |
282 | spin_unlock_bh(&police->tcfp_lock); | ||
276 | ret = p->tcfp_result; | 283 | ret = p->tcfp_result; |
277 | goto inc_drops; | 284 | goto inc_drops; |
278 | } | 285 | } |
286 | spin_unlock_bh(&police->tcfp_lock); | ||
279 | } | 287 | } |
280 | 288 | ||
281 | inc_overlimits: | 289 | inc_overlimits: |
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index 4b1af706896c..25a7cf6d380f 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c | |||
@@ -469,22 +469,29 @@ begin: | |||
469 | goto begin; | 469 | goto begin; |
470 | } | 470 | } |
471 | prefetch(&skb->end); | 471 | prefetch(&skb->end); |
472 | f->credit -= qdisc_pkt_len(skb); | 472 | plen = qdisc_pkt_len(skb); |
473 | f->credit -= plen; | ||
473 | 474 | ||
474 | if (ktime_to_ns(skb->tstamp) || !q->rate_enable) | 475 | if (!q->rate_enable) |
475 | goto out; | 476 | goto out; |
476 | 477 | ||
477 | rate = q->flow_max_rate; | 478 | rate = q->flow_max_rate; |
478 | if (skb->sk) | 479 | |
479 | rate = min(skb->sk->sk_pacing_rate, rate); | 480 | /* If EDT time was provided for this skb, we need to |
480 | 481 | * update f->time_next_packet only if this qdisc enforces | |
481 | if (rate <= q->low_rate_threshold) { | 482 | * a flow max rate. |
482 | f->credit = 0; | 483 | */ |
483 | plen = qdisc_pkt_len(skb); | 484 | if (!skb->tstamp) { |
484 | } else { | 485 | if (skb->sk) |
485 | plen = max(qdisc_pkt_len(skb), q->quantum); | 486 | rate = min(skb->sk->sk_pacing_rate, rate); |
486 | if (f->credit > 0) | 487 | |
487 | goto out; | 488 | if (rate <= q->low_rate_threshold) { |
489 | f->credit = 0; | ||
490 | } else { | ||
491 | plen = max(plen, q->quantum); | ||
492 | if (f->credit > 0) | ||
493 | goto out; | ||
494 | } | ||
488 | } | 495 | } |
489 | if (rate != ~0UL) { | 496 | if (rate != ~0UL) { |
490 | u64 len = (u64)plen * NSEC_PER_SEC; | 497 | u64 len = (u64)plen * NSEC_PER_SEC; |