rcu in bpqether driver.
PATCH 1/1 rcu in bpqether driver.
From Suzanne Wood <[email protected]>:
Clarify RCU implementation in bpqether.c.
Because bpq_new_device() calls list_add_rcu() and bpq_free_device() calls list_del_rcu(), substitute list_for_each_entry_rcu() for list_for_each_entry() in bpq_get_ax25_dev() and in bpq_seq_start().
Add rcu dereference protection in bpq_seq_next().
The rcu_read_lock()/unlock() in bpq_device_event() are removed because netdev event handlers are called with RTNL locking in place.
FYI: bpq_free_device() calls list_del_rcu() which, per list.h, requires synchronize_rcu() which can block or call_rcu() or call_rcu_bh() which cannot block. Herbert Xu notes that synchronization is done here by unregister_netdevice(). This calls synchronize_net() which in turn uses synchronize_rcu().
drivers/net/hamradio/bpqether.c | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-)
drivers/net/hamradio/bpqether.c +3 -6
@@ -144,7 +144,7 @@ static inline struct net_device *bpq_get {struct bpqdev *bpq; -list_for_each_entry (bpq, &bpq_devices, bpq_list) { +list_for_each_entry_rcu (bpq, &bpq_devices, bpq_list) {if (bpq->ethdev == dev)return bpq->axdev; }
@@ -399,7 +399,7 @@ static void *bpq_seq_start(struct seq_fiif (*pos ==0 )return SEQ_START_TOKEN ; -list_for_each_entry (bpqdev, &bpq_devices, bpq_list) { +list_for_each_entry_rcu (bpqdev, &bpq_devices, bpq_list) {if (i == *pos)return bpqdev; }
@@ -418,7 +418,7 @@ static void *bpq_seq_next(struct seq_fil p = ((struct bpqdev *)v)->bpq_list.next;return (p == &bpq_devices) ?NULL - : list_entry(p, struct bpqdev, bpq_list); + : rcu_dereference(list_entry(p, struct bpqdev, bpq_list)); }static void bpq_seq_stop (struct seq_file *seq,void *v)
@@ -561,8 +561,6 @@ static int bpq_device_event(struct notifif (!dev_is_ethdev (dev))return NOTIFY_DONE ; -rcu_read_lock (); -switch (event) {case NETDEV_UP :/* new ethernet device -> new BPQ interface */ if (bpq_get_ax25_dev (dev) ==NULL )
@@ -581,7 +579,6 @@ static int bpq_device_event(struct notifdefault :break ; } -rcu_read_unlock ();return NOTIFY_DONE ; }
Jeff Garzik
Appliedapplied