Whamcloud - gitweb
b=3244
[fs/lustre-release.git] / lustre / kernel_patches / patches / netconsole-2.4.24-ppc.patch
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
7 @@ -12,6 +12,8 @@
8   *
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>
12 + * 
13   */
14  
15  /****************************************************************
16 @@ -51,6 +53,7 @@
17  #include <linux/tty_driver.h>
18  #include <linux/etherdevice.h>
19  #include <linux/elf.h>
20 +#include "netconsole.h"
21  
22  static struct net_device *netconsole_dev;
23  static u16 source_port, netdump_target_port, netlog_target_port, syslog_target_port;
24 @@ -62,12 +65,11 @@
25  static unsigned int mhz = 500, idle_timeout;
26  static unsigned long long mhz_cycles, jiffy_cycles;
27  
28 -#include "netconsole.h"
29  
30  #define MAX_UDP_CHUNK 1460
31  #define MAX_PRINT_CHUNK (MAX_UDP_CHUNK-HEADER_LEN)
32  
33 -#define DEBUG 0
34 +#define DEBUG 0 
35  #if DEBUG
36  # define Dprintk(x...) printk(KERN_INFO x)
37  #else
38 @@ -187,6 +189,22 @@
39                 }
40         }
41  }
42 +void (*irqfunc)(int, void *, struct pt_regs *);
43 +
44 +static void netdump_poll(struct net_device *dev)
45 +{
46 +       int budget = 1;
47 +
48 +       disable_irq(dev->irq);
49 +       
50 +       irqfunc(dev->irq, dev, 0);
51 +       
52 +       if(dev->poll && test_bit(__LINK_STATE_RX_SCHED, &dev->state))
53 +               dev->poll(dev, &budget);
54 +
55 +       enable_irq(dev->irq);
56 +
57 +}
58  
59  static struct sk_buff * alloc_netconsole_skb(struct net_device *dev, int len, int reserve)
60  {
61 @@ -209,7 +227,7 @@
62                                 once = 0;
63                         }
64                         Dprintk("alloc skb: polling controller ...\n");
65 -                       dev->poll_controller(dev);
66 +                       netdump_poll(dev);
67                         goto repeat;
68                 }
69         }
70 @@ -231,7 +249,7 @@
71                 spin_unlock(&dev->xmit_lock);
72  
73                 Dprintk("xmit skb: polling controller ...\n");
74 -               dev->poll_controller(dev);
75 +               netdump_poll(dev);
76                 zap_completion_queue();
77                 goto repeat_poll;
78         }
79 @@ -426,18 +444,79 @@
80  static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;
81  static unsigned int log_offset;
82  
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;
93 +
94 +#define SEND_MSG_BUFFER(buf, len)                      \
95 +do                                                     \
96 +{                                                      \
97 +       reply_t reply;                                  \
98 +       unsigned int flags;                             \
99 +       __save_flags(flags);                            \
100 +       __cli();                                        \
101 +       reply.code = REPLY_LOG;                         \
102 +       reply.nr = 0;                                   \
103 +       reply.info = 0;                                 \
104 +       spin_lock(&sequence_lock);                      \
105 +       send_netlog_skb(dev, buf, len, &reply); \
106 +       spin_unlock(&sequence_lock);                    \
107 +       __restore_flags(flags);                         \
108 +}while(0);
109 +
110 +void netconsole_do_sysrq(req_t *req)
111 +{
112 +        struct pt_regs regs;
113 +       struct net_device *dev = netconsole_dev;
114 +
115 +       if (!dev)
116 +               return;
117 +       Set_Sysrq_mode();
118 +       get_current_regs(&regs);
119 +       handle_sysrq((int)req->from, &regs, NULL);
120 +       
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;
125 +       } 
126 +
127 +       Clear_Sysrq_mode();
128 +}
129  static void write_netconsole_msg(struct console *con, const char *msg0, unsigned int msg_len)
130  {
131         int len, left, i;
132         struct net_device *dev;
133         const char *msg = msg0;
134         reply_t reply;
135 -
136 +       
137         dev = netconsole_dev;
138         if (!dev || netdump_mode)
139                 return;
140 -
141 -       if (dev->poll_controller && netif_running(dev)) {
142 +       if (sysrq_mode){
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; 
152 +               }
153 +               if (left_len > 0){
154 +                       memcpy(send_cache + send_cache_pos, msg + (msg_len -left_len), left_len);
155 +                       send_cache_pos += left_len;
156 +               }
157 +               return; 
158 +       }else if (netif_running(dev)) {
159                 unsigned long flags;
160  
161                 __save_flags(flags);
162 @@ -567,8 +646,6 @@
163         req_t *req;
164         struct net_device *dev;
165  
166 -       if (!netdump_mode)
167 -               return NET_RX_SUCCESS;
168  #if DEBUG
169         {
170                 static int packet_count;
171 @@ -722,8 +799,16 @@
172         Dprintk("... netdump from:    %08x.\n", req->from);
173         Dprintk("... netdump to:      %08x.\n", req->to);
174  
175 -       add_new_req(req);
176 +       if (netdump_mode) 
177 +               add_new_req(req);
178 +       else if (req->command == COMM_SYSRQ){
179 +               add_new_req(req);
180 +               wake_up(&sysrq_thread_queue);   
181 +               return NET_RX_DROP;
182 +       }
183  out:
184 +       if (!netdump_mode)
185 +               return NET_RX_SUCCESS;
186         return NET_RX_DROP;
187  }
188  
189 @@ -763,6 +848,7 @@
190         kunmap_atomic(kaddr, KM_NETDUMP);
191  }
192  
193 +
194  /*
195   * This function waits for the client to acknowledge the receipt
196   * of the netdump startup reply, with the possibility of packets
197 @@ -792,7 +878,7 @@
198                 // wait 1 sec.
199                 udelay(100);
200                 Dprintk("handshake: polling controller ...\n");
201 -               dev->poll_controller(dev);
202 +               netdump_poll(dev);              
203                 zap_completion_queue();
204                 req = get_new_req();
205                 if (req)
206 @@ -884,6 +970,7 @@
207          */
208         spin_lock_init(&dev->xmit_lock);
209  
210 +#ifdef __i386__
211         esp = (unsigned long) ((char *)regs + sizeof (struct pt_regs));
212         ss = __KERNEL_DS;
213         if (regs->xcs & 3) {
214 @@ -893,6 +980,7 @@
215         myregs = *regs;
216         myregs.esp = esp;
217         myregs.xss = (myregs.xss & 0xffff0000) | ss;
218 +#endif
219  
220         rdtscll(t0);
221  
222 @@ -904,7 +992,7 @@
223         while (netdump_mode) {
224                 __cli();
225                 Dprintk("main netdump loop: polling controller ...\n");
226 -               dev->poll_controller(dev);
227 +               netdump_poll(dev);
228                 zap_completion_queue();
229  #if !CLI
230                 __sti();
231 @@ -1009,6 +1097,32 @@
232         printk("NETDUMP END!\n");
233         __restore_flags(flags);
234  }
235 +static int netconsole_sysrq_schedule(void *arg) 
236 +{
237 +       struct task_struct *tsk = current;
238 +
239 +       sprintf(tsk->comm, "sysrq_schedule");
240 +       sigfillset(&tsk->blocked);
241 +
242 +       /* main loop */
243 +       thread_stopped = 0;     
244 +       for (;;) {
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);       
251 +               }
252 +               if (stop_sysrq_thread)
253 +                       break;
254 +               wake_up(&sysrq_thread_waiter_queue);
255 +       }
256 +       thread_stopped = 1;     
257 +       wake_up(&sysrq_thread_waiter_queue);
258 +       return 0;
259 +}
260 +
261  
262  static char *dev;
263  static int netdump_target_eth_byte0 = 255;
264 @@ -1087,11 +1201,12 @@
265  
266  static struct console netconsole =
267          { flags: CON_ENABLED, write: write_netconsole_msg };
268 -
269  static int init_netconsole(void)
270  {
271         struct net_device *ndev = NULL;
272         struct in_device *in_dev;
273 +       struct irqaction *action;
274 +       int rc = 0;
275  
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);
280                 return -1;
281         }
282 -       if (!ndev->poll_controller) {
283 -               printk(KERN_ERR "netlog: %s's network driver does not implement netlogging yet, aborting.\n", dev);
284 -               return -1;
285 -       }
286         in_dev = in_dev_get(ndev);
287         if (!in_dev) {
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");
292                 return -1;
293 -       }
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 @@
299  
300         mhz_cycles = (unsigned long long)mhz * 1000000ULL;
301         jiffy_cycles = (unsigned long long)mhz * (1000000/HZ);
302 -
303 -       INIT_LIST_HEAD(&request_list);
304 -
305 +       
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);
311 +        if (!action) {
312 +               printk(KERN_ERR "couldn't find irq handler for <%s>", dev);
313 +               return -1;
314 +       }
315 +       irqfunc = action->handler;
316 +
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); 
323 +             return -1; 
324 +       }
325 +
326  #define STARTUP_MSG "[...network console startup...]\n"
327         write_netconsole_msg(NULL, STARTUP_MSG, strlen(STARTUP_MSG));
328  
329 @@ -1230,7 +1354,11 @@
330  
331  static void cleanup_netconsole(void)
332  {
333 -       printk(KERN_INFO "netlog: network logging shut down.\n");
334 +       stop_sysrq_thread = 1;
335 +       
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);
340  
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
346 @@ -29,7 +29,7 @@
347   *
348   ****************************************************************/
349  
350 -#define NETCONSOLE_VERSION 0x04
351 +#define NETCONSOLE_VERSION 0x03
352  
353  enum netdump_commands {
354         COMM_NONE = 0,
355 @@ -42,6 +42,8 @@
356         COMM_START_NETDUMP_ACK = 7,
357         COMM_GET_REGS = 8,
358         COMM_SHOW_STATE = 9,
359 +       COMM_START_WRITE_NETDUMP_ACK = 10,
360 +        COMM_SYSRQ = 11,
361  };
362  
363  #define NETDUMP_REQ_SIZE (8+4*4)
364 @@ -69,6 +71,7 @@
365         REPLY_REGS = 10,
366         REPLY_MAGIC = 11,
367         REPLY_SHOW_STATE = 12,
368 +       REPLY_SYSRQ = 13,
369  };
370  
371  typedef struct netdump_reply_s {
372 @@ -78,4 +81,24 @@
373  } reply_t;
374  
375  #define HEADER_LEN (1 + sizeof(reply_t))
376 -
377 +/* for netconsole */
378 +static inline void get_current_regs(struct pt_regs *regs)
379 +{
380 +#ifdef __i386__
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();
395 +#endif
396 +}
397 +               
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
402 @@ -182,7 +182,20 @@
403  
404         return 0;
405  }
406 +struct irqaction *find_irq_action(unsigned int irq, void *dev_id)
407 +{
408 +       struct irqaction *a, *r=0;
409  
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) {
413 +                       r=a;
414 +                       break;
415 +               }
416 +       }
417 +       spin_unlock_irq(&irq_desc[irq].lock);
418 +       return r;
419 +}
420  
421  /*
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
427 @@ -66,6 +66,7 @@
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);
435 @@ -186,7 +187,6 @@
436  EXPORT_SYMBOL(edd);
437  EXPORT_SYMBOL(eddnr);
438  #endif
439 -
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 @@
448  
449         skb_bond(skb);
450  
451 +       if (unlikely(skb->dev->rx_hook != NULL)) {
452 +               int ret;
453 +
454 +               ret = skb->dev->rx_hook(skb);
455 +               if (ret == NET_RX_DROP){
456 +                       kfree_skb(skb);
457 +                       return ret;
458 +               }
459 +        }
460 +
461         netdev_rx_stat[smp_processor_id()].total++;
462  
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
468 @@ -38,7 +38,7 @@
469  extern void disable_irq_nosync(unsigned int);
470  extern void enable_irq(unsigned int);
471  extern void release_x86_irqs(struct task_struct *);
472 -
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 */
476  #endif
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
481 @@ -66,8 +66,6 @@
482         vsprintf(buf, fmt, args);
483         va_end(args);
484         printk(KERN_EMERG "Kernel panic: %s\n",buf);
485 -       if (netdump_func)
486 -               BUG();
487         if (in_interrupt())
488                 printk(KERN_EMERG "In interrupt handler - not syncing\n");
489         else if (!current->pid)