aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-05-19 11:19:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-22 14:05:59 -0400
commit87057825824973f29cf2f37cff1e549170b2d7e6 (patch)
treedbbb7596aeea401a1e9c9379d0948889dbde8884
parent9cef873798dfcdc10ff40b02abf1de935ceeba85 (diff)
wext: remove atomic requirement for wireless stats
The requirement for wireless stats to be atomic is now mostly artificial since we hold the rtnl _and_ the dev_base_lock for iterating the device list. Doing that is not required, just the rtnl is sufficient (and the rtnl is required for other reasons outlined in commit "wext: fix get_wireless_stats locking"). This will fix http://bugzilla.kernel.org/show_bug.cgi?id=13344 and make things easier for drivers. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/wireless/wext.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index d3bbef70cc7c..22378daceb94 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -636,8 +636,10 @@ static void wireless_seq_printf_stats(struct seq_file *seq,
636/* 636/*
637 * Print info for /proc/net/wireless (print all entries) 637 * Print info for /proc/net/wireless (print all entries)
638 */ 638 */
639static int wireless_seq_show(struct seq_file *seq, void *v) 639static int wireless_dev_seq_show(struct seq_file *seq, void *v)
640{ 640{
641 might_sleep();
642
641 if (v == SEQ_START_TOKEN) 643 if (v == SEQ_START_TOKEN)
642 seq_printf(seq, "Inter-| sta-| Quality | Discarded " 644 seq_printf(seq, "Inter-| sta-| Quality | Discarded "
643 "packets | Missed | WE\n" 645 "packets | Missed | WE\n"
@@ -651,21 +653,41 @@ static int wireless_seq_show(struct seq_file *seq, void *v)
651 653
652static void *wireless_dev_seq_start(struct seq_file *seq, loff_t *pos) 654static void *wireless_dev_seq_start(struct seq_file *seq, loff_t *pos)
653{ 655{
656 struct net *net = seq_file_net(seq);
657 loff_t off;
658 struct net_device *dev;
659
654 rtnl_lock(); 660 rtnl_lock();
655 return dev_seq_start(seq, pos); 661 if (!*pos)
662 return SEQ_START_TOKEN;
663
664 off = 1;
665 for_each_netdev(net, dev)
666 if (off++ == *pos)
667 return dev;
668 return NULL;
669}
670
671static void *wireless_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
672{
673 struct net *net = seq_file_net(seq);
674
675 ++*pos;
676
677 return v == SEQ_START_TOKEN ?
678 first_net_device(net) : next_net_device(v);
656} 679}
657 680
658static void wireless_dev_seq_stop(struct seq_file *seq, void *v) 681static void wireless_dev_seq_stop(struct seq_file *seq, void *v)
659{ 682{
660 dev_seq_stop(seq, v);
661 rtnl_unlock(); 683 rtnl_unlock();
662} 684}
663 685
664static const struct seq_operations wireless_seq_ops = { 686static const struct seq_operations wireless_seq_ops = {
665 .start = wireless_dev_seq_start, 687 .start = wireless_dev_seq_start,
666 .next = dev_seq_next, 688 .next = wireless_dev_seq_next,
667 .stop = wireless_dev_seq_stop, 689 .stop = wireless_dev_seq_stop,
668 .show = wireless_seq_show, 690 .show = wireless_dev_seq_show,
669}; 691};
670 692
671static int seq_open_wireless(struct inode *inode, struct file *file) 693static int seq_open_wireless(struct inode *inode, struct file *file)