forked from mirrors/linux
		
	pkt_sched: fq: fix non TCP flows pacing
Steinar reported FQ pacing was not working for UDP flows. It looks like the initial sk->sk_pacing_rate value of 0 was a wrong choice. We should init it to ~0U (unlimited) Then, TCA_FQ_FLOW_DEFAULT_RATE should be removed because it makes no real sense. The default rate is really unlimited, and we need to avoid a zero divide. Reported-by: Steinar H. Gunderson <sesse@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									2b1f18a4d6
								
							
						
					
					
						commit
						7eec4174ff
					
				
					 2 changed files with 10 additions and 11 deletions
				
			
		| 
						 | 
					@ -2319,6 +2319,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
 | 
				
			||||||
	sk->sk_ll_usec		=	sysctl_net_busy_read;
 | 
						sk->sk_ll_usec		=	sysctl_net_busy_read;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sk->sk_pacing_rate = ~0U;
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Before updating sk_refcnt, we must commit prior changes to memory
 | 
						 * Before updating sk_refcnt, we must commit prior changes to memory
 | 
				
			||||||
	 * (Documentation/RCU/rculist_nulls.txt for details)
 | 
						 * (Documentation/RCU/rculist_nulls.txt for details)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -472,19 +472,15 @@ static struct sk_buff *fq_dequeue(struct Qdisc *sch)
 | 
				
			||||||
	if (f->credit > 0 || !q->rate_enable)
 | 
						if (f->credit > 0 || !q->rate_enable)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (skb->sk && skb->sk->sk_state != TCP_TIME_WAIT) {
 | 
					 | 
				
			||||||
		rate = skb->sk->sk_pacing_rate ?: q->flow_default_rate;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		rate = min(rate, q->flow_max_rate);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
	rate = q->flow_max_rate;
 | 
						rate = q->flow_max_rate;
 | 
				
			||||||
		if (rate == ~0U)
 | 
						if (skb->sk && skb->sk->sk_state != TCP_TIME_WAIT)
 | 
				
			||||||
			goto out;
 | 
							rate = min(skb->sk->sk_pacing_rate, rate);
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
	if (rate) {
 | 
						if (rate != ~0U) {
 | 
				
			||||||
		u32 plen = max(qdisc_pkt_len(skb), q->quantum);
 | 
							u32 plen = max(qdisc_pkt_len(skb), q->quantum);
 | 
				
			||||||
		u64 len = (u64)plen * NSEC_PER_SEC;
 | 
							u64 len = (u64)plen * NSEC_PER_SEC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (likely(rate))
 | 
				
			||||||
			do_div(len, rate);
 | 
								do_div(len, rate);
 | 
				
			||||||
		/* Since socket rate can change later,
 | 
							/* Since socket rate can change later,
 | 
				
			||||||
		 * clamp the delay to 125 ms.
 | 
							 * clamp the delay to 125 ms.
 | 
				
			||||||
| 
						 | 
					@ -735,12 +731,14 @@ static int fq_dump(struct Qdisc *sch, struct sk_buff *skb)
 | 
				
			||||||
	if (opts == NULL)
 | 
						if (opts == NULL)
 | 
				
			||||||
		goto nla_put_failure;
 | 
							goto nla_put_failure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TCA_FQ_FLOW_DEFAULT_RATE is not used anymore,
 | 
				
			||||||
 | 
						 * do not bother giving its value
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	if (nla_put_u32(skb, TCA_FQ_PLIMIT, sch->limit) ||
 | 
						if (nla_put_u32(skb, TCA_FQ_PLIMIT, sch->limit) ||
 | 
				
			||||||
	    nla_put_u32(skb, TCA_FQ_FLOW_PLIMIT, q->flow_plimit) ||
 | 
						    nla_put_u32(skb, TCA_FQ_FLOW_PLIMIT, q->flow_plimit) ||
 | 
				
			||||||
	    nla_put_u32(skb, TCA_FQ_QUANTUM, q->quantum) ||
 | 
						    nla_put_u32(skb, TCA_FQ_QUANTUM, q->quantum) ||
 | 
				
			||||||
	    nla_put_u32(skb, TCA_FQ_INITIAL_QUANTUM, q->initial_quantum) ||
 | 
						    nla_put_u32(skb, TCA_FQ_INITIAL_QUANTUM, q->initial_quantum) ||
 | 
				
			||||||
	    nla_put_u32(skb, TCA_FQ_RATE_ENABLE, q->rate_enable) ||
 | 
						    nla_put_u32(skb, TCA_FQ_RATE_ENABLE, q->rate_enable) ||
 | 
				
			||||||
	    nla_put_u32(skb, TCA_FQ_FLOW_DEFAULT_RATE, q->flow_default_rate) ||
 | 
					 | 
				
			||||||
	    nla_put_u32(skb, TCA_FQ_FLOW_MAX_RATE, q->flow_max_rate) ||
 | 
						    nla_put_u32(skb, TCA_FQ_FLOW_MAX_RATE, q->flow_max_rate) ||
 | 
				
			||||||
	    nla_put_u32(skb, TCA_FQ_BUCKETS_LOG, q->fq_trees_log))
 | 
						    nla_put_u32(skb, TCA_FQ_BUCKETS_LOG, q->fq_trees_log))
 | 
				
			||||||
		goto nla_put_failure;
 | 
							goto nla_put_failure;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue