@@ -77,8 +77,8 @@ static int stats_timer __read_mostly = 1;
77
77
module_param (stats_timer , int , S_IRUGO );
78
78
MODULE_PARM_DESC (stats_timer , "enable timer for statistics (default:on)" );
79
79
80
- HLIST_HEAD ( can_rx_dev_list );
81
- static struct dev_rcv_lists can_rx_alldev_list ;
80
+ /* receive filters subscribed for 'all' CAN devices */
81
+ struct dev_rcv_lists can_rx_alldev_list ;
82
82
static DEFINE_SPINLOCK (can_rcvlists_lock );
83
83
84
84
static struct kmem_cache * rcv_cache __read_mostly ;
@@ -292,28 +292,10 @@ EXPORT_SYMBOL(can_send);
292
292
293
293
static struct dev_rcv_lists * find_dev_rcv_lists (struct net_device * dev )
294
294
{
295
- struct dev_rcv_lists * d = NULL ;
296
- struct hlist_node * n ;
297
-
298
- /*
299
- * find receive list for this device
300
- *
301
- * The hlist_for_each_entry*() macros curse through the list
302
- * using the pointer variable n and set d to the containing
303
- * struct in each list iteration. Therefore, after list
304
- * iteration, d is unmodified when the list is empty, and it
305
- * points to last list element, when the list is non-empty
306
- * but no match in the loop body is found. I.e. d is *not*
307
- * NULL when no match is found. We can, however, use the
308
- * cursor variable n to decide if a match was found.
309
- */
310
-
311
- hlist_for_each_entry_rcu (d , n , & can_rx_dev_list , list ) {
312
- if (d -> dev == dev )
313
- break ;
314
- }
315
-
316
- return n ? d : NULL ;
295
+ if (!dev )
296
+ return & can_rx_alldev_list ;
297
+ else
298
+ return (struct dev_rcv_lists * )dev -> ml_priv ;
317
299
}
318
300
319
301
/**
@@ -467,16 +449,6 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
467
449
}
468
450
EXPORT_SYMBOL (can_rx_register );
469
451
470
- /*
471
- * can_rx_delete_device - rcu callback for dev_rcv_lists structure removal
472
- */
473
- static void can_rx_delete_device (struct rcu_head * rp )
474
- {
475
- struct dev_rcv_lists * d = container_of (rp , struct dev_rcv_lists , rcu );
476
-
477
- kfree (d );
478
- }
479
-
480
452
/*
481
453
* can_rx_delete_receiver - rcu callback for single receiver entry removal
482
454
*/
@@ -541,7 +513,6 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
541
513
"dev %s, id %03X, mask %03X\n" ,
542
514
DNAME (dev ), can_id , mask );
543
515
r = NULL ;
544
- d = NULL ;
545
516
goto out ;
546
517
}
547
518
@@ -552,21 +523,17 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
552
523
can_pstats .rcv_entries -- ;
553
524
554
525
/* remove device structure requested by NETDEV_UNREGISTER */
555
- if (d -> remove_on_zero_entries && !d -> entries )
556
- hlist_del_rcu ( & d -> list );
557
- else
558
- d = NULL ;
526
+ if (d -> remove_on_zero_entries && !d -> entries ) {
527
+ kfree ( d );
528
+ dev -> ml_priv = NULL ;
529
+ }
559
530
560
531
out :
561
532
spin_unlock (& can_rcvlists_lock );
562
533
563
534
/* schedule the receiver item for deletion */
564
535
if (r )
565
536
call_rcu (& r -> rcu , can_rx_delete_receiver );
566
-
567
- /* schedule the device structure for deletion */
568
- if (d )
569
- call_rcu (& d -> rcu , can_rx_delete_device );
570
537
}
571
538
EXPORT_SYMBOL (can_rx_unregister );
572
539
@@ -780,48 +747,35 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg,
780
747
781
748
case NETDEV_REGISTER :
782
749
783
- /*
784
- * create new dev_rcv_lists for this device
785
- *
786
- * N.B. zeroing the struct is the correct initialization
787
- * for the embedded hlist_head structs.
788
- * Another list type, e.g. list_head, would require
789
- * explicit initialization.
790
- */
791
-
750
+ /* create new dev_rcv_lists for this device */
792
751
d = kzalloc (sizeof (* d ), GFP_KERNEL );
793
752
if (!d ) {
794
753
printk (KERN_ERR
795
754
"can: allocation of receive list failed\n" );
796
755
return NOTIFY_DONE ;
797
756
}
798
- d -> dev = dev ;
799
-
800
- spin_lock (& can_rcvlists_lock );
801
- hlist_add_head_rcu (& d -> list , & can_rx_dev_list );
802
- spin_unlock (& can_rcvlists_lock );
757
+ BUG_ON (dev -> ml_priv );
758
+ dev -> ml_priv = d ;
803
759
804
760
break ;
805
761
806
762
case NETDEV_UNREGISTER :
807
763
spin_lock (& can_rcvlists_lock );
808
764
809
- d = find_dev_rcv_lists ( dev ) ;
765
+ d = dev -> ml_priv ;
810
766
if (d ) {
811
- if (d -> entries ) {
767
+ if (d -> entries )
812
768
d -> remove_on_zero_entries = 1 ;
813
- d = NULL ;
814
- } else
815
- hlist_del_rcu (& d -> list );
769
+ else {
770
+ kfree (d );
771
+ dev -> ml_priv = NULL ;
772
+ }
816
773
} else
817
774
printk (KERN_ERR "can: notifier: receive list not "
818
775
"found for dev %s\n" , dev -> name );
819
776
820
777
spin_unlock (& can_rcvlists_lock );
821
778
822
- if (d )
823
- call_rcu (& d -> rcu , can_rx_delete_device );
824
-
825
779
break ;
826
780
}
827
781
@@ -853,21 +807,13 @@ static __init int can_init(void)
853
807
{
854
808
printk (banner );
855
809
810
+ memset (& can_rx_alldev_list , 0 , sizeof (can_rx_alldev_list ));
811
+
856
812
rcv_cache = kmem_cache_create ("can_receiver" , sizeof (struct receiver ),
857
813
0 , 0 , NULL );
858
814
if (!rcv_cache )
859
815
return - ENOMEM ;
860
816
861
- /*
862
- * Insert can_rx_alldev_list for reception on all devices.
863
- * This struct is zero initialized which is correct for the
864
- * embedded hlist heads, the dev pointer, and the entries counter.
865
- */
866
-
867
- spin_lock (& can_rcvlists_lock );
868
- hlist_add_head_rcu (& can_rx_alldev_list .list , & can_rx_dev_list );
869
- spin_unlock (& can_rcvlists_lock );
870
-
871
817
if (stats_timer ) {
872
818
/* the statistics are updated every second (timer triggered) */
873
819
setup_timer (& can_stattimer , can_stat_update , 0 );
@@ -887,8 +833,7 @@ static __init int can_init(void)
887
833
888
834
static __exit void can_exit (void )
889
835
{
890
- struct dev_rcv_lists * d ;
891
- struct hlist_node * n , * next ;
836
+ struct net_device * dev ;
892
837
893
838
if (stats_timer )
894
839
del_timer (& can_stattimer );
@@ -900,14 +845,19 @@ static __exit void can_exit(void)
900
845
unregister_netdevice_notifier (& can_netdev_notifier );
901
846
sock_unregister (PF_CAN );
902
847
903
- /* remove can_rx_dev_list */
904
- spin_lock (& can_rcvlists_lock );
905
- hlist_del (& can_rx_alldev_list .list );
906
- hlist_for_each_entry_safe (d , n , next , & can_rx_dev_list , list ) {
907
- hlist_del (& d -> list );
908
- kfree (d );
848
+ /* remove created dev_rcv_lists from still registered CAN devices */
849
+ rcu_read_lock ();
850
+ for_each_netdev_rcu (& init_net , dev ) {
851
+ if (dev -> type == ARPHRD_CAN && dev -> ml_priv ){
852
+
853
+ struct dev_rcv_lists * d = dev -> ml_priv ;
854
+
855
+ BUG_ON (d -> entries );
856
+ kfree (d );
857
+ dev -> ml_priv = NULL ;
858
+ }
909
859
}
910
- spin_unlock ( & can_rcvlists_lock );
860
+ rcu_read_unlock ( );
911
861
912
862
rcu_barrier (); /* Wait for completion of call_rcu()'s */
913
863
0 commit comments