diff options
Diffstat (limited to 'net/sched/act_police.c')
-rw-r--r-- | net/sched/act_police.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 38015b493947..5c72a116b1a4 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -182,17 +182,32 @@ override: | |||
182 | R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE]); | 182 | R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE]); |
183 | if (R_tab == NULL) | 183 | if (R_tab == NULL) |
184 | goto failure; | 184 | goto failure; |
185 | |||
186 | if (!est && (ret == ACT_P_CREATED || | ||
187 | !gen_estimator_active(&police->tcf_bstats, | ||
188 | &police->tcf_rate_est))) { | ||
189 | err = -EINVAL; | ||
190 | goto failure; | ||
191 | } | ||
192 | |||
185 | if (parm->peakrate.rate) { | 193 | if (parm->peakrate.rate) { |
186 | P_tab = qdisc_get_rtab(&parm->peakrate, | 194 | P_tab = qdisc_get_rtab(&parm->peakrate, |
187 | tb[TCA_POLICE_PEAKRATE]); | 195 | tb[TCA_POLICE_PEAKRATE]); |
188 | if (P_tab == NULL) { | 196 | if (P_tab == NULL) |
189 | qdisc_put_rtab(R_tab); | ||
190 | goto failure; | 197 | goto failure; |
191 | } | ||
192 | } | 198 | } |
193 | } | 199 | } |
194 | /* No failure allowed after this point */ | 200 | |
195 | spin_lock_bh(&police->tcf_lock); | 201 | spin_lock_bh(&police->tcf_lock); |
202 | if (est) { | ||
203 | err = gen_replace_estimator(&police->tcf_bstats, | ||
204 | &police->tcf_rate_est, | ||
205 | &police->tcf_lock, est); | ||
206 | if (err) | ||
207 | goto failure_unlock; | ||
208 | } | ||
209 | |||
210 | /* No failure allowed after this point */ | ||
196 | if (R_tab != NULL) { | 211 | if (R_tab != NULL) { |
197 | qdisc_put_rtab(police->tcfp_R_tab); | 212 | qdisc_put_rtab(police->tcfp_R_tab); |
198 | police->tcfp_R_tab = R_tab; | 213 | police->tcfp_R_tab = R_tab; |
@@ -217,10 +232,6 @@ override: | |||
217 | 232 | ||
218 | if (tb[TCA_POLICE_AVRATE]) | 233 | if (tb[TCA_POLICE_AVRATE]) |
219 | police->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]); | 234 | police->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]); |
220 | if (est) | ||
221 | gen_replace_estimator(&police->tcf_bstats, | ||
222 | &police->tcf_rate_est, | ||
223 | &police->tcf_lock, est); | ||
224 | 235 | ||
225 | spin_unlock_bh(&police->tcf_lock); | 236 | spin_unlock_bh(&police->tcf_lock); |
226 | if (ret != ACT_P_CREATED) | 237 | if (ret != ACT_P_CREATED) |
@@ -238,7 +249,13 @@ override: | |||
238 | a->priv = police; | 249 | a->priv = police; |
239 | return ret; | 250 | return ret; |
240 | 251 | ||
252 | failure_unlock: | ||
253 | spin_unlock_bh(&police->tcf_lock); | ||
241 | failure: | 254 | failure: |
255 | if (P_tab) | ||
256 | qdisc_put_rtab(P_tab); | ||
257 | if (R_tab) | ||
258 | qdisc_put_rtab(R_tab); | ||
242 | if (ret == ACT_P_CREATED) | 259 | if (ret == ACT_P_CREATED) |
243 | kfree(police); | 260 | kfree(police); |
244 | return err; | 261 | return err; |