aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/netpoll.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/netpoll.c')
-rw-r--r--net/core/netpoll.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a119696d5521..ab3c0c9713b0 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -130,19 +130,20 @@ static int checksum_udp(struct sk_buff *skb, struct udphdr *uh,
130 */ 130 */
131static void poll_napi(struct netpoll *np) 131static void poll_napi(struct netpoll *np)
132{ 132{
133 struct netpoll_info *npinfo = np->dev->npinfo;
133 int budget = 16; 134 int budget = 16;
134 135
135 if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) && 136 if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) &&
136 np->poll_owner != smp_processor_id() && 137 npinfo->poll_owner != smp_processor_id() &&
137 spin_trylock(&np->poll_lock)) { 138 spin_trylock(&npinfo->poll_lock)) {
138 np->rx_flags |= NETPOLL_RX_DROP; 139 npinfo->rx_flags |= NETPOLL_RX_DROP;
139 atomic_inc(&trapped); 140 atomic_inc(&trapped);
140 141
141 np->dev->poll(np->dev, &budget); 142 np->dev->poll(np->dev, &budget);
142 143
143 atomic_dec(&trapped); 144 atomic_dec(&trapped);
144 np->rx_flags &= ~NETPOLL_RX_DROP; 145 npinfo->rx_flags &= ~NETPOLL_RX_DROP;
145 spin_unlock(&np->poll_lock); 146 spin_unlock(&npinfo->poll_lock);
146 } 147 }
147} 148}
148 149
@@ -245,6 +246,7 @@ repeat:
245static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) 246static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
246{ 247{
247 int status; 248 int status;
249 struct netpoll_info *npinfo;
248 250
249repeat: 251repeat:
250 if(!np || !np->dev || !netif_running(np->dev)) { 252 if(!np || !np->dev || !netif_running(np->dev)) {
@@ -253,8 +255,9 @@ repeat:
253 } 255 }
254 256
255 /* avoid recursion */ 257 /* avoid recursion */
256 if(np->poll_owner == smp_processor_id() || 258 npinfo = np->dev->npinfo;
257 np->dev->xmit_lock_owner == smp_processor_id()) { 259 if (npinfo->poll_owner == smp_processor_id() ||
260 np->dev->xmit_lock_owner == smp_processor_id()) {
258 if (np->drop) 261 if (np->drop)
259 np->drop(skb); 262 np->drop(skb);
260 else 263 else
@@ -341,14 +344,18 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
341 344
342static void arp_reply(struct sk_buff *skb) 345static void arp_reply(struct sk_buff *skb)
343{ 346{
347 struct netpoll_info *npinfo = skb->dev->npinfo;
344 struct arphdr *arp; 348 struct arphdr *arp;
345 unsigned char *arp_ptr; 349 unsigned char *arp_ptr;
346 int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; 350 int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
347 u32 sip, tip; 351 u32 sip, tip;
348 struct sk_buff *send_skb; 352 struct sk_buff *send_skb;
349 struct netpoll *np = skb->dev->np; 353 struct netpoll *np = NULL;
350 354
351 if (!np) return; 355 if (npinfo)
356 np = npinfo->np;
357 if (!np)
358 return;
352 359
353 /* No arp on this interface */ 360 /* No arp on this interface */
354 if (skb->dev->flags & IFF_NOARP) 361 if (skb->dev->flags & IFF_NOARP)
@@ -429,7 +436,7 @@ int __netpoll_rx(struct sk_buff *skb)
429 int proto, len, ulen; 436 int proto, len, ulen;
430 struct iphdr *iph; 437 struct iphdr *iph;
431 struct udphdr *uh; 438 struct udphdr *uh;
432 struct netpoll *np = skb->dev->np; 439 struct netpoll *np = skb->dev->npinfo->np;
433 440
434 if (!np->rx_hook) 441 if (!np->rx_hook)
435 goto out; 442 goto out;
@@ -611,9 +618,7 @@ int netpoll_setup(struct netpoll *np)
611{ 618{
612 struct net_device *ndev = NULL; 619 struct net_device *ndev = NULL;
613 struct in_device *in_dev; 620 struct in_device *in_dev;
614 621 struct netpoll_info *npinfo;
615 np->poll_lock = SPIN_LOCK_UNLOCKED;
616 np->poll_owner = -1;
617 622
618 if (np->dev_name) 623 if (np->dev_name)
619 ndev = dev_get_by_name(np->dev_name); 624 ndev = dev_get_by_name(np->dev_name);
@@ -624,7 +629,16 @@ int netpoll_setup(struct netpoll *np)
624 } 629 }
625 630
626 np->dev = ndev; 631 np->dev = ndev;
627 ndev->np = np; 632 if (!ndev->npinfo) {
633 npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL);
634 if (!npinfo)
635 goto release;
636
637 npinfo->np = NULL;
638 npinfo->poll_lock = SPIN_LOCK_UNLOCKED;
639 npinfo->poll_owner = -1;
640 } else
641 npinfo = ndev->npinfo;
628 642
629 if (!ndev->poll_controller) { 643 if (!ndev->poll_controller) {
630 printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", 644 printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
@@ -693,12 +707,15 @@ int netpoll_setup(struct netpoll *np)
693 } 707 }
694 708
695 if(np->rx_hook) 709 if(np->rx_hook)
696 np->rx_flags = NETPOLL_RX_ENABLED; 710 npinfo->rx_flags = NETPOLL_RX_ENABLED;
711 npinfo->np = np;
712 ndev->npinfo = npinfo;
697 713
698 return 0; 714 return 0;
699 715
700 release: 716 release:
701 ndev->np = NULL; 717 if (!ndev->npinfo)
718 kfree(npinfo);
702 np->dev = NULL; 719 np->dev = NULL;
703 dev_put(ndev); 720 dev_put(ndev);
704 return -1; 721 return -1;
@@ -706,9 +723,11 @@ int netpoll_setup(struct netpoll *np)
706 723
707void netpoll_cleanup(struct netpoll *np) 724void netpoll_cleanup(struct netpoll *np)
708{ 725{
709 if (np->dev) 726 if (np->dev) {
710 np->dev->np = NULL; 727 if (np->dev->npinfo)
711 dev_put(np->dev); 728 np->dev->npinfo->np = NULL;
729 dev_put(np->dev);
730 }
712 np->dev = NULL; 731 np->dev = NULL;
713} 732}
714 733