Whamcloud - gitweb
b=10651
[fs/lustre-release.git] / lustre / kernel_patches / patches / export-show_task-2.4-rh.patch
1 Index: linux-2.4.20/kernel/ksyms.c
2 ===================================================================
3 --- linux-2.4.20.orig/kernel/ksyms.c    2004-10-21 21:30:14.000000000 -0400
4 +++ linux-2.4.20/kernel/ksyms.c 2004-10-21 21:32:00.000000000 -0400
5 @@ -75,6 +75,7 @@
6  extern spinlock_t dma_spin_lock;
7  extern int panic_timeout;
8  
9 +extern void show_task(task_t *);
10  
11  #ifdef CONFIG_MODVERSIONS
12  const struct module_symbol __export_Using_Versions
13 @@ -636,3 +637,4 @@
14  extern void check_tasklist_locked(void);
15  EXPORT_SYMBOL_GPL(check_tasklist_locked);
16  EXPORT_SYMBOL(dump_stack);
17 +EXPORT_SYMBOL(show_task);
18 Index: linux-2.4.20/arch/i386/kernel/traps.c
19 ===================================================================
20 --- linux-2.4.20.orig/arch/i386/kernel/traps.c  2004-10-21 21:30:15.000000000 -0400
21 +++ linux-2.4.20/arch/i386/kernel/traps.c       2004-10-25 14:34:41.000000000 -0400
22 @@ -137,29 +137,141 @@
23  
24  #endif
25  
26 -void show_trace(unsigned long * stack)
27 +void scan_stack (unsigned long *stack)
28  {
29         int i;
30         unsigned long addr;
31 -       /* static to not take up stackspace; if we race here too bad */
32 -       static char buffer[512];
33 +       /* static to not take up stackspace */
34 +       static char buffer[NR_CPUS][512], *bufp;
35  
36 -       if (!stack)
37 -               stack = (unsigned long*)&stack;
38 +       bufp = buffer[smp_processor_id()];
39  
40 -       printk("Call Trace:   ");
41 +       /*
42 +        * If we have frame pointers then use them to get
43 +        * a 100% exact backtrace, up until the entry frame:
44 +        */
45         i = 1;
46         while (((long) stack & (THREAD_SIZE-1)) != 0) {
47                 addr = *stack++;
48                 if (kernel_text_address(addr)) {
49 -                       lookup_symbol(addr, buffer, 512);
50 -                       printk("[<%08lx>] %s (0x%x))\n", addr,buffer,stack-1);
51 +                       lookup_symbol(addr, bufp, 512);
52 +                       printk("[<%08lx>] %s (0x%p)\n", addr,bufp,stack-1);
53                         i++;
54                 }
55         }
56 +}
57 +
58 +#if CONFIG_FRAME_POINTER
59 +void show_stack_frame_params (int param_count, unsigned long params[])
60 +{
61 +       int i;
62 +       unsigned long *p, task_addr, stack_base;
63 +
64 +       if (param_count <= 0)
65 +               return;
66 +
67 +       task_addr = (unsigned long) current;
68 +       stack_base = task_addr + THREAD_SIZE - 1;
69 +
70 +       printk("             (");
71 +
72 +       for (i = 0, p = params;
73 +            ((param_count - i) > 1) && (p >= task_addr) && (p <= stack_base);
74 +            i++, p++) {
75 +               printk("0x%x, ", *p);
76 +
77 +               if ((i % 4) == 3)
78 +                       printk("\n              ");
79 +       }
80 +
81 +       if ((p >= task_addr) && (p <= stack_base))
82 +               printk("0x%x)\n", *p);
83 +}
84 +
85 +/* Display a stack trace for the currently executing task.  The 'dummy'
86 + * parameter serves a purpose although its value is unused.  We use the
87 + * address of 'dummy' as a reference point for finding the saved %ebp register
88 + * value on the stack.
89 + */
90 +void frame_pointer_walk (void *dummy)
91 +{
92 +       int i;
93 +       unsigned long addr, task_addr, *frame_ptr, *next_frame_ptr, *eip_ptr,
94 +                     eip, stack_base;
95 +       /* static to not take up stackspace */
96 +       static char buffer[NR_CPUS][512], *bufp;
97 +
98 +       bufp = buffer[smp_processor_id()];
99 +       task_addr = (unsigned long) current;
100 +       stack_base = task_addr + THREAD_SIZE - 1;
101 +       frame_ptr = (unsigned long *) (&dummy - 2);
102 +
103 +       for (; ; ) {
104 +               next_frame_ptr = (unsigned long *) (*frame_ptr);
105 +               addr = (unsigned long) next_frame_ptr;
106 +
107 +               /* Stop when we reach a frame pointer that points to a
108 +                * location clearly outside our own kernel stack.
109 +                */
110 +               if ((addr < task_addr) || (addr > stack_base))
111 +                       break;
112 +
113 +               eip_ptr = frame_ptr + 1;
114 +               eip = *eip_ptr;
115 +
116 +               if (kernel_text_address(eip)) {
117 +                       lookup_symbol(eip, bufp, 512);
118 +                       show_stack_frame_params(4, frame_ptr + 2);
119 +                       printk("[<%08lx>] %s (0x%x)\n", eip, bufp,
120 +                              eip_ptr);
121 +               }
122 +
123 +               frame_ptr = next_frame_ptr;
124 +       }
125 +}
126 +
127 +typedef void (*stack_trace_fn_t) (unsigned long *stack);
128 +
129 +void show_trace(unsigned long * stack)
130 +{
131 +       static const stack_trace_fn_t trace_fn_vector[] =
132 +               { scan_stack, frame_pointer_walk };
133 +       unsigned long addr, task_addr, stack_base;
134 +       int task_is_current;
135 +
136 +       if (!stack)
137 +               stack = (unsigned long*)&stack;
138 +
139 +       printk("Call Trace:\n");
140 +       addr = (unsigned long) stack;
141 +       task_addr = (unsigned long) current;
142 +       stack_base = task_addr + THREAD_SIZE - 1;
143 +       task_is_current = (addr >= task_addr) && (addr <= stack_base);
144 +
145 +       /* We may use frame pointers to do a stack trace only if the current
146 +        * task is being traced.  Tracing some other task in this manner
147 +        * would require a saved %ebp register value.  Perhaps in the future
148 +        * I'll consider providing a means of obtaining this.
149 +        */
150 +       trace_fn_vector[task_is_current](stack);
151 +
152         printk("\n");
153  }
154  
155 +#else /* CONFIG_FRAME_POINTER */
156 +
157 +void show_trace(unsigned long * stack)
158 +{
159 +       if (!stack)
160 +               stack = (unsigned long*)&stack;
161 +
162 +       printk("Call Trace:\n");
163 +       scan_stack(stack);
164 +       printk("\n");
165 +}
166 +
167 +#endif /* CONFIG_FRAME_POINTER */
168 +
169  void show_trace_task(struct task_struct *tsk)
170  {
171         unsigned long esp = tsk->thread.esp;