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