diff options
Diffstat (limited to 'include/linux/netpoll.h')
-rw-r--r-- | include/linux/netpoll.h | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 28f5389c924b..66d5379c305e 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h | |||
@@ -23,6 +23,7 @@ struct netpoll { | |||
23 | u8 remote_mac[ETH_ALEN]; | 23 | u8 remote_mac[ETH_ALEN]; |
24 | 24 | ||
25 | struct list_head rx; /* rx_np list element */ | 25 | struct list_head rx; /* rx_np list element */ |
26 | struct rcu_head rcu; | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | struct netpoll_info { | 29 | struct netpoll_info { |
@@ -38,28 +39,40 @@ struct netpoll_info { | |||
38 | struct delayed_work tx_work; | 39 | struct delayed_work tx_work; |
39 | 40 | ||
40 | struct netpoll *netpoll; | 41 | struct netpoll *netpoll; |
42 | struct rcu_head rcu; | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | void netpoll_send_udp(struct netpoll *np, const char *msg, int len); | 45 | void netpoll_send_udp(struct netpoll *np, const char *msg, int len); |
44 | void netpoll_print_options(struct netpoll *np); | 46 | void netpoll_print_options(struct netpoll *np); |
45 | int netpoll_parse_options(struct netpoll *np, char *opt); | 47 | int netpoll_parse_options(struct netpoll *np, char *opt); |
46 | int __netpoll_setup(struct netpoll *np, struct net_device *ndev); | 48 | int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp); |
47 | int netpoll_setup(struct netpoll *np); | 49 | int netpoll_setup(struct netpoll *np); |
48 | int netpoll_trap(void); | 50 | int netpoll_trap(void); |
49 | void netpoll_set_trap(int trap); | 51 | void netpoll_set_trap(int trap); |
50 | void __netpoll_cleanup(struct netpoll *np); | 52 | void __netpoll_cleanup(struct netpoll *np); |
53 | void __netpoll_free_rcu(struct netpoll *np); | ||
51 | void netpoll_cleanup(struct netpoll *np); | 54 | void netpoll_cleanup(struct netpoll *np); |
52 | int __netpoll_rx(struct sk_buff *skb); | 55 | int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo); |
53 | void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | 56 | void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, |
54 | struct net_device *dev); | 57 | struct net_device *dev); |
55 | static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) | 58 | static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) |
56 | { | 59 | { |
60 | unsigned long flags; | ||
61 | local_irq_save(flags); | ||
57 | netpoll_send_skb_on_dev(np, skb, np->dev); | 62 | netpoll_send_skb_on_dev(np, skb, np->dev); |
63 | local_irq_restore(flags); | ||
58 | } | 64 | } |
59 | 65 | ||
60 | 66 | ||
61 | 67 | ||
62 | #ifdef CONFIG_NETPOLL | 68 | #ifdef CONFIG_NETPOLL |
69 | static inline bool netpoll_rx_on(struct sk_buff *skb) | ||
70 | { | ||
71 | struct netpoll_info *npinfo = rcu_dereference_bh(skb->dev->npinfo); | ||
72 | |||
73 | return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags); | ||
74 | } | ||
75 | |||
63 | static inline bool netpoll_rx(struct sk_buff *skb) | 76 | static inline bool netpoll_rx(struct sk_buff *skb) |
64 | { | 77 | { |
65 | struct netpoll_info *npinfo; | 78 | struct netpoll_info *npinfo; |
@@ -67,14 +80,14 @@ static inline bool netpoll_rx(struct sk_buff *skb) | |||
67 | bool ret = false; | 80 | bool ret = false; |
68 | 81 | ||
69 | local_irq_save(flags); | 82 | local_irq_save(flags); |
70 | npinfo = rcu_dereference_bh(skb->dev->npinfo); | ||
71 | 83 | ||
72 | if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags)) | 84 | if (!netpoll_rx_on(skb)) |
73 | goto out; | 85 | goto out; |
74 | 86 | ||
87 | npinfo = rcu_dereference_bh(skb->dev->npinfo); | ||
75 | spin_lock(&npinfo->rx_lock); | 88 | spin_lock(&npinfo->rx_lock); |
76 | /* check rx_flags again with the lock held */ | 89 | /* check rx_flags again with the lock held */ |
77 | if (npinfo->rx_flags && __netpoll_rx(skb)) | 90 | if (npinfo->rx_flags && __netpoll_rx(skb, npinfo)) |
78 | ret = true; | 91 | ret = true; |
79 | spin_unlock(&npinfo->rx_lock); | 92 | spin_unlock(&npinfo->rx_lock); |
80 | 93 | ||
@@ -83,13 +96,6 @@ out: | |||
83 | return ret; | 96 | return ret; |
84 | } | 97 | } |
85 | 98 | ||
86 | static inline int netpoll_rx_on(struct sk_buff *skb) | ||
87 | { | ||
88 | struct netpoll_info *npinfo = rcu_dereference_bh(skb->dev->npinfo); | ||
89 | |||
90 | return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags); | ||
91 | } | ||
92 | |||
93 | static inline int netpoll_receive_skb(struct sk_buff *skb) | 99 | static inline int netpoll_receive_skb(struct sk_buff *skb) |
94 | { | 100 | { |
95 | if (!list_empty(&skb->dev->napi_list)) | 101 | if (!list_empty(&skb->dev->napi_list)) |
@@ -119,7 +125,7 @@ static inline void netpoll_poll_unlock(void *have) | |||
119 | } | 125 | } |
120 | } | 126 | } |
121 | 127 | ||
122 | static inline int netpoll_tx_running(struct net_device *dev) | 128 | static inline bool netpoll_tx_running(struct net_device *dev) |
123 | { | 129 | { |
124 | return irqs_disabled(); | 130 | return irqs_disabled(); |
125 | } | 131 | } |
@@ -127,11 +133,11 @@ static inline int netpoll_tx_running(struct net_device *dev) | |||
127 | #else | 133 | #else |
128 | static inline bool netpoll_rx(struct sk_buff *skb) | 134 | static inline bool netpoll_rx(struct sk_buff *skb) |
129 | { | 135 | { |
130 | return 0; | 136 | return false; |
131 | } | 137 | } |
132 | static inline int netpoll_rx_on(struct sk_buff *skb) | 138 | static inline bool netpoll_rx_on(struct sk_buff *skb) |
133 | { | 139 | { |
134 | return 0; | 140 | return false; |
135 | } | 141 | } |
136 | static inline int netpoll_receive_skb(struct sk_buff *skb) | 142 | static inline int netpoll_receive_skb(struct sk_buff *skb) |
137 | { | 143 | { |
@@ -147,9 +153,9 @@ static inline void netpoll_poll_unlock(void *have) | |||
147 | static inline void netpoll_netdev_init(struct net_device *dev) | 153 | static inline void netpoll_netdev_init(struct net_device *dev) |
148 | { | 154 | { |
149 | } | 155 | } |
150 | static inline int netpoll_tx_running(struct net_device *dev) | 156 | static inline bool netpoll_tx_running(struct net_device *dev) |
151 | { | 157 | { |
152 | return 0; | 158 | return false; |
153 | } | 159 | } |
154 | #endif | 160 | #endif |
155 | 161 | ||