aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
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 /net/core
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 'net/core')
-rw-r--r--net/core/netpoll.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 537e01afd81b..4e98ffac3af0 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -288,11 +288,11 @@ static int netpoll_owner_active(struct net_device *dev)
288 return 0; 288 return 0;
289} 289}
290 290
291void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) 291void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
292 struct net_device *dev)
292{ 293{
293 int status = NETDEV_TX_BUSY; 294 int status = NETDEV_TX_BUSY;
294 unsigned long tries; 295 unsigned long tries;
295 struct net_device *dev = np->dev;
296 const struct net_device_ops *ops = dev->netdev_ops; 296 const struct net_device_ops *ops = dev->netdev_ops;
297 /* It is up to the caller to keep npinfo alive. */ 297 /* It is up to the caller to keep npinfo alive. */
298 struct netpoll_info *npinfo = np->dev->npinfo; 298 struct netpoll_info *npinfo = np->dev->npinfo;
@@ -346,7 +346,7 @@ void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
346 schedule_delayed_work(&npinfo->tx_work,0); 346 schedule_delayed_work(&npinfo->tx_work,0);
347 } 347 }
348} 348}
349EXPORT_SYMBOL(netpoll_send_skb); 349EXPORT_SYMBOL(netpoll_send_skb_on_dev);
350 350
351void netpoll_send_udp(struct netpoll *np, const char *msg, int len) 351void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
352{ 352{