@@ -97,12 +97,12 @@ static int netlink_dump(struct sock *sk);
9797static void netlink_skb_destructor (struct sk_buff * skb );
9898
9999/* nl_table locking explained:
100- * Lookup and traversal are protected with nl_sk_hash_lock or nl_table_lock
101- * combined with an RCU read-side lock. Insertion and removal are protected
102- * with nl_sk_hash_lock while using RCU list modification primitives and may
103- * run in parallel to nl_table_lock protected lookups. Destruction of the
104- * Netlink socket may only occur * after* nl_table_lock has been acquired
105- * either during or after the socket has been removed from the list .
100+ * Lookup and traversal are protected with an RCU read-side lock. Insertion
101+ * and removal are protected with nl_sk_hash_lock while using RCU list
102+ * modification primitives and may run in parallel to RCU protected lookups.
103+ * Destruction of the Netlink socket may only occur *after* nl_table_lock has
104+ * been acquired * either during or after the socket has been removed from
105+ * the list and after an RCU grace period .
106106 */
107107DEFINE_RWLOCK (nl_table_lock );
108108EXPORT_SYMBOL_GPL (nl_table_lock );
@@ -1003,13 +1003,11 @@ static struct sock *netlink_lookup(struct net *net, int protocol, u32 portid)
10031003 struct netlink_table * table = & nl_table [protocol ];
10041004 struct sock * sk ;
10051005
1006- read_lock (& nl_table_lock );
10071006 rcu_read_lock ();
10081007 sk = __netlink_lookup (table , portid , net );
10091008 if (sk )
10101009 sock_hold (sk );
10111010 rcu_read_unlock ();
1012- read_unlock (& nl_table_lock );
10131011
10141012 return sk ;
10151013}
@@ -1183,6 +1181,13 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
11831181 goto out ;
11841182}
11851183
1184+ static void deferred_put_nlk_sk (struct rcu_head * head )
1185+ {
1186+ struct netlink_sock * nlk = container_of (head , struct netlink_sock , rcu );
1187+
1188+ sock_put (& nlk -> sk );
1189+ }
1190+
11861191static int netlink_release (struct socket * sock )
11871192{
11881193 struct sock * sk = sock -> sk ;
@@ -1248,7 +1253,7 @@ static int netlink_release(struct socket *sock)
12481253 local_bh_disable ();
12491254 sock_prot_inuse_add (sock_net (sk ), & netlink_proto , -1 );
12501255 local_bh_enable ();
1251- sock_put ( sk );
1256+ call_rcu ( & nlk -> rcu , deferred_put_nlk_sk );
12521257 return 0 ;
12531258}
12541259
@@ -1263,19 +1268,16 @@ static int netlink_autobind(struct socket *sock)
12631268
12641269retry :
12651270 cond_resched ();
1266- netlink_table_grab ();
12671271 rcu_read_lock ();
12681272 if (__netlink_lookup (table , portid , net )) {
12691273 /* Bind collision, search negative portid values. */
12701274 portid = rover -- ;
12711275 if (rover > -4097 )
12721276 rover = -4097 ;
12731277 rcu_read_unlock ();
1274- netlink_table_ungrab ();
12751278 goto retry ;
12761279 }
12771280 rcu_read_unlock ();
1278- netlink_table_ungrab ();
12791281
12801282 err = netlink_insert (sk , net , portid );
12811283 if (err == - EADDRINUSE )
@@ -2910,9 +2912,8 @@ static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos)
29102912}
29112913
29122914static void * netlink_seq_start (struct seq_file * seq , loff_t * pos )
2913- __acquires (nl_table_lock ) __acquires ( RCU )
2915+ __acquires (RCU )
29142916{
2915- read_lock (& nl_table_lock );
29162917 rcu_read_lock ();
29172918 return * pos ? netlink_seq_socket_idx (seq , * pos - 1 ) : SEQ_START_TOKEN ;
29182919}
@@ -2964,10 +2965,9 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
29642965}
29652966
29662967static void netlink_seq_stop (struct seq_file * seq , void * v )
2967- __releases (RCU ) __releases ( nl_table_lock )
2968+ __releases (RCU )
29682969{
29692970 rcu_read_unlock ();
2970- read_unlock (& nl_table_lock );
29712971}
29722972
29732973
0 commit comments