aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-08-03 09:54:41 -0400
committerJohn W. Linville <linville@tuxdriver.com>2006-08-04 14:57:19 -0400
commit782a6675119c76c071e74e2ddd98268f47770cba (patch)
tree83815eb8984242ec93a632694d0d243ec8ccd691 /net
parentefe78cda3596f8a6d1c2d4a6b1a221bafa3e1a48 (diff)
[PATCH] Send wireless netlink events with a clean slate
Drivers expect to be able to call wireless_send_event in arbitrary contexts. On the other hand, netlink really doesn't like being invoked in an IRQ context. So we need to postpone the sending of netlink skb's to a tasklet. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/core/wireless.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/net/core/wireless.c b/net/core/wireless.c
index d2bc72d318f7..de0bde4b51dd 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -82,6 +82,7 @@
82#include <linux/init.h> /* for __init */ 82#include <linux/init.h> /* for __init */
83#include <linux/if_arp.h> /* ARPHRD_ETHER */ 83#include <linux/if_arp.h> /* ARPHRD_ETHER */
84#include <linux/etherdevice.h> /* compare_ether_addr */ 84#include <linux/etherdevice.h> /* compare_ether_addr */
85#include <linux/interrupt.h>
85 86
86#include <linux/wireless.h> /* Pretty obvious */ 87#include <linux/wireless.h> /* Pretty obvious */
87#include <net/iw_handler.h> /* New driver API */ 88#include <net/iw_handler.h> /* New driver API */
@@ -1842,6 +1843,18 @@ int wireless_rtnetlink_set(struct net_device * dev,
1842 */ 1843 */
1843 1844
1844#ifdef WE_EVENT_RTNETLINK 1845#ifdef WE_EVENT_RTNETLINK
1846static struct sk_buff_head wireless_nlevent_queue;
1847
1848static void wireless_nlevent_process(unsigned long data)
1849{
1850 struct sk_buff *skb;
1851
1852 while ((skb = skb_dequeue(&wireless_nlevent_queue)))
1853 netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_ATOMIC);
1854}
1855
1856static DECLARE_TASKLET(wireless_nlevent_tasklet, wireless_nlevent_process, 0);
1857
1845/* ---------------------------------------------------------------- */ 1858/* ---------------------------------------------------------------- */
1846/* 1859/*
1847 * Fill a rtnetlink message with our event data. 1860 * Fill a rtnetlink message with our event data.
@@ -1904,8 +1917,17 @@ static inline void rtmsg_iwinfo(struct net_device * dev,
1904 return; 1917 return;
1905 } 1918 }
1906 NETLINK_CB(skb).dst_group = RTNLGRP_LINK; 1919 NETLINK_CB(skb).dst_group = RTNLGRP_LINK;
1907 netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_ATOMIC); 1920 skb_queue_tail(&wireless_nlevent_queue, skb);
1921 tasklet_schedule(&wireless_nlevent_tasklet);
1922}
1923
1924static int __init wireless_nlevent_init(void)
1925{
1926 skb_queue_head_init(&wireless_nlevent_queue);
1927 return 0;
1908} 1928}
1929
1930subsys_initcall(wireless_nlevent_init);
1909#endif /* WE_EVENT_RTNETLINK */ 1931#endif /* WE_EVENT_RTNETLINK */
1910 1932
1911/* ---------------------------------------------------------------- */ 1933/* ---------------------------------------------------------------- */