udp: ipv4: do not use sk_dst_lock from softirq context
Using sk_dst_lock from softirq context is not supported right now.
Instead of adding BH protection everywhere,
udp_sk_rx_dst_set() can instead use xchg(), as suggested
by David.
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Fixes: 9750223102 ("udp: ipv4: must add synchronization in udp_sk_rx_dst_set()")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
	
	
This commit is contained in:
		
					parent
					
						
							
								50dc875f2e
							
						
					
				
			
			
				commit
				
					
						e47eb5dfb2
					
				
			
		
					 1 changed files with 4 additions and 9 deletions
				
			
		|  | @ -1600,20 +1600,15 @@ static void flush_stack(struct sock **stack, unsigned int count, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* For TCP sockets, sk_rx_dst is protected by socket lock
 | /* For TCP sockets, sk_rx_dst is protected by socket lock
 | ||||||
|  * For UDP, we use sk_dst_lock to guard against concurrent changes. |  * For UDP, we use xchg() to guard against concurrent changes. | ||||||
|  */ |  */ | ||||||
| static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) | static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) | ||||||
| { | { | ||||||
| 	struct dst_entry *old; | 	struct dst_entry *old; | ||||||
| 
 | 
 | ||||||
| 	spin_lock(&sk->sk_dst_lock); |  | ||||||
| 	old = sk->sk_rx_dst; |  | ||||||
| 	if (likely(old != dst)) { |  | ||||||
| 	dst_hold(dst); | 	dst_hold(dst); | ||||||
| 		sk->sk_rx_dst = dst; | 	old = xchg(&sk->sk_rx_dst, dst); | ||||||
| 	dst_release(old); | 	dst_release(old); | ||||||
| 	} |  | ||||||
| 	spin_unlock(&sk->sk_dst_lock); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Eric Dumazet
				Eric Dumazet