mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	net/ipv4: Use nested-BH locking for ipv4_tcp_sk.
ipv4_tcp_sk is a per-CPU variable and relies on disabled BH for its locking. Without per-CPU locking in local_bh_disable() on PREEMPT_RT this data structure requires explicit locking. Make a struct with a sock member (original ipv4_tcp_sk) and a local_lock_t and use local_lock_nested_bh() for locking. This change adds only lockdep coverage and does not alter the functional behaviour for !PREEMPT_RT. Cc: David Ahern <dsahern@kernel.org> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Link: https://patch.msgid.link/20240620132727.660738-7-bigeasy@linutronix.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
		
							parent
							
								
									585aa621af
								
							
						
					
					
						commit
						ebad6d0334
					
				
					 2 changed files with 16 additions and 4 deletions
				
			
		|  | @ -544,6 +544,11 @@ struct sock { | |||
| 	netns_tracker		ns_tracker; | ||||
| }; | ||||
| 
 | ||||
| struct sock_bh_locked { | ||||
| 	struct sock *sock; | ||||
| 	local_lock_t bh_lock; | ||||
| }; | ||||
| 
 | ||||
| enum sk_pacing { | ||||
| 	SK_PACING_NONE		= 0, | ||||
| 	SK_PACING_NEEDED	= 1, | ||||
|  |  | |||
|  | @ -93,7 +93,9 @@ static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key, | |||
| struct inet_hashinfo tcp_hashinfo; | ||||
| EXPORT_SYMBOL(tcp_hashinfo); | ||||
| 
 | ||||
| static DEFINE_PER_CPU(struct sock *, ipv4_tcp_sk); | ||||
| static DEFINE_PER_CPU(struct sock_bh_locked, ipv4_tcp_sk) = { | ||||
| 	.bh_lock = INIT_LOCAL_LOCK(bh_lock), | ||||
| }; | ||||
| 
 | ||||
| static u32 tcp_v4_init_seq(const struct sk_buff *skb) | ||||
| { | ||||
|  | @ -882,7 +884,9 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb, | |||
| 	arg.tos = ip_hdr(skb)->tos; | ||||
| 	arg.uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL); | ||||
| 	local_bh_disable(); | ||||
| 	ctl_sk = this_cpu_read(ipv4_tcp_sk); | ||||
| 	local_lock_nested_bh(&ipv4_tcp_sk.bh_lock); | ||||
| 	ctl_sk = this_cpu_read(ipv4_tcp_sk.sock); | ||||
| 
 | ||||
| 	sock_net_set(ctl_sk, net); | ||||
| 	if (sk) { | ||||
| 		ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ? | ||||
|  | @ -907,6 +911,7 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb, | |||
| 	sock_net_set(ctl_sk, &init_net); | ||||
| 	__TCP_INC_STATS(net, TCP_MIB_OUTSEGS); | ||||
| 	__TCP_INC_STATS(net, TCP_MIB_OUTRSTS); | ||||
| 	local_unlock_nested_bh(&ipv4_tcp_sk.bh_lock); | ||||
| 	local_bh_enable(); | ||||
| 
 | ||||
| #ifdef CONFIG_TCP_MD5SIG | ||||
|  | @ -1002,7 +1007,8 @@ static void tcp_v4_send_ack(const struct sock *sk, | |||
| 	arg.tos = tos; | ||||
| 	arg.uid = sock_net_uid(net, sk_fullsock(sk) ? sk : NULL); | ||||
| 	local_bh_disable(); | ||||
| 	ctl_sk = this_cpu_read(ipv4_tcp_sk); | ||||
| 	local_lock_nested_bh(&ipv4_tcp_sk.bh_lock); | ||||
| 	ctl_sk = this_cpu_read(ipv4_tcp_sk.sock); | ||||
| 	sock_net_set(ctl_sk, net); | ||||
| 	ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ? | ||||
| 			   inet_twsk(sk)->tw_mark : READ_ONCE(sk->sk_mark); | ||||
|  | @ -1017,6 +1023,7 @@ static void tcp_v4_send_ack(const struct sock *sk, | |||
| 
 | ||||
| 	sock_net_set(ctl_sk, &init_net); | ||||
| 	__TCP_INC_STATS(net, TCP_MIB_OUTSEGS); | ||||
| 	local_unlock_nested_bh(&ipv4_tcp_sk.bh_lock); | ||||
| 	local_bh_enable(); | ||||
| } | ||||
| 
 | ||||
|  | @ -3615,7 +3622,7 @@ void __init tcp_v4_init(void) | |||
| 
 | ||||
| 		sk->sk_clockid = CLOCK_MONOTONIC; | ||||
| 
 | ||||
| 		per_cpu(ipv4_tcp_sk, cpu) = sk; | ||||
| 		per_cpu(ipv4_tcp_sk.sock, cpu) = sk; | ||||
| 	} | ||||
| 	if (register_pernet_subsys(&tcp_sk_ops)) | ||||
| 		panic("Failed to create the TCP control socket.\n"); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Sebastian Andrzej Siewior
						Sebastian Andrzej Siewior