@@ -85,20 +85,19 @@ struct raw_frag_vec {
8585 int hlen ;
8686};
8787
88- struct raw_hashinfo raw_v4_hashinfo = {
89- .lock = __RW_LOCK_UNLOCKED (raw_v4_hashinfo .lock ),
90- };
88+ struct raw_hashinfo raw_v4_hashinfo ;
9189EXPORT_SYMBOL_GPL (raw_v4_hashinfo );
9290
9391int raw_hash_sk (struct sock * sk )
9492{
9593 struct raw_hashinfo * h = sk -> sk_prot -> h .raw_hash ;
96- struct hlist_head * head ;
94+ struct hlist_nulls_head * hlist ;
9795
98- head = & h -> ht [inet_sk (sk )-> inet_num & (RAW_HTABLE_SIZE - 1 )];
96+ hlist = & h -> ht [inet_sk (sk )-> inet_num & (RAW_HTABLE_SIZE - 1 )];
9997
10098 write_lock_bh (& h -> lock );
101- sk_add_node (sk , head );
99+ hlist_nulls_add_head_rcu (& sk -> sk_nulls_node , hlist );
100+ sock_set_flag (sk , SOCK_RCU_FREE );
102101 write_unlock_bh (& h -> lock );
103102 sock_prot_inuse_add (sock_net (sk ), sk -> sk_prot , 1 );
104103
@@ -111,7 +110,7 @@ void raw_unhash_sk(struct sock *sk)
111110 struct raw_hashinfo * h = sk -> sk_prot -> h .raw_hash ;
112111
113112 write_lock_bh (& h -> lock );
114- if (sk_del_node_init (sk ))
113+ if (__sk_nulls_del_node_init_rcu (sk ))
115114 sock_prot_inuse_add (sock_net (sk ), sk -> sk_prot , -1 );
116115 write_unlock_bh (& h -> lock );
117116}
@@ -164,17 +163,16 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
164163static int raw_v4_input (struct sk_buff * skb , const struct iphdr * iph , int hash )
165164{
166165 struct net * net = dev_net (skb -> dev );
166+ struct hlist_nulls_head * hlist ;
167+ struct hlist_nulls_node * hnode ;
167168 int sdif = inet_sdif (skb );
168169 int dif = inet_iif (skb );
169- struct hlist_head * head ;
170170 int delivered = 0 ;
171171 struct sock * sk ;
172172
173- head = & raw_v4_hashinfo .ht [hash ];
174- if (hlist_empty (head ))
175- return 0 ;
176- read_lock (& raw_v4_hashinfo .lock );
177- sk_for_each (sk , head ) {
173+ hlist = & raw_v4_hashinfo .ht [hash ];
174+ rcu_read_lock ();
175+ hlist_nulls_for_each_entry (sk , hnode , hlist , sk_nulls_node ) {
178176 if (!raw_v4_match (net , sk , iph -> protocol ,
179177 iph -> saddr , iph -> daddr , dif , sdif ))
180178 continue ;
@@ -189,7 +187,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
189187 raw_rcv (sk , clone );
190188 }
191189 }
192- read_unlock ( & raw_v4_hashinfo . lock );
190+ rcu_read_unlock ( );
193191 return delivered ;
194192}
195193
@@ -265,25 +263,26 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
265263void raw_icmp_error (struct sk_buff * skb , int protocol , u32 info )
266264{
267265 struct net * net = dev_net (skb -> dev );;
266+ struct hlist_nulls_head * hlist ;
267+ struct hlist_nulls_node * hnode ;
268268 int dif = skb -> dev -> ifindex ;
269269 int sdif = inet_sdif (skb );
270- struct hlist_head * head ;
271270 const struct iphdr * iph ;
272271 struct sock * sk ;
273272 int hash ;
274273
275274 hash = protocol & (RAW_HTABLE_SIZE - 1 );
276- head = & raw_v4_hashinfo .ht [hash ];
275+ hlist = & raw_v4_hashinfo .ht [hash ];
277276
278- read_lock ( & raw_v4_hashinfo . lock );
279- sk_for_each (sk , head ) {
277+ rcu_read_lock ( );
278+ hlist_nulls_for_each_entry (sk , hnode , hlist , sk_nulls_node ) {
280279 iph = (const struct iphdr * )skb -> data ;
281280 if (!raw_v4_match (net , sk , iph -> protocol ,
282281 iph -> saddr , iph -> daddr , dif , sdif ))
283282 continue ;
284283 raw_err (sk , skb , info );
285284 }
286- read_unlock ( & raw_v4_hashinfo . lock );
285+ rcu_read_unlock ( );
287286}
288287
289288static int raw_rcv_skb (struct sock * sk , struct sk_buff * skb )
@@ -944,44 +943,41 @@ struct proto raw_prot = {
944943};
945944
946945#ifdef CONFIG_PROC_FS
947- static struct sock * raw_get_first (struct seq_file * seq )
946+ static struct sock * raw_get_first (struct seq_file * seq , int bucket )
948947{
949- struct sock * sk ;
950948 struct raw_hashinfo * h = pde_data (file_inode (seq -> file ));
951949 struct raw_iter_state * state = raw_seq_private (seq );
950+ struct hlist_nulls_head * hlist ;
951+ struct hlist_nulls_node * hnode ;
952+ struct sock * sk ;
952953
953- for (state -> bucket = 0 ; state -> bucket < RAW_HTABLE_SIZE ;
954+ for (state -> bucket = bucket ; state -> bucket < RAW_HTABLE_SIZE ;
954955 ++ state -> bucket ) {
955- sk_for_each (sk , & h -> ht [state -> bucket ])
956+ hlist = & h -> ht [state -> bucket ];
957+ hlist_nulls_for_each_entry (sk , hnode , hlist , sk_nulls_node ) {
956958 if (sock_net (sk ) == seq_file_net (seq ))
957- goto found ;
959+ return sk ;
960+ }
958961 }
959- sk = NULL ;
960- found :
961- return sk ;
962+ return NULL ;
962963}
963964
964965static struct sock * raw_get_next (struct seq_file * seq , struct sock * sk )
965966{
966- struct raw_hashinfo * h = pde_data (file_inode (seq -> file ));
967967 struct raw_iter_state * state = raw_seq_private (seq );
968968
969969 do {
970- sk = sk_next (sk );
971- try_again :
972- ;
970+ sk = sk_nulls_next (sk );
973971 } while (sk && sock_net (sk ) != seq_file_net (seq ));
974972
975- if (!sk && ++ state -> bucket < RAW_HTABLE_SIZE ) {
976- sk = sk_head (& h -> ht [state -> bucket ]);
977- goto try_again ;
978- }
973+ if (!sk )
974+ return raw_get_first (seq , state -> bucket + 1 );
979975 return sk ;
980976}
981977
982978static struct sock * raw_get_idx (struct seq_file * seq , loff_t pos )
983979{
984- struct sock * sk = raw_get_first (seq );
980+ struct sock * sk = raw_get_first (seq , 0 );
985981
986982 if (sk )
987983 while (pos && (sk = raw_get_next (seq , sk )) != NULL )
@@ -990,11 +986,9 @@ static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos)
990986}
991987
992988void * raw_seq_start (struct seq_file * seq , loff_t * pos )
993- __acquires (& h - > lock )
989+ __acquires (RCU )
994990{
995- struct raw_hashinfo * h = pde_data (file_inode (seq -> file ));
996-
997- read_lock (& h -> lock );
991+ rcu_read_lock ();
998992 return * pos ? raw_get_idx (seq , * pos - 1 ) : SEQ_START_TOKEN ;
999993}
1000994EXPORT_SYMBOL_GPL (raw_seq_start );
@@ -1004,7 +998,7 @@ void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1004998 struct sock * sk ;
1005999
10061000 if (v == SEQ_START_TOKEN )
1007- sk = raw_get_first (seq );
1001+ sk = raw_get_first (seq , 0 );
10081002 else
10091003 sk = raw_get_next (seq , v );
10101004 ++ * pos ;
@@ -1013,11 +1007,9 @@ void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
10131007EXPORT_SYMBOL_GPL (raw_seq_next );
10141008
10151009void raw_seq_stop (struct seq_file * seq , void * v )
1016- __releases (& h - > lock )
1010+ __releases (RCU )
10171011{
1018- struct raw_hashinfo * h = pde_data (file_inode (seq -> file ));
1019-
1020- read_unlock (& h -> lock );
1012+ rcu_read_unlock ();
10211013}
10221014EXPORT_SYMBOL_GPL (raw_seq_stop );
10231015
@@ -1079,6 +1071,7 @@ static __net_initdata struct pernet_operations raw_net_ops = {
10791071
10801072int __init raw_proc_init (void )
10811073{
1074+
10821075 return register_pernet_subsys (& raw_net_ops );
10831076}
10841077
0 commit comments