aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/netpoll.h
diff options
context:
space:
mode:
authorNeil Horman <nhorman@tuxdriver.com>2010-10-13 12:01:49 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-18 11:32:07 -0400
commitc2355e1ab910278a94d487b78590ee3c8eecd08a (patch)
tree6a3adce66355ad36483500475f9931d0e359695e /include/linux/netpoll.h
parentc6ce3854f098e1307ecd3bde07903d65fb14a9cb (diff)
bonding: Fix bonding drivers improper modification of netpoll structure
The bonding driver currently modifies the netpoll structure in its xmit path while sending frames from netpoll. This is racy, as other cpus can access the netpoll structure in parallel. Since the bonding driver points np->dev to a slave device, other cpus can inadvertently attempt to send data directly to slave devices, leading to improper locking with the bonding master, lost frames, and deadlocks. This patch fixes that up. This patch also removes the real_dev pointer from the netpoll structure as that data is really only used by bonding in the poll_controller, and we can emulate its behavior by check each slave for IS_UP. Signed-off-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/netpoll.h')
-rw-r--r--include/linux/netpoll.h9
1 files changed, 7 insertions, 2 deletions
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index 50d8009be86c..79358bb712c6 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -14,7 +14,6 @@
14 14
15struct netpoll { 15struct netpoll {
16 struct net_device *dev; 16 struct net_device *dev;
17 struct net_device *real_dev;
18 char dev_name[IFNAMSIZ]; 17 char dev_name[IFNAMSIZ];
19 const char *name; 18 const char *name;
20 void (*rx_hook)(struct netpoll *, int, char *, int); 19 void (*rx_hook)(struct netpoll *, int, char *, int);
@@ -53,7 +52,13 @@ void netpoll_set_trap(int trap);
53void __netpoll_cleanup(struct netpoll *np); 52void __netpoll_cleanup(struct netpoll *np);
54void netpoll_cleanup(struct netpoll *np); 53void netpoll_cleanup(struct netpoll *np);
55int __netpoll_rx(struct sk_buff *skb); 54int __netpoll_rx(struct sk_buff *skb);
56void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb); 55void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
56 struct net_device *dev);
57static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
58{
59 netpoll_send_skb_on_dev(np, skb, np->dev);
60}
61
57 62
58 63
59#ifdef CONFIG_NETPOLL 64#ifdef CONFIG_NETPOLL