.. | .. |
---|
61 | 61 | struct pie_params p_params; |
---|
62 | 62 | u32 ecn_prob; |
---|
63 | 63 | u32 flows_cnt; |
---|
| 64 | + u32 flows_cursor; |
---|
64 | 65 | u32 quantum; |
---|
65 | 66 | u32 memory_limit; |
---|
66 | 67 | u32 new_flow_count; |
---|
.. | .. |
---|
201 | 202 | return NET_XMIT_CN; |
---|
202 | 203 | } |
---|
203 | 204 | |
---|
| 205 | +static struct netlink_range_validation fq_pie_q_range = { |
---|
| 206 | + .min = 1, |
---|
| 207 | + .max = 1 << 20, |
---|
| 208 | +}; |
---|
| 209 | + |
---|
204 | 210 | static const struct nla_policy fq_pie_policy[TCA_FQ_PIE_MAX + 1] = { |
---|
205 | 211 | [TCA_FQ_PIE_LIMIT] = {.type = NLA_U32}, |
---|
206 | 212 | [TCA_FQ_PIE_FLOWS] = {.type = NLA_U32}, |
---|
.. | .. |
---|
208 | 214 | [TCA_FQ_PIE_TUPDATE] = {.type = NLA_U32}, |
---|
209 | 215 | [TCA_FQ_PIE_ALPHA] = {.type = NLA_U32}, |
---|
210 | 216 | [TCA_FQ_PIE_BETA] = {.type = NLA_U32}, |
---|
211 | | - [TCA_FQ_PIE_QUANTUM] = {.type = NLA_U32}, |
---|
| 217 | + [TCA_FQ_PIE_QUANTUM] = |
---|
| 218 | + NLA_POLICY_FULL_RANGE(NLA_U32, &fq_pie_q_range), |
---|
212 | 219 | [TCA_FQ_PIE_MEMORY_LIMIT] = {.type = NLA_U32}, |
---|
213 | 220 | [TCA_FQ_PIE_ECN_PROB] = {.type = NLA_U32}, |
---|
214 | 221 | [TCA_FQ_PIE_ECN] = {.type = NLA_U32}, |
---|
.. | .. |
---|
372 | 379 | static void fq_pie_timer(struct timer_list *t) |
---|
373 | 380 | { |
---|
374 | 381 | struct fq_pie_sched_data *q = from_timer(q, t, adapt_timer); |
---|
| 382 | + unsigned long next, tupdate; |
---|
375 | 383 | struct Qdisc *sch = q->sch; |
---|
376 | 384 | spinlock_t *root_lock; /* to lock qdisc for probability calculations */ |
---|
377 | | - u32 idx; |
---|
| 385 | + int max_cnt, i; |
---|
378 | 386 | |
---|
379 | 387 | root_lock = qdisc_lock(qdisc_root_sleeping(sch)); |
---|
380 | 388 | spin_lock(root_lock); |
---|
381 | 389 | |
---|
382 | | - for (idx = 0; idx < q->flows_cnt; idx++) |
---|
383 | | - pie_calculate_probability(&q->p_params, &q->flows[idx].vars, |
---|
384 | | - q->flows[idx].backlog); |
---|
| 390 | + /* Limit this expensive loop to 2048 flows per round. */ |
---|
| 391 | + max_cnt = min_t(int, q->flows_cnt - q->flows_cursor, 2048); |
---|
| 392 | + for (i = 0; i < max_cnt; i++) { |
---|
| 393 | + pie_calculate_probability(&q->p_params, |
---|
| 394 | + &q->flows[q->flows_cursor].vars, |
---|
| 395 | + q->flows[q->flows_cursor].backlog); |
---|
| 396 | + q->flows_cursor++; |
---|
| 397 | + } |
---|
385 | 398 | |
---|
386 | | - /* reset the timer to fire after 'tupdate' jiffies. */ |
---|
387 | | - if (q->p_params.tupdate) |
---|
388 | | - mod_timer(&q->adapt_timer, jiffies + q->p_params.tupdate); |
---|
389 | | - |
---|
| 399 | + tupdate = q->p_params.tupdate; |
---|
| 400 | + next = 0; |
---|
| 401 | + if (q->flows_cursor >= q->flows_cnt) { |
---|
| 402 | + q->flows_cursor = 0; |
---|
| 403 | + next = tupdate; |
---|
| 404 | + } |
---|
| 405 | + if (tupdate) |
---|
| 406 | + mod_timer(&q->adapt_timer, jiffies + next); |
---|
390 | 407 | spin_unlock(root_lock); |
---|
391 | 408 | } |
---|
392 | 409 | |
---|