Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 2834
b: refs/heads/master
c: fbeec2e
h: refs/heads/master
v: v3
  • Loading branch information
Jeff Moyer authored and David S. Miller committed Jun 23, 2005
1 parent 11a159e commit 5746914
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 115c1d6e61b70851d9a363328c3b8d4c2559a1d3
refs/heads/master: fbeec2e1552949002065435c9829dc244ad85407
15 changes: 12 additions & 3 deletions trunk/include/linux/netpoll.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ struct netpoll_info {
spinlock_t poll_lock;
int poll_owner;
int rx_flags;
struct netpoll *np;
spinlock_t rx_lock;
struct netpoll *rx_np; /* netpoll that registered an rx_hook */
};

void netpoll_poll(struct netpoll *np);
Expand All @@ -44,11 +45,19 @@ void netpoll_queue(struct sk_buff *skb);
static inline int netpoll_rx(struct sk_buff *skb)
{
struct netpoll_info *npinfo = skb->dev->npinfo;
unsigned long flags;
int ret = 0;

if (!npinfo || !npinfo->rx_flags)
if (!npinfo || (!npinfo->rx_np && !npinfo->rx_flags))
return 0;

return npinfo->np && __netpoll_rx(skb);
spin_lock_irqsave(&npinfo->rx_lock, flags);
/* check rx_flags again with the lock held */
if (npinfo->rx_flags && __netpoll_rx(skb))
ret = 1;
spin_unlock_irqrestore(&npinfo->rx_lock, flags);

return ret;
}

static inline void netpoll_poll_lock(struct net_device *dev)
Expand Down
39 changes: 29 additions & 10 deletions trunk/net/core/netpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,11 +349,15 @@ static void arp_reply(struct sk_buff *skb)
unsigned char *arp_ptr;
int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
u32 sip, tip;
unsigned long flags;
struct sk_buff *send_skb;
struct netpoll *np = NULL;

if (npinfo)
np = npinfo->np;
spin_lock_irqsave(&npinfo->rx_lock, flags);
if (npinfo->rx_np && npinfo->rx_np->dev == skb->dev)
np = npinfo->rx_np;
spin_unlock_irqrestore(&npinfo->rx_lock, flags);

if (!np)
return;

Expand Down Expand Up @@ -436,9 +440,9 @@ int __netpoll_rx(struct sk_buff *skb)
int proto, len, ulen;
struct iphdr *iph;
struct udphdr *uh;
struct netpoll *np = skb->dev->npinfo->np;
struct netpoll *np = skb->dev->npinfo->rx_np;

if (!np->rx_hook)
if (!np)
goto out;
if (skb->dev->type != ARPHRD_ETHER)
goto out;
Expand Down Expand Up @@ -619,6 +623,7 @@ int netpoll_setup(struct netpoll *np)
struct net_device *ndev = NULL;
struct in_device *in_dev;
struct netpoll_info *npinfo;
unsigned long flags;

if (np->dev_name)
ndev = dev_get_by_name(np->dev_name);
Expand All @@ -634,9 +639,10 @@ int netpoll_setup(struct netpoll *np)
if (!npinfo)
goto release;

npinfo->np = NULL;
npinfo->rx_np = NULL;
npinfo->poll_lock = SPIN_LOCK_UNLOCKED;
npinfo->poll_owner = -1;
npinfo->rx_lock = SPIN_LOCK_UNLOCKED;
} else
npinfo = ndev->npinfo;

Expand Down Expand Up @@ -706,9 +712,13 @@ int netpoll_setup(struct netpoll *np)
np->name, HIPQUAD(np->local_ip));
}

if(np->rx_hook)
npinfo->rx_flags = NETPOLL_RX_ENABLED;
npinfo->np = np;
if (np->rx_hook) {
spin_lock_irqsave(&npinfo->rx_lock, flags);
npinfo->rx_flags |= NETPOLL_RX_ENABLED;
npinfo->rx_np = np;
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
}
/* last thing to do is link it to the net device structure */
ndev->npinfo = npinfo;

return 0;
Expand All @@ -723,11 +733,20 @@ int netpoll_setup(struct netpoll *np)

void netpoll_cleanup(struct netpoll *np)
{
struct netpoll_info *npinfo;
unsigned long flags;

if (np->dev) {
if (np->dev->npinfo)
np->dev->npinfo->np = NULL;
npinfo = np->dev->npinfo;
if (npinfo && npinfo->rx_np == np) {
spin_lock_irqsave(&npinfo->rx_lock, flags);
npinfo->rx_np = NULL;
npinfo->rx_flags &= ~NETPOLL_RX_ENABLED;
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
}
dev_put(np->dev);
}

np->dev = NULL;
}

Expand Down

0 comments on commit 5746914

Please sign in to comment.