Whamcloud - gitweb
7d6643b342f908dd6dff5a0e162da099c928e7db
[fs/lustre-release.git] / lnet / libcfs / linux / linux-tracefile.c
1 #define DEBUG_SUBSYSTEM S_LNET
2 #define LUSTRE_TRACEFILE_PRIVATE
3
4 #include <libcfs/libcfs.h>
5 #include <libcfs/kp30.h>
6 #include "tracefile.h"
7
8 #ifndef get_cpu
9 #define get_cpu() smp_processor_id()
10 #define put_cpu() do { } while (0)
11 #endif
12
13 extern union trace_data_union trace_data[NR_CPUS];
14
15 char *trace_console_buffers[NR_CPUS][3];
16
17 struct rw_semaphore tracefile_sem;
18
19 int tracefile_init_arch()
20 {
21         int    i;
22         int    j;
23
24         init_rwsem(&tracefile_sem);
25
26         for (i = 0; i < num_possible_cpus(); i++)
27                 for (j = 0; j < 3; j++) {
28                         trace_console_buffers[i][j] =
29                                 kmalloc(TRACE_CONSOLE_BUFFER_SIZE,
30                                         GFP_KERNEL);
31
32                         if (trace_console_buffers[i][j] == NULL) {
33                                 tracefile_fini_arch();
34                                 printk(KERN_ERR
35                                        "Can't allocate "
36                                        "console message buffer\n");
37                                 return -ENOMEM;
38                         }
39                 }
40
41         return 0;
42 }
43
44 void tracefile_fini_arch()
45 {
46         int    i;
47         int    j;
48
49         for (i = 0; i < num_possible_cpus(); i++)
50                 for (j = 0; j < 3; j++)
51                         if (trace_console_buffers[i][j] != NULL) {
52                                 kfree(trace_console_buffers[i][j]);
53                                 trace_console_buffers[i][j] = NULL;
54                         }
55 }
56
57 void tracefile_read_lock()
58 {
59         down_read(&tracefile_sem);
60 }
61
62 void tracefile_read_unlock()
63 {
64         up_read(&tracefile_sem);
65 }
66
67 void tracefile_write_lock()
68 {
69         down_write(&tracefile_sem);
70 }
71
72 void tracefile_write_unlock()
73 {
74         up_write(&tracefile_sem);
75 }
76
77 char *
78 trace_get_console_buffer(void)
79 {
80         int  cpu = get_cpu();
81         int  idx;
82
83         if (in_irq()) {
84                 idx = 0;
85         } else if (in_softirq()) {
86                 idx = 1;
87         } else {
88                 idx = 2;
89         }
90
91         return trace_console_buffers[cpu][idx];
92 }
93
94 void
95 trace_put_console_buffer(char *buffer)
96 {
97         put_cpu();
98 }
99
100 struct trace_cpu_data *
101 trace_get_tcd(void)
102 {
103         int cpu;
104
105         if (in_interrupt()) /* no logging in IRQ context */
106                 return NULL;
107
108         cpu = get_cpu();
109         return &trace_data[cpu].tcd;
110 }
111
112 void
113 trace_put_tcd (struct trace_cpu_data *tcd)
114 {
115         __LASSERT (!in_interrupt());
116         put_cpu();
117 }
118
119 int tcd_owns_tage(struct trace_cpu_data *tcd, struct trace_page *tage)
120 {
121         /*
122          * XXX nikita: do NOT call portals_debug_msg() (CDEBUG/ENTRY/EXIT)
123          * from here: this will lead to infinite recursion.
124          */
125         return tcd->tcd_cpu == tage->cpu;
126 }
127
128 void
129 set_ptldebug_header(struct ptldebug_header *header, int subsys, int mask,
130                     const int line, unsigned long stack)
131 {
132         struct timeval tv;
133
134         do_gettimeofday(&tv);
135
136         header->ph_subsys = subsys;
137         header->ph_mask = mask;
138         header->ph_cpu_id = smp_processor_id();
139         header->ph_sec = (__u32)tv.tv_sec;
140         header->ph_usec = tv.tv_usec;
141         header->ph_stack = stack;
142         header->ph_pid = current->pid;
143         header->ph_line_num = line;
144 #if defined(__arch_um__) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
145         header->ph_extern_pid = current->thread.extern_pid;
146 #elif defined(__arch_um__) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
147         header->ph_extern_pid = current->thread.mode.tt.extern_pid;
148 #else
149         header->ph_extern_pid = 0;
150 #endif
151         return;
152 }
153
154 void print_to_console(struct ptldebug_header *hdr, int mask, const char *buf,
155                              int len, const char *file, const char *fn)
156 {
157         char *prefix = "Lustre", *ptype = NULL;
158
159         if ((mask & D_EMERG) != 0) {
160                 prefix = "LustreError";
161                 ptype = KERN_EMERG;
162         } else if ((mask & D_ERROR) != 0) {
163                 prefix = "LustreError";
164                 ptype = KERN_ERR;
165         } else if ((mask & D_WARNING) != 0) {
166                 prefix = "Lustre";
167                 ptype = KERN_WARNING;
168         } else if ((mask & libcfs_printk) != 0 || (mask & D_CONSOLE)) {
169                 prefix = "Lustre";
170                 ptype = KERN_INFO;
171         }
172
173         if ((mask & D_CONSOLE) != 0) {
174                 printk("%s%s: %.*s", ptype, prefix, len, buf);
175         } else {
176                 printk("%s%s: %d:%d:(%s:%d:%s()) %.*s", ptype, prefix, hdr->ph_pid,
177                        hdr->ph_extern_pid, file, hdr->ph_line_num, fn, len, buf);
178         }
179         return;
180 }
181
182 int trace_max_debug_mb(void)
183 {
184         int  total_mb = (num_physpages >> (20 - CFS_PAGE_SHIFT));
185         
186         return MAX(512, (total_mb * 80)/100);
187 }
188
189 void
190 trace_call_on_all_cpus(void (*fn)(void *arg), void *arg)
191 {
192         cpumask_t cpus_allowed = current->cpus_allowed;
193         /* use cpus_allowed to quiet 2.4 UP kernel warning only */
194         cpumask_t m = cpus_allowed;
195         int       cpu;
196
197         /* Run the given routine on every CPU in thread context */
198         for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
199                 if (!cpu_online(cpu))
200                         continue;
201
202                 cpus_clear(m);
203                 cpu_set(cpu, m);
204                 set_cpus_allowed(current, m);
205
206                 fn(arg);
207
208                 set_cpus_allowed(current, cpus_allowed);
209         }
210 }