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.c36
1 files changed, 22 insertions, 14 deletions
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: