Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / libcfs / libcfs / darwin / darwin-tracefile.c
1
2 #define DEBUG_SUBSYSTEM S_LNET
3 #define LUSTRE_TRACEFILE_PRIVATE
4 #include <libcfs/libcfs.h>
5 #include "tracefile.h"
6
7 /*
8  * We can't support smp tracefile currently.
9  * Everything is put on one cpu.
10  */
11
12 #define M_TCD_MAX_PAGES (128 * 1280)
13
14 static long max_permit_mb = (64 * 1024);
15
16 spinlock_t trace_cpu_serializer;
17
18 /*
19  * thread currently executing tracefile code or NULL if none does. Used to
20  * detect recursive calls to libcfs_debug_msg().
21  */
22 static thread_t trace_owner = NULL;
23
24 extern int get_preemption_level(void);
25 extern atomic_t tage_allocated;
26
27 struct rw_semaphore tracefile_sem;
28
29 int tracefile_init_arch() {
30     init_rwsem(&tracefile_sem);
31 #error "Todo: initialise per-cpu console buffers"
32     return 0;
33 }
34
35 void tracefile_fini_arch() {
36 }
37
38 void tracefile_read_lock() {
39     down_read(&tracefile_sem);
40 }
41
42 void tracefile_read_unlock() {
43     up_read(&tracefile_sem);
44 }
45
46 void tracefile_write_lock() {
47     down_write(&tracefile_sem);
48 }
49
50 void tracefile_write_unlock() {
51     up_write(&tracefile_sem);
52 }
53
54 char *trace_get_console_buffer(void)
55 {
56 #error "todo: return a per-cpu/interrupt console buffer and disable pre-emption"
57 }
58
59 void trace_put_console_buffer(char *buffer)
60 {
61 #error "todo: re-enable pre-emption"
62 }
63
64 struct trace_cpu_data *trace_get_tcd(void)
65 {
66         struct trace_cpu_data *tcd;
67         int nr_pages;
68         struct list_head pages;
69
70         /*
71          * XXX nikita: do NOT call libcfs_debug_msg() (CDEBUG/ENTRY/EXIT)
72          * from here: this will lead to infinite recursion.
73          */
74
75         /*
76          * debugging check for recursive call to libcfs_debug_msg()
77          */
78         if (trace_owner == current_thread()) {
79                 /*
80                  * Cannot assert here.
81                  */
82                 printk(KERN_EMERG "recursive call to %s", __FUNCTION__);
83                 /*
84                  * "The death of God left the angels in a strange position."
85                  */
86                 cfs_enter_debugger();
87         }
88         tcd = &trace_data[0].tcd;
89         CFS_INIT_LIST_HEAD(&pages);
90         if (get_preemption_level() == 0)
91                 nr_pages = trace_refill_stock(tcd, CFS_ALLOC_STD, &pages);
92         else
93                 nr_pages = 0;
94         spin_lock(&trace_cpu_serializer);
95         trace_owner = current_thread();
96         tcd->tcd_cur_stock_pages += nr_pages;
97         list_splice(&pages, &tcd->tcd_stock_pages);
98         return tcd;
99 }
100
101 extern void raw_page_death_row_clean(void);
102
103 void __trace_put_tcd(struct trace_cpu_data *tcd)
104 {
105         /*
106          * XXX nikita: do NOT call libcfs_debug_msg() (CDEBUG/ENTRY/EXIT)
107          * from here: this will lead to infinite recursion.
108          */
109         LASSERT(trace_owner == current_thread());
110         trace_owner = NULL;
111         spin_unlock(&trace_cpu_serializer);
112         if (get_preemption_level() == 0)
113                 /* purge all pending pages */
114                 raw_page_death_row_clean();
115 }
116
117 int tcd_owns_tage(struct trace_cpu_data *tcd, struct trace_page *tage)
118 {
119         /*
120          * XXX nikita: do NOT call libcfs_debug_msg() (CDEBUG/ENTRY/EXIT)
121          * from here: this will lead to infinite recursion.
122          */
123         /* XNU has global tcd, and all pages are owned by it */
124         return 1;
125 }
126
127 void
128 set_ptldebug_header(struct ptldebug_header *header, int subsys, int mask,
129                     const int line, unsigned long stack)
130 {
131         struct timeval tv;
132         
133         /*
134          * XXX nikita: do NOT call libcfs_debug_msg() (CDEBUG/ENTRY/EXIT)
135          * from here: this will lead to infinite recursion.
136          */
137         do_gettimeofday(&tv);
138         header->ph_subsys = subsys;
139         header->ph_mask = mask;
140         header->ph_cpu_id = smp_processor_id();
141         header->ph_sec = (__u32)tv.tv_sec;
142         header->ph_usec = tv.tv_usec;
143         header->ph_stack = stack;
144         header->ph_pid = cfs_curproc_pid();
145         header->ph_line_num = line;
146         header->ph_extern_pid = (__u32)current_thread();
147 }
148
149 void print_to_console(struct ptldebug_header *hdr, int mask, const char *buf,
150                       int len, const char *file, const char *fn)
151 {
152         char *prefix = "Lustre", *ptype = KERN_INFO;
153
154         /*
155          * XXX nikita: do NOT call libcfs_debug_msg() (CDEBUG/ENTRY/EXIT)
156          * from here: this will lead to infinite recursion.
157          */
158         if ((mask & D_EMERG) != 0) {
159                 prefix = "LustreError";
160                 ptype = KERN_EMERG;
161         } else if ((mask & D_ERROR) != 0) {
162                 prefix = "LustreError";
163                 ptype = KERN_ERR;
164         } else if ((mask & D_WARNING) != 0) {
165                 prefix = "Lustre";
166                 ptype = KERN_WARNING;
167         } else if ((mask & libcfs_printk) != 0 || (mask & D_CONSOLE)) {
168                 prefix = "Lustre";
169                 ptype = KERN_INFO;
170         }
171
172         if ((mask & D_CONSOLE) != 0) {
173                 printk("%s%s: %.*s", ptype, prefix, len, buf);
174         } else {
175                 printk("%s%s: %d:%d:(%s:%d:%s()) %*s",
176                        ptype, prefix, hdr->ph_pid, hdr->ph_extern_pid,
177                        file, hdr->ph_line_num, fn, len, buf);
178         }
179 }
180
181 int trace_max_debug_mb(void)
182 {
183         return max_permit_mb;
184 }
185
186 void
187 trace_call_on_all_cpus(void (*fn)(void *arg), void *arg)
188 {
189 #error "tbd"
190 }