1 l-mpm/arch/i386/kernel/irq.c | 15
2 l-mpm/include/asm-i386/irq.h | 1
3 l-mpm/include/linux/netdevice.h | 22 -
4 l-mpm/include/linux/netpoll.h | 37 ++
6 l-mpm/net/core/Makefile | 1
7 l-mpm/net/core/dev.c | 22 -
8 l-mpm/net/core/netpoll.c | 632 ++++++++++++++++++++++++++++++++++++++++
9 8 files changed, 707 insertions(+), 26 deletions(-)
11 Index: linux-2.6.0-test6/net/core/netpoll.c
12 ===================================================================
13 --- linux-2.6.0-test6.orig/net/core/netpoll.c 2003-10-07 16:08:51.000000000 +0800
14 +++ linux-2.6.0-test6/net/core/netpoll.c 2003-10-09 20:40:07.769057232 +0800
17 + * Common framework for low-level network console, dump, and debugger code
19 + * Sep 8 2003 Matt Mackall <mpm@selenic.com>
22 +#include <linux/smp_lock.h>
23 +#include <linux/netdevice.h>
24 +#include <linux/etherdevice.h>
25 +#include <linux/string.h>
26 +#include <linux/inetdevice.h>
27 +#include <linux/inet.h>
28 +#include <linux/interrupt.h>
29 +#include <linux/netpoll.h>
30 +#include <linux/sched.h>
35 + * We maintain a small pool of fully-sized skbs, to make sure the
36 + * message gets out even in extreme OOM situations.
40 +#define MAX_UDP_CHUNK 1460
42 +static spinlock_t skb_list_lock = SPIN_LOCK_UNLOCKED;
44 +static struct sk_buff *skbs;
46 +static spinlock_t rx_list_lock = SPIN_LOCK_UNLOCKED;
47 +static LIST_HEAD(rx_list);
51 +#define MAX_SKB_SIZE \
52 + (MAX_UDP_CHUNK + sizeof(struct udphdr) + \
53 + sizeof(struct iphdr) + sizeof(struct ethhdr))
55 +static int checksum_udp(struct sk_buff *skb, struct udphdr *uh,
56 + unsigned short ulen, u32 saddr, u32 daddr)
61 + if (skb->ip_summed == CHECKSUM_HW)
62 + return csum_tcpudp_magic(
63 + saddr, daddr, ulen, IPPROTO_UDP, skb->csum);
65 + skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
67 + return csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
70 +void netpoll_poll(struct netpoll *np)
74 + if(!np || !np->dev || !(np->dev->flags & IFF_UP))
77 + disable_irq(np->dev->irq);
79 + /* Process pending work on NIC */
80 + np->irqfunc(np->dev->irq, np->dev, 0);
82 + /* If scheduling is stopped, tickle NAPI bits */
83 + if(trapped && np->dev->poll &&
84 + test_bit(__LINK_STATE_RX_SCHED, &np->dev->state))
85 + np->dev->poll(np->dev, &budget);
87 + enable_irq(np->dev->irq);
90 +static void refill_skbs(void)
92 + struct sk_buff *skb;
93 + unsigned long flags;
95 + spin_lock_irqsave(&skb_list_lock, flags);
96 + while (nr_skbs < MAX_SKBS) {
97 + skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC);
105 + spin_unlock_irqrestore(&skb_list_lock, flags);
108 +static void zap_completion_queue(void)
110 + unsigned long flags;
111 + struct softnet_data *sd = &get_cpu_var(softnet_data);
113 + if (sd->completion_queue) {
114 + struct sk_buff *clist;
116 + local_irq_save(flags);
117 + clist = sd->completion_queue;
118 + sd->completion_queue = NULL;
119 + local_irq_restore(flags);
121 + while (clist != NULL) {
122 + struct sk_buff *skb = clist;
123 + clist = clist->next;
128 + put_cpu_var(softnet_data);
131 +static struct sk_buff * find_skb(struct netpoll *np, int len, int reserve)
133 + int once = 1, count = 0;
134 + unsigned long flags;
135 + struct sk_buff *skb = NULL;
138 + zap_completion_queue();
139 + if (nr_skbs < MAX_SKBS)
142 + skb = alloc_skb(len, GFP_ATOMIC);
145 + spin_lock_irqsave(&skb_list_lock, flags);
151 + spin_unlock_irqrestore(&skb_list_lock, flags);
156 + if (once && (count == 1000000)) {
157 + printk("out of netpoll skbs!\n");
164 + atomic_set(&skb->users, 1);
165 + skb_reserve(skb, reserve);
169 +void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
174 + if(!np || !np->dev || !(np->dev->flags & IFF_UP)) {
179 + spin_lock(&np->dev->xmit_lock);
180 + np->dev->xmit_lock_owner = smp_processor_id();
182 + if (netif_queue_stopped(np->dev)) {
183 + np->dev->xmit_lock_owner = -1;
184 + spin_unlock(&np->dev->xmit_lock);
187 + zap_completion_queue();
191 + status = np->dev->hard_start_xmit(skb, np->dev);
192 + np->dev->xmit_lock_owner = -1;
193 + spin_unlock(&np->dev->xmit_lock);
195 + /* transmit busy */
200 +void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
202 + int total_len, eth_len, ip_len, udp_len;
203 + struct sk_buff *skb;
204 + struct udphdr *udph;
206 + struct ethhdr *eth;
208 + udp_len = len + sizeof(*udph);
209 + ip_len = eth_len = udp_len + sizeof(*iph);
210 + total_len = eth_len + ETH_HLEN;
212 + skb = find_skb(np, total_len, total_len - len);
216 + memcpy(skb->data, msg, len);
219 + udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
220 + udph->source = htons(np->local_port);
221 + udph->dest = htons(np->remote_port);
222 + udph->len = htons(udp_len);
225 + iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
230 + iph->tot_len = htons(ip_len);
234 + iph->protocol = IPPROTO_UDP;
236 + iph->saddr = htonl(np->local_ip);
237 + iph->daddr = htonl(np->remote_ip);
238 + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
240 + eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
242 + eth->h_proto = htons(ETH_P_IP);
243 + memcpy(eth->h_source, np->local_mac, 6);
244 + memcpy(eth->h_dest, np->remote_mac, 6);
246 + netpoll_send_skb(np, skb);
249 +static void arp_reply(struct sk_buff *skb)
251 + struct in_device *in_dev = (struct in_device *) skb->dev->ip_ptr;
252 + struct arphdr *arp;
253 + unsigned char *arp_ptr, *sha, *tha;
254 + int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
256 + struct sk_buff *send_skb;
257 + unsigned long flags;
258 + struct list_head *p;
259 + struct netpoll *np = 0;
261 + spin_lock_irqsave(&rx_list_lock, flags);
262 + list_for_each(p, &rx_list) {
263 + np = list_entry(p, struct netpoll, rx_list);
264 + if ( np->dev == skb->dev )
268 + spin_unlock_irqrestore(&rx_list_lock, flags);
272 + /* No arp on this interface */
273 + if (!in_dev || skb->dev->flags & IFF_NOARP)
276 + if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
277 + (2 * skb->dev->addr_len) +
278 + (2 * sizeof(u32)))))
281 + skb->h.raw = skb->nh.raw = skb->data;
282 + arp = skb->nh.arph;
284 + if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
285 + arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
286 + arp->ar_pro != htons(ETH_P_IP) ||
287 + arp->ar_op != htons(ARPOP_REQUEST))
290 + arp_ptr= (unsigned char *)(arp+1);
292 + arp_ptr += skb->dev->addr_len;
293 + memcpy(&sip, arp_ptr, 4);
296 + arp_ptr += skb->dev->addr_len;
297 + memcpy(&tip, arp_ptr, 4);
299 + /* Should we ignore arp? */
300 + if (tip != in_dev->ifa_list->ifa_address ||
301 + LOOPBACK(tip) || MULTICAST(tip))
305 + size = sizeof(struct arphdr) + 2 * (skb->dev->addr_len + 4);
306 + send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev),
307 + LL_RESERVED_SPACE(np->dev));
312 + send_skb->nh.raw = send_skb->data;
313 + arp = (struct arphdr *) skb_put(send_skb, size);
314 + send_skb->dev = skb->dev;
315 + send_skb->protocol = htons(ETH_P_ARP);
317 + /* Fill the device header for the ARP frame */
319 + if (np->dev->hard_header &&
320 + np->dev->hard_header(send_skb, skb->dev, ptype,
321 + np->remote_mac, np->local_mac,
322 + send_skb->len) < 0) {
323 + kfree_skb(send_skb);
328 + * Fill out the arp protocol part.
330 + * we only support ethernet device type,
331 + * which (according to RFC 1390) should always equal 1 (Ethernet).
334 + arp->ar_hrd = htons(np->dev->type);
335 + arp->ar_pro = htons(ETH_P_IP);
336 + arp->ar_hln = np->dev->addr_len;
338 + arp->ar_op = htons(type);
340 + arp_ptr=(unsigned char *)(arp + 1);
341 + memcpy(arp_ptr, np->dev->dev_addr, np->dev->addr_len);
342 + arp_ptr += np->dev->addr_len;
343 + memcpy(arp_ptr, &tip, 4);
345 + memcpy(arp_ptr, np->local_mac, np->dev->addr_len);
346 + arp_ptr += np->dev->addr_len;
347 + memcpy(arp_ptr, &sip, 4);
349 + netpoll_send_skb(np, send_skb);
352 +static int rx_hook(struct sk_buff *skb)
354 + int proto, len, ulen;
357 + struct netpoll *np;
358 + struct list_head *p;
359 + unsigned long flags;
360 + int rx_hook_called = 0;
362 + if (skb->dev->type != ARPHRD_ETHER)
365 + /* check if netpoll clients need ARP */
366 + if (skb->protocol == __constant_htons(ETH_P_ARP) && trapped) {
371 + proto = ntohs(skb->mac.ethernet->h_proto);
372 + if (proto != ETH_P_IP)
374 + if (skb->pkt_type == PACKET_OTHERHOST)
376 + if (skb_shared(skb))
379 + iph = (struct iphdr *)skb->data;
380 + if (!pskb_may_pull(skb, sizeof(struct iphdr)))
382 + if (iph->ihl < 5 || iph->version != 4)
384 + if (!pskb_may_pull(skb, iph->ihl*4))
386 + if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
389 + len = ntohs(iph->tot_len);
390 + if (skb->len < len || len < iph->ihl*4)
393 + if (iph->protocol != IPPROTO_UDP)
397 + uh = (struct udphdr *)(((char *)iph) + iph->ihl*4);
398 + ulen = ntohs(uh->len);
402 + if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr) < 0)
405 + spin_lock_irqsave(&rx_list_lock, flags);
406 + list_for_each(p, &rx_list) {
407 + np = list_entry(p, struct netpoll, rx_list);
408 + if (np->dev && np->dev != skb->dev)
410 + if (np->local_ip && np->local_ip != ntohl(iph->daddr))
412 + if (np->remote_ip && np->remote_ip != ntohl(iph->saddr))
414 + if (np->local_port && np->local_port != ntohs(uh->dest))
418 + np->rx_hook(np, ntohs(uh->source),
419 + (char *)(uh+1), ulen-sizeof(uh)-4);
420 + rx_hook_called = 1;
423 + spin_unlock_irqrestore(&rx_list_lock, flags);
425 + if (rx_hook_called)
431 +int netpoll_parse_options(struct netpoll *np, char *opt)
433 + char *cur=opt, *delim;
436 + if ((delim = strchr(cur, '@')) == NULL)
439 + np->local_port=simple_strtol(cur, 0, 10);
443 + printk(KERN_INFO "%s: local port %d\n", np->name, np->local_port);
446 + if ((delim = strchr(cur, '/')) == NULL)
449 + np->local_ip=ntohl(in_aton(cur));
452 + printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
453 + np->name, HIPQUAD(np->local_ip));
457 + if ( *cur != ',') {
458 + /* parse out dev name */
459 + if ((delim = strchr(cur, ',')) == NULL)
462 + strlcpy(np->dev_name, cur, sizeof(np->dev_name));
467 + printk(KERN_INFO "%s: interface %s\n", np->name, np->dev_name);
469 + if ( *cur != '@' ) {
471 + if ((delim = strchr(cur, '@')) == NULL)
474 + np->remote_port=simple_strtol(cur, 0, 10);
478 + printk(KERN_INFO "%s: remote port %d\n", np->name, np->remote_port);
481 + if ((delim = strchr(cur, '/')) == NULL)
484 + np->remote_ip=ntohl(in_aton(cur));
487 + printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n",
488 + np->name, HIPQUAD(np->remote_ip));
493 + if ((delim = strchr(cur, ':')) == NULL)
496 + np->remote_mac[0]=simple_strtol(cur, 0, 16);
498 + if ((delim = strchr(cur, ':')) == NULL)
501 + np->remote_mac[1]=simple_strtol(cur, 0, 16);
503 + if ((delim = strchr(cur, ':')) == NULL)
506 + np->remote_mac[2]=simple_strtol(cur, 0, 16);
508 + if ((delim = strchr(cur, ':')) == NULL)
511 + np->remote_mac[3]=simple_strtol(cur, 0, 16);
513 + if ((delim = strchr(cur, ':')) == NULL)
516 + np->remote_mac[4]=simple_strtol(cur, 0, 16);
518 + np->remote_mac[5]=simple_strtol(cur, 0, 16);
521 + printk(KERN_INFO "%s: remote ethernet address "
522 + "%02x:%02x:%02x:%02x:%02x:%02x\n",
529 + np->remote_mac[5]);
534 + printk(KERN_INFO "%s: couldn't parse config at %s!\n",
539 +int netpoll_setup(struct netpoll *np)
541 + struct net_device *ndev = NULL;
542 + struct in_device *in_dev;
543 + struct irqaction *a;
546 + ndev = dev_get_by_name(np->dev_name);
548 + printk(KERN_ERR "%s: %s doesn't exist, aborting.\n",
549 + np->name, np->dev_name);
553 + if (!(ndev->flags & IFF_UP)) {
554 + unsigned short oflags;
555 + unsigned long jiff;
557 + printk(KERN_INFO "%s: device %s not up yet, forcing it\n",
558 + np->name, np->dev_name);
560 + oflags = ndev->flags;
563 + if (dev_change_flags(ndev, oflags | IFF_UP) < 0) {
564 + printk(KERN_ERR "%s: failed to open %s\n",
565 + np->name, np->dev_name);
571 + jiff = jiffies + 6*HZ;
572 + while(!netif_carrier_ok(ndev)) {
573 + if (!time_before(jiffies, jiff)) {
575 + "%s: timeout waiting for carrier\n",
584 + if (!memcmp(np->local_mac, "\0\0\0\0\0\0", 6) && ndev->dev_addr)
585 + memcpy(np->local_mac, ndev->dev_addr, 6);
589 + in_dev = in_dev_get(ndev);
592 + printk(KERN_ERR "%s: no IP address for %s, aborting\n",
593 + np->name, np->dev_name);
597 + np->local_ip = ntohl(in_dev->ifa_list->ifa_local);
598 + in_dev_put(in_dev);
599 + printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
600 + np->name, HIPQUAD(np->local_ip));
603 + a=find_irq_action(ndev->irq, ndev);
605 + printk(KERN_ERR "%s: couldn't find irq handler for %s, "
606 + "aborting\n", np->name, np->dev_name);
610 + np->irqfunc = a->handler;
614 + unsigned long flags;
616 + np->dev->rx_hook = rx_hook;
618 + spin_lock_irqsave(&rx_list_lock, flags);
619 + list_add(&np->rx_list, &rx_list);
620 + spin_unlock_irqrestore(&rx_list_lock, flags);
626 +void netpoll_cleanup(struct netpoll *np)
629 + unsigned long flags;
631 + spin_lock_irqsave(&rx_list_lock, flags);
632 + list_del(&np->rx_list);
633 + np->dev->rx_hook = 0;
634 + spin_unlock_irqrestore(&rx_list_lock, flags);
645 +void netpoll_set_trap(int trap)
649 Index: linux-2.6.0-test6/include/linux/netpoll.h
650 ===================================================================
651 --- linux-2.6.0-test6.orig/include/linux/netpoll.h 2003-10-07 16:08:51.000000000 +0800
652 +++ linux-2.6.0-test6/include/linux/netpoll.h 2003-10-07 16:08:51.000000000 +0800
655 + * Common code for low-level network console, dump, and debugger code
657 + * Derived from netconsole, kgdb-over-ethernet, and netdump patches
660 +#ifndef _LINUX_NETPOLL_H
661 +#define _LINUX_NETPOLL_H
663 +#include <linux/netdevice.h>
664 +#include <linux/irq.h>
665 +#include <linux/list.h>
670 + struct net_device *dev;
671 + char dev_name[16], *name;
672 + irqreturn_t (*irqfunc)(int, void *, struct pt_regs *);
673 + void (*rx_hook)(struct netpoll *, int, char *, int);
674 + u32 local_ip, remote_ip;
675 + u16 local_port, remote_port;
676 + unsigned char local_mac[6], remote_mac[6];
677 + struct list_head rx_list;
680 +void netpoll_poll(struct netpoll *np);
681 +void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);
682 +void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
683 +int netpoll_parse_options(struct netpoll *np, char *opt);
684 +int netpoll_setup(struct netpoll *np);
685 +int netpoll_trap(void);
686 +void netpoll_set_trap(int trap);
687 +void netpoll_cleanup(struct netpoll *np);
691 Index: linux-2.6.0-test6/net/core/Makefile
692 ===================================================================
693 --- linux-2.6.0-test6.orig/net/core/Makefile 2003-09-28 08:51:03.000000000 +0800
694 +++ linux-2.6.0-test6/net/core/Makefile 2003-10-07 16:08:51.000000000 +0800
696 obj-$(CONFIG_NET_DIVERT) += dv.o
697 obj-$(CONFIG_NET_PKTGEN) += pktgen.o
698 obj-$(CONFIG_NET_RADIO) += wireless.o
699 +obj-$(CONFIG_NETPOLL) += netpoll.o
700 Index: linux-2.6.0-test6/net/Kconfig
701 ===================================================================
702 --- linux-2.6.0-test6.orig/net/Kconfig 2003-09-28 08:50:07.000000000 +0800
703 +++ linux-2.6.0-test6/net/Kconfig 2003-10-09 20:36:23.429162080 +0800
706 source "net/bluetooth/Kconfig"
712 Index: linux-2.6.0-test6/include/linux/netdevice.h
713 ===================================================================
714 --- linux-2.6.0-test6.orig/include/linux/netdevice.h 2003-10-07 16:08:42.000000000 +0800
715 +++ linux-2.6.0-test6/include/linux/netdevice.h 2003-10-07 16:08:51.000000000 +0800
716 @@ -452,13 +452,13 @@
717 unsigned char *haddr);
718 int (*neigh_setup)(struct net_device *dev, struct neigh_parms *);
719 int (*accept_fastpath)(struct net_device *, struct dst_entry*);
720 +#ifdef CONFIG_NETPOLL
721 + int (*rx_hook)(struct sk_buff *skb);
725 struct net_bridge_port *br_port;
728 - int kgdb_is_trapped;
730 #ifdef CONFIG_NET_POLL_CONTROLLER
731 void (*poll_controller)(struct net_device *);
734 extern struct net_device *dev_get_by_index(int ifindex);
735 extern struct net_device *__dev_get_by_index(int ifindex);
736 extern int dev_restart(struct net_device *dev);
738 -extern int kgdb_eth_is_trapped(void);
739 -extern int kgdb_net_interrupt(struct sk_buff *skb);
740 -extern void kgdb_send_arp_request(void);
741 +#ifdef CONFIG_NETPOLL
742 +extern int netpoll_trap(void);
745 typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len);
748 static inline void netif_wake_queue(struct net_device *dev)
751 - if (kgdb_eth_is_trapped()) {
752 +#ifdef CONFIG_NETPOLL
753 + if (netpoll_trap())
757 if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
758 __netif_schedule(dev);
761 static inline void netif_stop_queue(struct net_device *dev)
764 - if (kgdb_eth_is_trapped()) {
765 +#ifdef CONFIG_NETPOLL
766 + if (netpoll_trap())
770 set_bit(__LINK_STATE_XOFF, &dev->state);
772 Index: linux-2.6.0-test6/net/core/dev.c
773 ===================================================================
774 --- linux-2.6.0-test6.orig/net/core/dev.c 2003-10-07 16:08:42.000000000 +0800
775 +++ linux-2.6.0-test6/net/core/dev.c 2003-10-09 20:36:23.436161016 +0800
776 @@ -1352,16 +1352,8 @@
777 struct softnet_data *queue;
781 - /* See if kgdb_eth wants this packet */
782 - if (!kgdb_net_interrupt(skb)) {
783 - /* No.. if we're 'trapped' then junk it */
784 - if (kgdb_eth_is_trapped()) {
786 - return NET_RX_DROP;
789 - /* kgdb_eth ate the packet... drop it silently */
790 +#ifdef CONFIG_NETPOLL
791 + if (skb->dev->rx_hook && skb->dev->rx_hook(skb)) {
795 @@ -1556,6 +1548,13 @@
796 int ret = NET_RX_DROP;
797 unsigned short type = skb->protocol;
799 +#ifdef CONFIG_NETPOLL
800 + if (skb->dev->rx_hook && skb->dev->rx_hook(skb)) {
802 + return NET_RX_DROP;
806 if (!skb->stamp.tv_sec)
807 do_gettimeofday(&skb->stamp);
809 Index: linux-2.6.0-test6/include/asm-i386/irq.h
810 ===================================================================
811 --- linux-2.6.0-test6.orig/include/asm-i386/irq.h 2003-09-28 08:50:36.000000000 +0800
812 +++ linux-2.6.0-test6/include/asm-i386/irq.h 2003-10-07 16:08:51.000000000 +0800
814 extern void disable_irq_nosync(unsigned int);
815 extern void enable_irq(unsigned int);
816 extern void release_x86_irqs(struct task_struct *);
817 +struct irqaction *find_irq_action(unsigned int irq, void *dev_id);
819 #ifdef CONFIG_X86_LOCAL_APIC
820 #define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */
821 Index: linux-2.6.0-test6/arch/i386/kernel/irq.c
822 ===================================================================
823 --- linux-2.6.0-test6.orig/arch/i386/kernel/irq.c 2003-10-07 16:08:34.000000000 +0800
824 +++ linux-2.6.0-test6/arch/i386/kernel/irq.c 2003-10-09 20:36:23.433161472 +0800
827 spin_unlock_irqrestore(&desc->lock, flags);
831 * do_IRQ handles all normal device IRQ's (the special
832 * SMP cross-CPU interrupts have their own specific
837 +struct irqaction *find_irq_action(unsigned int irq, void *dev_id)
839 + struct irqaction *a, *r=0;
841 + spin_lock_irq(&irq_desc[irq].lock);
842 + for(a=irq_desc[irq].action; a; a=a->next) {
843 + if(a->dev_id == dev_id) {
848 + spin_unlock_irq(&irq_desc[irq].lock);
852 static struct proc_dir_entry * root_irq_dir;
853 static struct proc_dir_entry * irq_dir [NR_IRQS];