@@ -193,7 +193,7 @@ static int announce_servers(struct sockaddr_qrtr *sq)
193193 struct qrtr_server * srv ;
194194 struct qrtr_node * node ;
195195 void __rcu * * slot ;
196- int ret = 0 ;
196+ int ret ;
197197
198198 node = node_get (qrtr_ns .local_node );
199199 if (!node )
@@ -203,18 +203,27 @@ static int announce_servers(struct sockaddr_qrtr *sq)
203203 /* Announce the list of servers registered in this node */
204204 radix_tree_for_each_slot (slot , & node -> servers , & iter , 0 ) {
205205 srv = radix_tree_deref_slot (slot );
206+ if (!srv )
207+ continue ;
208+ if (radix_tree_deref_retry (srv )) {
209+ slot = radix_tree_iter_retry (& iter );
210+ continue ;
211+ }
212+ slot = radix_tree_iter_resume (slot , & iter );
213+ rcu_read_unlock ();
206214
207215 ret = service_announce_new (sq , srv );
208216 if (ret < 0 ) {
209217 pr_err ("failed to announce new service\n" );
210- goto err_out ;
218+ return ret ;
211219 }
220+
221+ rcu_read_lock ();
212222 }
213223
214- err_out :
215224 rcu_read_unlock ();
216225
217- return ret ;
226+ return 0 ;
218227}
219228
220229static struct qrtr_server * server_add (unsigned int service ,
@@ -339,7 +348,7 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
339348 struct qrtr_node * node ;
340349 void __rcu * * slot ;
341350 struct kvec iv ;
342- int ret = 0 ;
351+ int ret ;
343352
344353 iv .iov_base = & pkt ;
345354 iv .iov_len = sizeof (pkt );
@@ -352,7 +361,16 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
352361 /* Advertise removal of this client to all servers of remote node */
353362 radix_tree_for_each_slot (slot , & node -> servers , & iter , 0 ) {
354363 srv = radix_tree_deref_slot (slot );
364+ if (!srv )
365+ continue ;
366+ if (radix_tree_deref_retry (srv )) {
367+ slot = radix_tree_iter_retry (& iter );
368+ continue ;
369+ }
370+ slot = radix_tree_iter_resume (slot , & iter );
371+ rcu_read_unlock ();
355372 server_del (node , srv -> port );
373+ rcu_read_lock ();
356374 }
357375 rcu_read_unlock ();
358376
@@ -368,6 +386,14 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
368386 rcu_read_lock ();
369387 radix_tree_for_each_slot (slot , & local_node -> servers , & iter , 0 ) {
370388 srv = radix_tree_deref_slot (slot );
389+ if (!srv )
390+ continue ;
391+ if (radix_tree_deref_retry (srv )) {
392+ slot = radix_tree_iter_retry (& iter );
393+ continue ;
394+ }
395+ slot = radix_tree_iter_resume (slot , & iter );
396+ rcu_read_unlock ();
371397
372398 sq .sq_family = AF_QIPCRTR ;
373399 sq .sq_node = srv -> node ;
@@ -379,14 +405,14 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
379405 ret = kernel_sendmsg (qrtr_ns .sock , & msg , & iv , 1 , sizeof (pkt ));
380406 if (ret < 0 ) {
381407 pr_err ("failed to send bye cmd\n" );
382- goto err_out ;
408+ return ret ;
383409 }
410+ rcu_read_lock ();
384411 }
385412
386- err_out :
387413 rcu_read_unlock ();
388414
389- return ret ;
415+ return 0 ;
390416}
391417
392418static int ctrl_cmd_del_client (struct sockaddr_qrtr * from ,
@@ -404,7 +430,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from,
404430 struct list_head * li ;
405431 void __rcu * * slot ;
406432 struct kvec iv ;
407- int ret = 0 ;
433+ int ret ;
408434
409435 iv .iov_base = & pkt ;
410436 iv .iov_len = sizeof (pkt );
@@ -447,6 +473,14 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from,
447473 rcu_read_lock ();
448474 radix_tree_for_each_slot (slot , & local_node -> servers , & iter , 0 ) {
449475 srv = radix_tree_deref_slot (slot );
476+ if (!srv )
477+ continue ;
478+ if (radix_tree_deref_retry (srv )) {
479+ slot = radix_tree_iter_retry (& iter );
480+ continue ;
481+ }
482+ slot = radix_tree_iter_resume (slot , & iter );
483+ rcu_read_unlock ();
450484
451485 sq .sq_family = AF_QIPCRTR ;
452486 sq .sq_node = srv -> node ;
@@ -458,14 +492,14 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from,
458492 ret = kernel_sendmsg (qrtr_ns .sock , & msg , & iv , 1 , sizeof (pkt ));
459493 if (ret < 0 ) {
460494 pr_err ("failed to send del client cmd\n" );
461- goto err_out ;
495+ return ret ;
462496 }
497+ rcu_read_lock ();
463498 }
464499
465- err_out :
466500 rcu_read_unlock ();
467501
468- return ret ;
502+ return 0 ;
469503}
470504
471505static int ctrl_cmd_new_server (struct sockaddr_qrtr * from ,
@@ -571,16 +605,34 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from,
571605 rcu_read_lock ();
572606 radix_tree_for_each_slot (node_slot , & nodes , & node_iter , 0 ) {
573607 node = radix_tree_deref_slot (node_slot );
608+ if (!node )
609+ continue ;
610+ if (radix_tree_deref_retry (node )) {
611+ node_slot = radix_tree_iter_retry (& node_iter );
612+ continue ;
613+ }
614+ node_slot = radix_tree_iter_resume (node_slot , & node_iter );
574615
575616 radix_tree_for_each_slot (srv_slot , & node -> servers ,
576617 & srv_iter , 0 ) {
577618 struct qrtr_server * srv ;
578619
579620 srv = radix_tree_deref_slot (srv_slot );
621+ if (!srv )
622+ continue ;
623+ if (radix_tree_deref_retry (srv )) {
624+ srv_slot = radix_tree_iter_retry (& srv_iter );
625+ continue ;
626+ }
627+
580628 if (!server_match (srv , & filter ))
581629 continue ;
582630
631+ srv_slot = radix_tree_iter_resume (srv_slot , & srv_iter );
632+
633+ rcu_read_unlock ();
583634 lookup_notify (from , srv , true);
635+ rcu_read_lock ();
584636 }
585637 }
586638 rcu_read_unlock ();
0 commit comments