aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/netpoll.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/netpoll.h')
-rw-r--r--include/linux/netpoll.h52
1 files changed, 38 insertions, 14 deletions
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index 2524267210d3..50d8009be86c 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -14,6 +14,7 @@
14 14
15struct netpoll { 15struct netpoll {
16 struct net_device *dev; 16 struct net_device *dev;
17 struct net_device *real_dev;
17 char dev_name[IFNAMSIZ]; 18 char dev_name[IFNAMSIZ];
18 const char *name; 19 const char *name;
19 void (*rx_hook)(struct netpoll *, int, char *, int); 20 void (*rx_hook)(struct netpoll *, int, char *, int);
@@ -21,53 +22,69 @@ struct netpoll {
21 __be32 local_ip, remote_ip; 22 __be32 local_ip, remote_ip;
22 u16 local_port, remote_port; 23 u16 local_port, remote_port;
23 u8 remote_mac[ETH_ALEN]; 24 u8 remote_mac[ETH_ALEN];
25
26 struct list_head rx; /* rx_np list element */
24}; 27};
25 28
26struct netpoll_info { 29struct netpoll_info {
27 atomic_t refcnt; 30 atomic_t refcnt;
31
28 int rx_flags; 32 int rx_flags;
29 spinlock_t rx_lock; 33 spinlock_t rx_lock;
30 struct netpoll *rx_np; /* netpoll that registered an rx_hook */ 34 struct list_head rx_np; /* netpolls that registered an rx_hook */
35
31 struct sk_buff_head arp_tx; /* list of arp requests to reply to */ 36 struct sk_buff_head arp_tx; /* list of arp requests to reply to */
32 struct sk_buff_head txq; 37 struct sk_buff_head txq;
38
33 struct delayed_work tx_work; 39 struct delayed_work tx_work;
40
41 struct netpoll *netpoll;
34}; 42};
35 43
44void netpoll_poll_dev(struct net_device *dev);
36void netpoll_poll(struct netpoll *np); 45void netpoll_poll(struct netpoll *np);
37void netpoll_send_udp(struct netpoll *np, const char *msg, int len); 46void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
38void netpoll_print_options(struct netpoll *np); 47void netpoll_print_options(struct netpoll *np);
39int netpoll_parse_options(struct netpoll *np, char *opt); 48int netpoll_parse_options(struct netpoll *np, char *opt);
49int __netpoll_setup(struct netpoll *np);
40int netpoll_setup(struct netpoll *np); 50int netpoll_setup(struct netpoll *np);
41int netpoll_trap(void); 51int netpoll_trap(void);
42void netpoll_set_trap(int trap); 52void netpoll_set_trap(int trap);
53void __netpoll_cleanup(struct netpoll *np);
43void netpoll_cleanup(struct netpoll *np); 54void netpoll_cleanup(struct netpoll *np);
44int __netpoll_rx(struct sk_buff *skb); 55int __netpoll_rx(struct sk_buff *skb);
56void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);
45 57
46 58
47#ifdef CONFIG_NETPOLL 59#ifdef CONFIG_NETPOLL
48static inline int netpoll_rx(struct sk_buff *skb) 60static inline bool netpoll_rx(struct sk_buff *skb)
49{ 61{
50 struct netpoll_info *npinfo = skb->dev->npinfo; 62 struct netpoll_info *npinfo;
51 unsigned long flags; 63 unsigned long flags;
52 int ret = 0; 64 bool ret = false;
65
66 local_irq_save(flags);
67 npinfo = rcu_dereference_bh(skb->dev->npinfo);
53 68
54 if (!npinfo || (!npinfo->rx_np && !npinfo->rx_flags)) 69 if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags))
55 return 0; 70 goto out;
56 71
57 spin_lock_irqsave(&npinfo->rx_lock, flags); 72 spin_lock(&npinfo->rx_lock);
58 /* check rx_flags again with the lock held */ 73 /* check rx_flags again with the lock held */
59 if (npinfo->rx_flags && __netpoll_rx(skb)) 74 if (npinfo->rx_flags && __netpoll_rx(skb))
60 ret = 1; 75 ret = true;
61 spin_unlock_irqrestore(&npinfo->rx_lock, flags); 76 spin_unlock(&npinfo->rx_lock);
62 77
78out:
79 local_irq_restore(flags);
63 return ret; 80 return ret;
64} 81}
65 82
66static inline int netpoll_rx_on(struct sk_buff *skb) 83static inline int netpoll_rx_on(struct sk_buff *skb)
67{ 84{
68 struct netpoll_info *npinfo = skb->dev->npinfo; 85 struct netpoll_info *npinfo = rcu_dereference_bh(skb->dev->npinfo);
69 86
70 return npinfo && (npinfo->rx_np || npinfo->rx_flags); 87 return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags);
71} 88}
72 89
73static inline int netpoll_receive_skb(struct sk_buff *skb) 90static inline int netpoll_receive_skb(struct sk_buff *skb)
@@ -81,7 +98,6 @@ static inline void *netpoll_poll_lock(struct napi_struct *napi)
81{ 98{
82 struct net_device *dev = napi->dev; 99 struct net_device *dev = napi->dev;
83 100
84 rcu_read_lock(); /* deal with race on ->npinfo */
85 if (dev && dev->npinfo) { 101 if (dev && dev->npinfo) {
86 spin_lock(&napi->poll_lock); 102 spin_lock(&napi->poll_lock);
87 napi->poll_owner = smp_processor_id(); 103 napi->poll_owner = smp_processor_id();
@@ -98,11 +114,15 @@ static inline void netpoll_poll_unlock(void *have)
98 napi->poll_owner = -1; 114 napi->poll_owner = -1;
99 spin_unlock(&napi->poll_lock); 115 spin_unlock(&napi->poll_lock);
100 } 116 }
101 rcu_read_unlock(); 117}
118
119static inline int netpoll_tx_running(struct net_device *dev)
120{
121 return irqs_disabled();
102} 122}
103 123
104#else 124#else
105static inline int netpoll_rx(struct sk_buff *skb) 125static inline bool netpoll_rx(struct sk_buff *skb)
106{ 126{
107 return 0; 127 return 0;
108} 128}
@@ -124,6 +144,10 @@ static inline void netpoll_poll_unlock(void *have)
124static inline void netpoll_netdev_init(struct net_device *dev) 144static inline void netpoll_netdev_init(struct net_device *dev)
125{ 145{
126} 146}
147static inline int netpoll_tx_running(struct net_device *dev)
148{
149 return 0;
150}
127#endif 151#endif
128 152
129#endif 153#endif