Whamcloud - gitweb
b=17167 libcfs: ensure all libcfs exported symbols to have cfs_ prefix
[fs/lustre-release.git] / libcfs / libcfs / darwin / darwin-tracefile.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #define DEBUG_SUBSYSTEM S_LNET
38 #define LUSTRE_TRACEFILE_PRIVATE
39 #include <libcfs/libcfs.h>
40 #include "tracefile.h"
41
42 /*
43  * We can't support smp tracefile currently.
44  * Everything is put on one cpu.
45  */
46
47 #define M_TCD_MAX_PAGES (128 * 1280)
48
49 static long max_permit_mb = (64 * 1024);
50
51 spinlock_t trace_cpu_serializer;
52
53 /*
54  * thread currently executing tracefile code or NULL if none does. Used to
55  * detect recursive calls to libcfs_debug_msg().
56  */
57 static thread_t trace_owner = NULL;
58
59 extern int get_preemption_level(void);
60 extern atomic_t tage_allocated;
61
62 struct rw_semaphore tracefile_sem;
63
64 int tracefile_init_arch() {
65     init_rwsem(&tracefile_sem);
66 #error "Todo: initialise per-cpu console buffers"
67     return 0;
68 }
69
70 void tracefile_fini_arch() {
71     fini_rwsem(&tracefile_sem);
72 }
73
74 void tracefile_read_lock() {
75     down_read(&tracefile_sem);
76 }
77
78 void tracefile_read_unlock() {
79     up_read(&tracefile_sem);
80 }
81
82 void tracefile_write_lock() {
83     down_write(&tracefile_sem);
84 }
85
86 void tracefile_write_unlock() {
87     up_write(&tracefile_sem);
88 }
89
90 char *trace_get_console_buffer(void)
91 {
92 #error "todo: return a per-cpu/interrupt console buffer and disable pre-emption"
93 }
94
95 void trace_put_console_buffer(char *buffer)
96 {
97 #error "todo: re-enable pre-emption"
98 }
99
100 struct trace_cpu_data *trace_get_tcd(void)
101 {
102         struct trace_cpu_data *tcd;
103         int nr_pages;
104         struct list_head pages;
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
111         /*
112          * debugging check for recursive call to libcfs_debug_msg()
113          */
114         if (trace_owner == current_thread()) {
115                 /*
116                  * Cannot assert here.
117                  */
118                 printk(KERN_EMERG "recursive call to %s", __FUNCTION__);
119                 /*
120                  * "The death of God left the angels in a strange position."
121                  */
122                 cfs_enter_debugger();
123         }
124         tcd = &trace_data[0].tcd;
125         CFS_INIT_LIST_HEAD(&pages);
126         if (get_preemption_level() == 0)
127                 nr_pages = trace_refill_stock(tcd, CFS_ALLOC_STD, &pages);
128         else
129                 nr_pages = 0;
130         spin_lock(&trace_cpu_serializer);
131         trace_owner = current_thread();
132         tcd->tcd_cur_stock_pages += nr_pages;
133         list_splice(&pages, &tcd->tcd_stock_pages);
134         return tcd;
135 }
136
137 extern void raw_page_death_row_clean(void);
138
139 void __trace_put_tcd(struct trace_cpu_data *tcd)
140 {
141         /*
142          * XXX nikita: do NOT call libcfs_debug_msg() (CDEBUG/ENTRY/EXIT)
143          * from here: this will lead to infinite recursion.
144          */
145         LASSERT(trace_owner == current_thread());
146         trace_owner = NULL;
147         spin_unlock(&trace_cpu_serializer);
148         if (get_preemption_level() == 0)
149                 /* purge all pending pages */
150                 raw_page_death_row_clean();
151 }
152
153 int tcd_owns_tage(struct trace_cpu_data *tcd, struct trace_page *tage)
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         /* XNU has global tcd, and all pages are owned by it */
160         return 1;
161 }
162
163 void
164 set_ptldebug_header(struct ptldebug_header *header, int subsys, int mask,
165                     const int line, unsigned long stack)
166 {
167         struct timeval tv;
168         
169         /*
170          * XXX nikita: do NOT call libcfs_debug_msg() (CDEBUG/ENTRY/EXIT)
171          * from here: this will lead to infinite recursion.
172          */
173         do_gettimeofday(&tv);
174         header->ph_subsys = subsys;
175         header->ph_mask = mask;
176         header->ph_cpu_id = smp_processor_id();
177         header->ph_sec = (__u32)tv.tv_sec;
178         header->ph_usec = tv.tv_usec;
179         header->ph_stack = stack;
180         header->ph_pid = cfs_curproc_pid();
181         header->ph_line_num = line;
182         header->ph_extern_pid = (__u32)current_thread();
183 }
184
185 void print_to_console(struct ptldebug_header *hdr, int mask, const char *buf,
186                       int len, const char *file, const char *fn)
187 {
188         char *prefix = "Lustre", *ptype = KERN_INFO;
189
190         /*
191          * XXX nikita: do NOT call libcfs_debug_msg() (CDEBUG/ENTRY/EXIT)
192          * from here: this will lead to infinite recursion.
193          */
194         if ((mask & D_EMERG) != 0) {
195                 prefix = "LustreError";
196                 ptype = KERN_EMERG;
197         } else if ((mask & D_ERROR) != 0) {
198                 prefix = "LustreError";
199                 ptype = KERN_ERR;
200         } else if ((mask & D_WARNING) != 0) {
201                 prefix = "Lustre";
202                 ptype = KERN_WARNING;
203         } else if ((mask & libcfs_printk) != 0 || (mask & D_CONSOLE)) {
204                 prefix = "Lustre";
205                 ptype = KERN_INFO;
206         }
207
208         if ((mask & D_CONSOLE) != 0) {
209                 printk("%s%s: %.*s", ptype, prefix, len, buf);
210         } else {
211                 printk("%s%s: %d:%d:(%s:%d:%s()) %*s",
212                        ptype, prefix, hdr->ph_pid, hdr->ph_extern_pid,
213                        file, hdr->ph_line_num, fn, len, buf);
214         }
215 }
216
217 int trace_max_debug_mb(void)
218 {
219         return max_permit_mb;
220 }