1 Index: linux-2.4.24/drivers/net/netconsole.c
\r
2 ===================================================================
\r
3 Index: bglio/drivers/net/netconsole.c
4 ===================================================================
5 --- bglio.orig/drivers/net/netconsole.c 2004-05-07 15:50:22.000000000 -0700
6 +++ bglio/drivers/net/netconsole.c 2004-05-07 17:15:28.000000000 -0700
9 * 2001-09-17 started by Ingo Molnar.
10 * 2002-03-14 simultaneous syslog packet option by Michael K. Johnson
11 + * 2003-10-30 Add sysrq command processing by Wangdi <wangdi@clusterfs.com>
15 /****************************************************************
17 #include <linux/tty_driver.h>
18 #include <linux/etherdevice.h>
19 #include <linux/elf.h>
20 +#include "netconsole.h"
22 static struct net_device *netconsole_dev;
23 static u16 source_port, netdump_target_port, netlog_target_port, syslog_target_port;
25 static unsigned int mhz = 500, idle_timeout;
26 static unsigned long long mhz_cycles, jiffy_cycles;
28 -#include "netconsole.h"
30 #define MAX_UDP_CHUNK 1460
31 #define MAX_PRINT_CHUNK (MAX_UDP_CHUNK-HEADER_LEN)
36 # define Dprintk(x...) printk(KERN_INFO x)
42 +void (*irqfunc)(int, void *, struct pt_regs *);
44 +static void netdump_poll(struct net_device *dev)
48 + disable_irq(dev->irq);
50 + irqfunc(dev->irq, dev, 0);
52 + if(dev->poll && test_bit(__LINK_STATE_RX_SCHED, &dev->state))
53 + dev->poll(dev, &budget);
55 + enable_irq(dev->irq);
59 static struct sk_buff * alloc_netconsole_skb(struct net_device *dev, int len, int reserve)
64 Dprintk("alloc skb: polling controller ...\n");
65 - dev->poll_controller(dev);
71 spin_unlock(&dev->xmit_lock);
73 Dprintk("xmit skb: polling controller ...\n");
74 - dev->poll_controller(dev);
76 zap_completion_queue();
80 static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;
81 static unsigned int log_offset;
83 +static int thread_stopped = 0;
84 +/*Interrupt function for netdump */
85 +static int sysrq_mode = 0;
86 +static int stop_sysrq_thread = 0;
87 +#define Set_Sysrq_mode() (sysrq_mode = 1)
88 +#define Clear_Sysrq_mode() (sysrq_mode = 0)
89 +static char send_cache[MAX_PRINT_CHUNK];
90 +static unsigned int send_cache_pos = 0;
91 +wait_queue_head_t sysrq_thread_queue;
92 +wait_queue_head_t sysrq_thread_waiter_queue;
94 +#define SEND_MSG_BUFFER(buf, len) \
98 + unsigned int flags; \
99 + __save_flags(flags); \
101 + reply.code = REPLY_LOG; \
104 + spin_lock(&sequence_lock); \
105 + send_netlog_skb(dev, buf, len, &reply); \
106 + spin_unlock(&sequence_lock); \
107 + __restore_flags(flags); \
110 +void netconsole_do_sysrq(req_t *req)
112 + struct pt_regs regs;
113 + struct net_device *dev = netconsole_dev;
118 + get_current_regs(®s);
119 + handle_sysrq((int)req->from, ®s, NULL);
121 + if (send_cache_pos != 0){
122 + SEND_MSG_BUFFER(send_cache, send_cache_pos);
123 + memset(send_cache, 0, MAX_PRINT_CHUNK);
124 + send_cache_pos = 0;
127 + Clear_Sysrq_mode();
129 static void write_netconsole_msg(struct console *con, const char *msg0, unsigned int msg_len)
132 struct net_device *dev;
133 const char *msg = msg0;
137 dev = netconsole_dev;
138 if (!dev || netdump_mode)
141 - if (dev->poll_controller && netif_running(dev)) {
143 + unsigned long total_len = send_cache_pos + msg_len;
144 + unsigned long left_len = msg_len;
145 + while (total_len >= MAX_PRINT_CHUNK){
146 + unsigned long send_len = MAX_PRINT_CHUNK - send_cache_pos;
147 + memcpy(send_cache + send_cache_pos, msg, send_len);
148 + SEND_MSG_BUFFER(send_cache, MAX_PRINT_CHUNK);
149 + send_cache_pos = 0;
150 + total_len -= MAX_PRINT_CHUNK;
151 + left_len -= send_len;
154 + memcpy(send_cache + send_cache_pos, msg + (msg_len -left_len), left_len);
155 + send_cache_pos += left_len;
158 + }else if (netif_running(dev)) {
164 struct net_device *dev;
167 - return NET_RX_SUCCESS;
170 static int packet_count;
172 Dprintk("... netdump from: %08x.\n", req->from);
173 Dprintk("... netdump to: %08x.\n", req->to);
178 + else if (req->command == COMM_SYSRQ){
180 + wake_up(&sysrq_thread_queue);
181 + return NET_RX_DROP;
185 + return NET_RX_SUCCESS;
190 kunmap_atomic(kaddr, KM_NETDUMP);
195 * This function waits for the client to acknowledge the receipt
196 * of the netdump startup reply, with the possibility of packets
200 Dprintk("handshake: polling controller ...\n");
201 - dev->poll_controller(dev);
203 zap_completion_queue();
208 spin_lock_init(&dev->xmit_lock);
211 esp = (unsigned long) ((char *)regs + sizeof (struct pt_regs));
217 myregs.xss = (myregs.xss & 0xffff0000) | ss;
223 while (netdump_mode) {
225 Dprintk("main netdump loop: polling controller ...\n");
226 - dev->poll_controller(dev);
228 zap_completion_queue();
231 @@ -1009,6 +1097,32 @@
232 printk("NETDUMP END!\n");
233 __restore_flags(flags);
235 +static int netconsole_sysrq_schedule(void *arg)
237 + struct task_struct *tsk = current;
239 + sprintf(tsk->comm, "sysrq_schedule");
240 + sigfillset(&tsk->blocked);
243 + thread_stopped = 0;
245 + wait_event_interruptible(sysrq_thread_queue,
246 + !list_empty(&request_list) || stop_sysrq_thread);
247 + while (!list_empty(&request_list)) {
248 + req_t *req = get_new_req();
249 + if (req->command == COMM_SYSRQ)
250 + netconsole_do_sysrq(req);
252 + if (stop_sysrq_thread)
254 + wake_up(&sysrq_thread_waiter_queue);
256 + thread_stopped = 1;
257 + wake_up(&sysrq_thread_waiter_queue);
263 static int netdump_target_eth_byte0 = 255;
264 @@ -1087,11 +1201,12 @@
266 static struct console netconsole =
267 { flags: CON_ENABLED, write: write_netconsole_msg };
269 static int init_netconsole(void)
271 struct net_device *ndev = NULL;
272 struct in_device *in_dev;
273 + struct irqaction *action;
276 printk(KERN_INFO "netlog: using network device <%s>\n", dev);
277 // this will be valid once the device goes up.
278 @@ -1101,10 +1216,6 @@
279 printk(KERN_ERR "netlog: network device %s does not exist, aborting.\n", dev);
282 - if (!ndev->poll_controller) {
283 - printk(KERN_ERR "netlog: %s's network driver does not implement netlogging yet, aborting.\n", dev);
286 in_dev = in_dev_get(ndev);
288 printk(KERN_ERR "netlog: network device %s is not an IP protocol device, aborting.\n", dev);
289 @@ -1137,8 +1248,6 @@
290 if (!netdump_target_ip && !netlog_target_ip && !syslog_target_ip) {
291 printk(KERN_ERR "netlog: target_ip parameter not specified, aborting.\n");
294 - if (netdump_target_ip) {
295 #define IP(x) ((unsigned char *)&netdump_target_ip)[x]
296 printk(KERN_INFO "netlog: using netdump target IP %u.%u.%u.%u\n",
297 IP(3), IP(2), IP(1), IP(0));
298 @@ -1214,12 +1323,27 @@
300 mhz_cycles = (unsigned long long)mhz * 1000000ULL;
301 jiffy_cycles = (unsigned long long)mhz * (1000000/HZ);
303 - INIT_LIST_HEAD(&request_list);
306 ndev->rx_hook = netconsole_rx_hook;
307 netdump_func = netconsole_netdump;
308 netconsole_dev = ndev;
309 + /* find irq function of the ndev*/
310 + action=find_irq_action(ndev->irq, ndev);
312 + printk(KERN_ERR "couldn't find irq handler for <%s>", dev);
315 + irqfunc = action->handler;
317 + stop_sysrq_thread = 0;
318 + INIT_LIST_HEAD(&request_list);
319 + init_waitqueue_head(&sysrq_thread_queue);
320 + init_waitqueue_head(&sysrq_thread_waiter_queue);
321 + if ((rc = kernel_thread(netconsole_sysrq_schedule, NULL, 0)) < 0 ){
322 + printk(KERN_ERR "Can not start netconsole sysrq thread: rc %d\n", rc);
326 #define STARTUP_MSG "[...network console startup...]\n"
327 write_netconsole_msg(NULL, STARTUP_MSG, strlen(STARTUP_MSG));
329 @@ -1230,7 +1354,11 @@
331 static void cleanup_netconsole(void)
333 - printk(KERN_INFO "netlog: network logging shut down.\n");
334 + stop_sysrq_thread = 1;
336 + wake_up(&sysrq_thread_queue);
337 + wait_event(sysrq_thread_waiter_queue, thread_stopped);
338 + printk(KERN_INFO"netlog: network logging shut down.\n");
339 unregister_console(&netconsole);
341 #define SHUTDOWN_MSG "[...network console shutdown...]\n"
342 Index: bglio/drivers/net/netconsole.h
343 ===================================================================
344 --- bglio.orig/drivers/net/netconsole.h 2004-05-07 15:50:22.000000000 -0700
345 +++ bglio/drivers/net/netconsole.h 2004-05-07 17:11:01.000000000 -0700
348 ****************************************************************/
350 -#define NETCONSOLE_VERSION 0x04
351 +#define NETCONSOLE_VERSION 0x03
353 enum netdump_commands {
356 COMM_START_NETDUMP_ACK = 7,
359 + COMM_START_WRITE_NETDUMP_ACK = 10,
363 #define NETDUMP_REQ_SIZE (8+4*4)
367 REPLY_SHOW_STATE = 12,
371 typedef struct netdump_reply_s {
375 #define HEADER_LEN (1 + sizeof(reply_t))
377 +/* for netconsole */
378 +static inline void get_current_regs(struct pt_regs *regs)
381 + __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx));
382 + __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx));
383 + __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx));
384 + __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi));
385 + __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi));
386 + __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp));
387 + __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax));
388 + __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp));
389 + __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss));
390 + __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs));
391 + __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds));
392 + __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes));
393 + __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags));
394 + regs->eip = (unsigned long)current_text_addr();
398 Index: bglio/arch/i386/kernel/irq.c
399 ===================================================================
400 --- bglio.orig/arch/i386/kernel/irq.c 2004-05-07 15:50:17.000000000 -0700
401 +++ bglio/arch/i386/kernel/irq.c 2004-05-07 17:11:01.000000000 -0700
406 +struct irqaction *find_irq_action(unsigned int irq, void *dev_id)
408 + struct irqaction *a, *r=0;
410 + spin_lock_irq(&irq_desc[irq].lock);
411 + for(a=irq_desc[irq].action; a; a=a->next) {
412 + if(a->dev_id == dev_id) {
417 + spin_unlock_irq(&irq_desc[irq].lock);
422 * Global interrupt locks for SMP. Allow interrupts to come in on any
423 Index: bglio/arch/i386/kernel/i386_ksyms.c
424 ===================================================================
425 --- bglio.orig/arch/i386/kernel/i386_ksyms.c 2004-05-07 15:50:22.000000000 -0700
426 +++ bglio/arch/i386/kernel/i386_ksyms.c 2004-05-07 17:11:01.000000000 -0700
428 EXPORT_SYMBOL(iounmap);
429 EXPORT_SYMBOL(enable_irq);
430 EXPORT_SYMBOL(disable_irq);
431 +EXPORT_SYMBOL(find_irq_action);
432 EXPORT_SYMBOL(disable_irq_nosync);
433 EXPORT_SYMBOL(probe_irq_mask);
434 EXPORT_SYMBOL(kernel_thread);
437 EXPORT_SYMBOL(eddnr);
440 EXPORT_SYMBOL_GPL(show_mem);
441 EXPORT_SYMBOL_GPL(show_state);
442 EXPORT_SYMBOL_GPL(show_regs);
443 Index: bglio/net/core/dev.c
444 ===================================================================
445 --- bglio.orig/net/core/dev.c 2004-05-07 15:50:22.000000000 -0700
446 +++ bglio/net/core/dev.c 2004-05-07 17:11:01.000000000 -0700
447 @@ -1476,6 +1476,16 @@
451 + if (unlikely(skb->dev->rx_hook != NULL)) {
454 + ret = skb->dev->rx_hook(skb);
455 + if (ret == NET_RX_DROP){
461 netdev_rx_stat[smp_processor_id()].total++;
463 #ifdef CONFIG_NET_FASTROUTE
464 Index: bglio/include/asm-i386/irq.h
465 ===================================================================
466 --- bglio.orig/include/asm-i386/irq.h 2004-05-07 15:25:28.000000000 -0700
467 +++ bglio/include/asm-i386/irq.h 2004-05-07 17:11:01.000000000 -0700
469 extern void disable_irq_nosync(unsigned int);
470 extern void enable_irq(unsigned int);
471 extern void release_x86_irqs(struct task_struct *);
473 +extern struct irqaction *find_irq_action(unsigned int irq, void *dev_id);
474 #ifdef CONFIG_X86_LOCAL_APIC
475 #define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */
477 Index: bglio/kernel/panic.c
478 ===================================================================
479 --- bglio.orig/kernel/panic.c 2004-05-07 15:50:22.000000000 -0700
480 +++ bglio/kernel/panic.c 2004-05-07 17:11:01.000000000 -0700
482 vsprintf(buf, fmt, args);
484 printk(KERN_EMERG "Kernel panic: %s\n",buf);
488 printk(KERN_EMERG "In interrupt handler - not syncing\n");
489 else if (!current->pid)