| .. | .. |
|---|
| 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 | |
|---|