@@ -193,7 +193,7 @@ static int announce_servers(struct sockaddr_qrtr *sq)
193
193
struct qrtr_server * srv ;
194
194
struct qrtr_node * node ;
195
195
void __rcu * * slot ;
196
- int ret = 0 ;
196
+ int ret ;
197
197
198
198
node = node_get (qrtr_ns .local_node );
199
199
if (!node )
@@ -203,18 +203,27 @@ static int announce_servers(struct sockaddr_qrtr *sq)
203
203
/* Announce the list of servers registered in this node */
204
204
radix_tree_for_each_slot (slot , & node -> servers , & iter , 0 ) {
205
205
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 ();
206
214
207
215
ret = service_announce_new (sq , srv );
208
216
if (ret < 0 ) {
209
217
pr_err ("failed to announce new service\n" );
210
- goto err_out ;
218
+ return ret ;
211
219
}
220
+
221
+ rcu_read_lock ();
212
222
}
213
223
214
- err_out :
215
224
rcu_read_unlock ();
216
225
217
- return ret ;
226
+ return 0 ;
218
227
}
219
228
220
229
static struct qrtr_server * server_add (unsigned int service ,
@@ -339,7 +348,7 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
339
348
struct qrtr_node * node ;
340
349
void __rcu * * slot ;
341
350
struct kvec iv ;
342
- int ret = 0 ;
351
+ int ret ;
343
352
344
353
iv .iov_base = & pkt ;
345
354
iv .iov_len = sizeof (pkt );
@@ -352,7 +361,16 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
352
361
/* Advertise removal of this client to all servers of remote node */
353
362
radix_tree_for_each_slot (slot , & node -> servers , & iter , 0 ) {
354
363
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 ();
355
372
server_del (node , srv -> port );
373
+ rcu_read_lock ();
356
374
}
357
375
rcu_read_unlock ();
358
376
@@ -368,6 +386,14 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
368
386
rcu_read_lock ();
369
387
radix_tree_for_each_slot (slot , & local_node -> servers , & iter , 0 ) {
370
388
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 ();
371
397
372
398
sq .sq_family = AF_QIPCRTR ;
373
399
sq .sq_node = srv -> node ;
@@ -379,14 +405,14 @@ static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
379
405
ret = kernel_sendmsg (qrtr_ns .sock , & msg , & iv , 1 , sizeof (pkt ));
380
406
if (ret < 0 ) {
381
407
pr_err ("failed to send bye cmd\n" );
382
- goto err_out ;
408
+ return ret ;
383
409
}
410
+ rcu_read_lock ();
384
411
}
385
412
386
- err_out :
387
413
rcu_read_unlock ();
388
414
389
- return ret ;
415
+ return 0 ;
390
416
}
391
417
392
418
static int ctrl_cmd_del_client (struct sockaddr_qrtr * from ,
@@ -404,7 +430,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from,
404
430
struct list_head * li ;
405
431
void __rcu * * slot ;
406
432
struct kvec iv ;
407
- int ret = 0 ;
433
+ int ret ;
408
434
409
435
iv .iov_base = & pkt ;
410
436
iv .iov_len = sizeof (pkt );
@@ -447,6 +473,14 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from,
447
473
rcu_read_lock ();
448
474
radix_tree_for_each_slot (slot , & local_node -> servers , & iter , 0 ) {
449
475
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 ();
450
484
451
485
sq .sq_family = AF_QIPCRTR ;
452
486
sq .sq_node = srv -> node ;
@@ -458,14 +492,14 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from,
458
492
ret = kernel_sendmsg (qrtr_ns .sock , & msg , & iv , 1 , sizeof (pkt ));
459
493
if (ret < 0 ) {
460
494
pr_err ("failed to send del client cmd\n" );
461
- goto err_out ;
495
+ return ret ;
462
496
}
497
+ rcu_read_lock ();
463
498
}
464
499
465
- err_out :
466
500
rcu_read_unlock ();
467
501
468
- return ret ;
502
+ return 0 ;
469
503
}
470
504
471
505
static int ctrl_cmd_new_server (struct sockaddr_qrtr * from ,
@@ -571,16 +605,34 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from,
571
605
rcu_read_lock ();
572
606
radix_tree_for_each_slot (node_slot , & nodes , & node_iter , 0 ) {
573
607
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 );
574
615
575
616
radix_tree_for_each_slot (srv_slot , & node -> servers ,
576
617
& srv_iter , 0 ) {
577
618
struct qrtr_server * srv ;
578
619
579
620
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
+
580
628
if (!server_match (srv , & filter ))
581
629
continue ;
582
630
631
+ srv_slot = radix_tree_iter_resume (srv_slot , & srv_iter );
632
+
633
+ rcu_read_unlock ();
583
634
lookup_notify (from , srv , true);
635
+ rcu_read_lock ();
584
636
}
585
637
}
586
638
rcu_read_unlock ();
0 commit comments