aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/act_pedit.c3
-rw-r--r--net/sched/act_police.c36
-rw-r--r--net/sched/sch_fq.c31
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 {
41struct tcf_police { 38struct 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
281inc_overlimits: 289inc_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;