Whamcloud - gitweb
- configurable stack size fo x86_64
[fs/lustre-release.git] / lustre / kernel_patches / patches / netconsole-2.4.20-rh.patch
1 Index: linux-2.4.20-rh/drivers/net/netconsole.c
2 ===================================================================
3 --- linux-2.4.20-rh.orig/drivers/net/netconsole.c       2003-07-22 16:02:23.000000000 +0800
4 +++ linux-2.4.20-rh/drivers/net/netconsole.c    2003-11-11 07:42:33.000000000 +0800
5 @@ -12,6 +12,8 @@
6   *
7   * 2001-09-17    started by Ingo Molnar.
8   * 2002-03-14    simultaneous syslog packet option by Michael K. Johnson
9 + * 2003-10-30    Add sysrq command processing by Wangdi <wangdi@clusterfs.com>
10 + * 
11   */
12  
13  /****************************************************************
14 @@ -51,6 +53,7 @@
15  #include <linux/tty_driver.h>
16  #include <linux/etherdevice.h>
17  #include <linux/elf.h>
18 +#include "netconsole.h"
19  
20  static struct net_device *netconsole_dev;
21  static u16 source_port, netdump_target_port, netlog_target_port, syslog_target_port;
22 @@ -62,12 +65,11 @@
23  static unsigned int mhz = 500, idle_timeout;
24  static unsigned long long mhz_cycles, jiffy_cycles;
25  
26 -#include "netconsole.h"
27  
28  #define MAX_UDP_CHUNK 1460
29  #define MAX_PRINT_CHUNK (MAX_UDP_CHUNK-HEADER_LEN)
30  
31 -#define DEBUG 0
32 +#define DEBUG 0 
33  #if DEBUG
34  # define Dprintk(x...) printk(KERN_INFO x)
35  #else
36 @@ -187,6 +189,22 @@
37                 }
38         }
39  }
40 +void (*irqfunc)(int, void *, struct pt_regs *);
41 +
42 +static void netdump_poll(struct net_device *dev)
43 +{
44 +       int budget = 1;
45 +
46 +       disable_irq(dev->irq);
47 +       
48 +       irqfunc(dev->irq, dev, 0);
49 +       
50 +       if(dev->poll && test_bit(__LINK_STATE_RX_SCHED, &dev->state))
51 +               dev->poll(dev, &budget);
52 +
53 +       enable_irq(dev->irq);
54 +
55 +}
56  
57  static struct sk_buff * alloc_netconsole_skb(struct net_device *dev, int len, int reserve)
58  {
59 @@ -209,7 +227,7 @@
60                                 once = 0;
61                         }
62                         Dprintk("alloc skb: polling controller ...\n");
63 -                       dev->poll_controller(dev);
64 +                       netdump_poll(dev);
65                         goto repeat;
66                 }
67         }
68 @@ -231,7 +249,7 @@
69                 spin_unlock(&dev->xmit_lock);
70  
71                 Dprintk("xmit skb: polling controller ...\n");
72 -               dev->poll_controller(dev);
73 +               netdump_poll(dev);
74                 zap_completion_queue();
75                 goto repeat_poll;
76         }
77 @@ -426,18 +444,79 @@
78  static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;
79  static unsigned int log_offset;
80  
81 +static int thread_stopped = 0;
82 +/*Interrupt function for netdump */
83 +static int sysrq_mode = 0;
84 +static int stop_sysrq_thread = 0;
85 +#define Set_Sysrq_mode()       (sysrq_mode = 1)
86 +#define Clear_Sysrq_mode()     (sysrq_mode = 0)
87 +static char send_cache[MAX_PRINT_CHUNK];
88 +static unsigned int send_cache_pos = 0;
89 +wait_queue_head_t sysrq_thread_queue;
90 +wait_queue_head_t sysrq_thread_waiter_queue;
91 +
92 +#define SEND_MSG_BUFFER(buf, len)                      \
93 +do                                                     \
94 +{                                                      \
95 +       reply_t reply;                                  \
96 +       unsigned int flags;                             \
97 +       __save_flags(flags);                            \
98 +       __cli();                                        \
99 +       reply.code = REPLY_LOG;                         \
100 +       reply.nr = 0;                                   \
101 +       reply.info = 0;                                 \
102 +       spin_lock(&sequence_lock);                      \
103 +       send_netlog_skb(dev, buf, len, &reply); \
104 +       spin_unlock(&sequence_lock);                    \
105 +       __restore_flags(flags);                         \
106 +}while(0);
107 +
108 +void netconsole_do_sysrq(req_t *req)
109 +{
110 +        struct pt_regs regs;
111 +       struct net_device *dev = netconsole_dev;
112 +
113 +       if (!dev)
114 +               return;
115 +       Set_Sysrq_mode();
116 +       get_current_regs(&regs);
117 +       handle_sysrq((int)req->from, &regs, NULL);
118 +       
119 +       if (send_cache_pos != 0){
120 +               SEND_MSG_BUFFER(send_cache, send_cache_pos);
121 +               memset(send_cache, 0, MAX_PRINT_CHUNK);
122 +               send_cache_pos = 0;
123 +       } 
124 +
125 +       Clear_Sysrq_mode();
126 +}
127  static void write_netconsole_msg(struct console *con, const char *msg0, unsigned int msg_len)
128  {
129         int len, left, i;
130         struct net_device *dev;
131         const char *msg = msg0;
132         reply_t reply;
133 -
134 +       
135         dev = netconsole_dev;
136         if (!dev || netdump_mode)
137                 return;
138 -
139 -       if (dev->poll_controller && netif_running(dev)) {
140 +       if (sysrq_mode){
141 +               unsigned long total_len = send_cache_pos + msg_len;
142 +               unsigned long left_len = msg_len;
143 +               while (total_len >=  MAX_PRINT_CHUNK){
144 +                       unsigned long send_len = MAX_PRINT_CHUNK - send_cache_pos; 
145 +                       memcpy(send_cache + send_cache_pos, msg, send_len);
146 +                       SEND_MSG_BUFFER(send_cache, MAX_PRINT_CHUNK);
147 +                       send_cache_pos = 0;
148 +                       total_len -= MAX_PRINT_CHUNK;
149 +                       left_len -= send_len; 
150 +               }
151 +               if (left_len > 0){
152 +                       memcpy(send_cache + send_cache_pos, msg + (msg_len -left_len), left_len);
153 +                       send_cache_pos += left_len;
154 +               }
155 +               return; 
156 +       }else if (netif_running(dev)) {
157                 unsigned long flags;
158  
159                 __save_flags(flags);
160 @@ -567,8 +646,6 @@
161         req_t *req;
162         struct net_device *dev;
163  
164 -       if (!netdump_mode)
165 -               return NET_RX_SUCCESS;
166  #if DEBUG
167         {
168                 static int packet_count;
169 @@ -722,8 +799,16 @@
170         Dprintk("... netdump from:    %08x.\n", req->from);
171         Dprintk("... netdump to:      %08x.\n", req->to);
172  
173 -       add_new_req(req);
174 +       if (netdump_mode) 
175 +               add_new_req(req);
176 +       else if (req->command == COMM_SYSRQ){
177 +               add_new_req(req);
178 +               wake_up(&sysrq_thread_queue);   
179 +               return NET_RX_DROP;
180 +       }
181  out:
182 +       if (!netdump_mode)
183 +               return NET_RX_SUCCESS;
184         return NET_RX_DROP;
185  }
186  
187 @@ -763,6 +848,7 @@
188         kunmap_atomic(kaddr, KM_NETDUMP);
189  }
190  
191 +
192  /*
193   * This function waits for the client to acknowledge the receipt
194   * of the netdump startup reply, with the possibility of packets
195 @@ -792,7 +878,7 @@
196                 // wait 1 sec.
197                 udelay(100);
198                 Dprintk("handshake: polling controller ...\n");
199 -               dev->poll_controller(dev);
200 +               netdump_poll(dev);              
201                 zap_completion_queue();
202                 req = get_new_req();
203                 if (req)
204 @@ -904,7 +990,7 @@
205         while (netdump_mode) {
206                 __cli();
207                 Dprintk("main netdump loop: polling controller ...\n");
208 -               dev->poll_controller(dev);
209 +               netdump_poll(dev);
210                 zap_completion_queue();
211  #if !CLI
212                 __sti();
213 @@ -1009,6 +1095,32 @@
214         printk("NETDUMP END!\n");
215         __restore_flags(flags);
216  }
217 +static int netconsole_sysrq_schedule(void *arg) 
218 +{
219 +       struct task_struct *tsk = current;
220 +
221 +       sprintf(tsk->comm, "sysrq_schedule");
222 +       sigfillset(&tsk->blocked);
223 +
224 +       /* main loop */
225 +       thread_stopped = 0;     
226 +       for (;;) {
227 +               wait_event_interruptible(sysrq_thread_queue,
228 +                                        !list_empty(&request_list) || stop_sysrq_thread);
229 +               while (!list_empty(&request_list)) {
230 +                       req_t *req = get_new_req();
231 +                       if (req->command == COMM_SYSRQ)
232 +                               netconsole_do_sysrq(req);       
233 +               }
234 +               if (stop_sysrq_thread)
235 +                       break;
236 +               wake_up(&sysrq_thread_waiter_queue);
237 +       }
238 +       thread_stopped = 1;     
239 +       wake_up(&sysrq_thread_waiter_queue);
240 +       return 0;
241 +}
242 +
243  
244  static char *dev;
245  static int netdump_target_eth_byte0 = 255;
246 @@ -1087,11 +1199,12 @@
247  
248  static struct console netconsole =
249          { flags: CON_ENABLED, write: write_netconsole_msg };
250 -
251  static int init_netconsole(void)
252  {
253         struct net_device *ndev = NULL;
254         struct in_device *in_dev;
255 +       struct irqaction *action;
256 +       int rc = 0;
257  
258         printk(KERN_INFO "netlog: using network device <%s>\n", dev);
259         // this will be valid once the device goes up.
260 @@ -1101,10 +1214,6 @@
261                 printk(KERN_ERR "netlog: network device %s does not exist, aborting.\n", dev);
262                 return -1;
263         }
264 -       if (!ndev->poll_controller) {
265 -               printk(KERN_ERR "netlog: %s's network driver does not implement netlogging yet, aborting.\n", dev);
266 -               return -1;
267 -       }
268         in_dev = in_dev_get(ndev);
269         if (!in_dev) {
270                 printk(KERN_ERR "netlog: network device %s is not an IP protocol device, aborting.\n", dev);
271 @@ -1137,8 +1246,6 @@
272         if (!netdump_target_ip && !netlog_target_ip && !syslog_target_ip) {
273                 printk(KERN_ERR "netlog: target_ip parameter not specified, aborting.\n");
274                 return -1;
275 -       }
276 -       if (netdump_target_ip) {
277  #define IP(x) ((unsigned char *)&netdump_target_ip)[x]
278                 printk(KERN_INFO "netlog: using netdump target IP %u.%u.%u.%u\n",
279                         IP(3), IP(2), IP(1), IP(0));
280 @@ -1214,12 +1321,27 @@
281  
282         mhz_cycles = (unsigned long long)mhz * 1000000ULL;
283         jiffy_cycles = (unsigned long long)mhz * (1000000/HZ);
284 -
285 -       INIT_LIST_HEAD(&request_list);
286 -
287 +       
288         ndev->rx_hook = netconsole_rx_hook;
289         netdump_func = netconsole_netdump;
290         netconsole_dev = ndev;
291 +       /* find irq function of the ndev*/
292 +       action=find_irq_action(ndev->irq, ndev);
293 +        if (!action) {
294 +               printk(KERN_ERR "couldn't find irq handler for <%s>", dev);
295 +               return -1;
296 +       }
297 +       irqfunc = action->handler;
298 +
299 +       stop_sysrq_thread = 0;
300 +       INIT_LIST_HEAD(&request_list);
301 +       init_waitqueue_head(&sysrq_thread_queue);
302 +       init_waitqueue_head(&sysrq_thread_waiter_queue);
303 +       if ((rc = kernel_thread(netconsole_sysrq_schedule, NULL, 0)) < 0 ){
304 +              printk(KERN_ERR "Can not start netconsole sysrq thread: rc %d\n", rc); 
305 +             return -1; 
306 +       }
307 +
308  #define STARTUP_MSG "[...network console startup...]\n"
309         write_netconsole_msg(NULL, STARTUP_MSG, strlen(STARTUP_MSG));
310  
311 @@ -1230,7 +1352,11 @@
312  
313  static void cleanup_netconsole(void)
314  {
315 -       printk(KERN_INFO "netlog: network logging shut down.\n");
316 +       stop_sysrq_thread = 1;
317 +       
318 +       wake_up(&sysrq_thread_queue);
319 +       wait_event(sysrq_thread_waiter_queue, thread_stopped); 
320 +       printk(KERN_INFO"netlog: network logging shut down.\n");
321         unregister_console(&netconsole);
322  
323  #define SHUTDOWN_MSG "[...network console shutdown...]\n"
324 Index: linux-2.4.20-rh/drivers/net/netconsole.h
325 ===================================================================
326 --- linux-2.4.20-rh.orig/drivers/net/netconsole.h       2003-07-22 16:02:23.000000000 +0800
327 +++ linux-2.4.20-rh/drivers/net/netconsole.h    2003-10-30 01:48:45.000000000 +0800
328 @@ -29,7 +29,7 @@
329   *
330   ****************************************************************/
331  
332 -#define NETCONSOLE_VERSION 0x04
333 +#define NETCONSOLE_VERSION 0x03
334  
335  enum netdump_commands {
336         COMM_NONE = 0,
337 @@ -42,6 +42,8 @@
338         COMM_START_NETDUMP_ACK = 7,
339         COMM_GET_REGS = 8,
340         COMM_SHOW_STATE = 9,
341 +       COMM_START_WRITE_NETDUMP_ACK = 10,
342 +        COMM_SYSRQ = 11,
343  };
344  
345  #define NETDUMP_REQ_SIZE (8+4*4)
346 @@ -69,6 +71,7 @@
347         REPLY_REGS = 10,
348         REPLY_MAGIC = 11,
349         REPLY_SHOW_STATE = 12,
350 +       REPLY_SYSRQ = 13,
351  };
352  
353  typedef struct netdump_reply_s {
354 @@ -78,4 +81,22 @@
355  } reply_t;
356  
357  #define HEADER_LEN (1 + sizeof(reply_t))
358 -
359 +/* for netconsole */
360 +static inline void get_current_regs(struct pt_regs *regs)
361 +{
362 +       __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx));
363 +       __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx));
364 +       __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx));
365 +       __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi));
366 +       __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi));
367 +       __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp));
368 +       __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax));
369 +       __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp));
370 +       __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss));
371 +       __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs));
372 +       __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds));
373 +       __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes));
374 +       __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags));
375 +       regs->eip = (unsigned long)current_text_addr();
376 +}
377 +               
378 Index: linux-2.4.20-rh/arch/i386/kernel/irq.c
379 ===================================================================
380 --- linux-2.4.20-rh.orig/arch/i386/kernel/irq.c 2003-10-30 08:29:38.000000000 +0800
381 +++ linux-2.4.20-rh/arch/i386/kernel/irq.c      2003-10-30 08:30:13.000000000 +0800
382 @@ -1043,7 +1043,20 @@
383         register_irq_proc(irq);
384         return 0;
385  }
386 +struct irqaction *find_irq_action(unsigned int irq, void *dev_id)
387 +{
388 +       struct irqaction *a, *r=0;
389  
390 +       spin_lock_irq(&irq_desc[irq].lock);
391 +       for(a=irq_desc[irq].action; a; a=a->next) {
392 +               if(a->dev_id == dev_id) {
393 +                       r=a;
394 +                       break;
395 +               }
396 +       }
397 +       spin_unlock_irq(&irq_desc[irq].lock);
398 +       return r;
399 +}
400  
401  static struct proc_dir_entry * root_irq_dir;
402  static struct proc_dir_entry * irq_dir [NR_IRQS];
403 Index: linux-2.4.20-rh/net/core/dev.c
404 ===================================================================
405 --- linux-2.4.20-rh.orig/net/core/dev.c 2003-10-29 01:40:26.000000000 +0800
406 +++ linux-2.4.20-rh/net/core/dev.c      2003-10-30 01:48:45.000000000 +0800
407 @@ -1475,6 +1475,16 @@
408  
409         skb_bond(skb);
410  
411 +       if (unlikely(skb->dev->rx_hook != NULL)) {
412 +               int ret;
413 +
414 +               ret = skb->dev->rx_hook(skb);
415 +               if (ret == NET_RX_DROP){
416 +                       kfree_skb(skb);
417 +                       return ret;
418 +               }
419 +        }
420 +
421         netdev_rx_stat[smp_processor_id()].total++;
422  
423  #ifdef CONFIG_NET_FASTROUTE
424 Index: linux-2.4.20-rh/include/asm-i386/irq.h
425 ===================================================================
426 --- linux-2.4.20-rh.orig/include/asm-i386/irq.h 2003-10-28 16:18:18.000000000 +0800
427 +++ linux-2.4.20-rh/include/asm-i386/irq.h      2003-10-30 10:24:49.000000000 +0800
428 @@ -38,7 +38,7 @@
429  extern void disable_irq_nosync(unsigned int);
430  extern void enable_irq(unsigned int);
431  extern void release_x86_irqs(struct task_struct *);
432 -
433 +extern struct irqaction *find_irq_action(unsigned int irq, void *dev_id);
434  #ifdef CONFIG_X86_LOCAL_APIC
435  #define ARCH_HAS_NMI_WATCHDOG          /* See include/linux/nmi.h */
436  #endif
437 Index: linux-2.4.20-rh/arch/i386/kernel/i386_ksyms.c
438 ===================================================================
439 --- linux-2.4.20-rh.orig/arch/i386/kernel/i386_ksyms.c  2003-10-28 19:44:57.000000000 +0800
440 +++ linux-2.4.20-rh/arch/i386/kernel/i386_ksyms.c       2003-10-30 11:14:55.000000000 +0800
441 @@ -68,6 +68,7 @@
442  EXPORT_SYMBOL(iounmap);
443  EXPORT_SYMBOL(enable_irq);
444  EXPORT_SYMBOL(disable_irq);
445 +EXPORT_SYMBOL(find_irq_action);
446  EXPORT_SYMBOL(disable_irq_nosync);
447  EXPORT_SYMBOL(probe_irq_mask);
448  EXPORT_SYMBOL(kernel_thread);
449 @@ -199,7 +200,6 @@
450  EXPORT_SYMBOL(edd);
451  EXPORT_SYMBOL(eddnr);
452  #endif
453 -
454  EXPORT_SYMBOL_GPL(show_mem);
455  EXPORT_SYMBOL_GPL(show_state);
456  EXPORT_SYMBOL_GPL(show_regs);
457 Index: linux-2.4.20-rh/kernel/panic.c
458 ===================================================================
459 --- linux-2.4.20-rh.orig/kernel/panic.c 2003-10-31 07:25:19.000000000 +0800
460 +++ linux-2.4.20-rh/kernel/panic.c      2003-10-31 07:25:59.000000000 +0800
461 @@ -219,8 +219,6 @@
462         }
463  #endif
464  
465 -       if (netdump_func)
466 -               BUG();
467         if (in_interrupt())
468                 printk(KERN_EMERG "In interrupt handler - not syncing\n");
469         else if (!current->pid)