1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=4:tabstop=4:
4 * Copyright (c) 2004 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or modify it under
9 * the terms of version 2 of the GNU General Public License as published by
10 * the Free Software Foundation. Lustre is distributed in the hope that it
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. You should have received a
14 * copy of the GNU General Public License along with Lustre; if not, write
15 * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
19 #define DEBUG_SUBSYSTEM S_LNET
20 #define LUSTRE_TRACEFILE_PRIVATE
22 #include <libcfs/libcfs.h>
23 #include <libcfs/kp30.h>
24 #include "tracefile.h"
27 #define get_cpu() smp_processor_id()
28 #define put_cpu() do { } while (0)
31 extern union trace_data_union trace_data[NR_CPUS];
32 extern char *tracefile;
33 extern int64_t tracefile_size;
35 event_t tracefile_event;
37 void tracefile_init_arch()
42 cfs_init_event(&tracefile_event, TRUE, TRUE);
44 memset(trace_console_buffers, 0, sizeof(trace_console_buffers));
46 for (i = 0; i < NR_CPUS; i++) {
47 for (j = 0; j < 1; j++) {
48 trace_console_buffers[i][j] =
49 cfs_alloc(TRACE_CONSOLE_BUFFER_SIZE,
52 if (trace_console_buffers[i][j] == NULL) {
53 tracefile_fini_arch();
54 KsPrint((0, "Can't allocate console message buffer\n"));
63 void tracefile_fini_arch()
68 for (i = 0; i < NR_CPUS; i++) {
69 for (j = 0; j < 2; j++) {
70 if (trace_console_buffers[i][j] != NULL) {
71 cfs_free(trace_console_buffers[i][j]);
72 trace_console_buffers[i][j] = NULL;
78 void tracefile_read_lock()
80 cfs_wait_event(&tracefile_event, 0);
83 void tracefile_read_unlock()
85 cfs_wake_event(&tracefile_event);
88 void tracefile_write_lock()
90 cfs_wait_event(&tracefile_event, 0);
93 void tracefile_write_unlock()
95 cfs_wake_event(&tracefile_event);
99 trace_get_console_buffer(void)
101 #pragma message ("is there possible problem with pre-emption ?")
102 int cpu = (int) KeGetCurrentProcessorNumber();
103 return trace_console_buffers[cpu][0];
107 trace_put_console_buffer(char *buffer)
111 struct trace_cpu_data *
114 #pragma message("todo: return NULL if in interrupt context")
116 int cpu = (int) KeGetCurrentProcessorNumber();
117 return &trace_data[cpu].tcd;
121 trace_put_tcd (struct trace_cpu_data *tcd, unsigned long flags)
126 set_ptldebug_header(struct ptldebug_header *header, int subsys, int mask,
127 const int line, unsigned long stack)
131 do_gettimeofday(&tv);
133 header->ph_subsys = subsys;
134 header->ph_mask = mask;
135 header->ph_cpu_id = smp_processor_id();
136 header->ph_sec = (__u32)tv.tv_sec;
137 header->ph_usec = tv.tv_usec;
138 header->ph_stack = stack;
139 header->ph_pid = current->pid;
140 header->ph_line_num = line;
141 header->ph_extern_pid = 0;
145 void print_to_console(struct ptldebug_header *hdr, int mask, const char *buf,
146 int len, const char *file, const char *fn)
148 char *prefix = NULL, *ptype = NULL;
150 if ((mask & D_EMERG) != 0) {
151 prefix = "LustreError";
153 } else if ((mask & D_ERROR) != 0) {
154 prefix = "LustreError";
156 } else if ((mask & D_WARNING) != 0) {
158 ptype = KERN_WARNING;
159 } else if ((mask & libcfs_printk) != 0 || (mask & D_CONSOLE)) {
164 if ((mask & D_CONSOLE) != 0) {
165 printk("%s%s: %s", ptype, prefix, buf);
167 printk("%s%s: %d:%d:(%s:%d:%s()) %s", ptype, prefix, hdr->ph_pid,
168 hdr->ph_extern_pid, file, hdr->ph_line_num, fn, buf);
173 int tcd_owns_tage(struct trace_cpu_data *tcd, struct trace_page *tage)
179 int trace_write_daemon_file(struct file *file, const char *buffer,
180 unsigned long count, void *data)
186 name =cfs_alloc(count + 1, 0);
190 if (copy_from_user((void *)name, (void*)buffer, count)) {
195 /* be nice and strip out trailing '\n' */
196 for (off = count ; off > 2 && isspace(name[off - 1]); off--)
201 tracefile_write_lock();
202 if (strcmp(name, "stop") == 0) {
206 } else if (strncmp(name, "size=", 5) == 0) {
207 tracefile_size = simple_strtoul(name + 5, NULL, 0);
208 if (tracefile_size < 10 || tracefile_size > 20480)
209 tracefile_size = TRACEFILE_SIZE;
211 tracefile_size <<= 20;
215 if (tracefile != NULL)
220 printk(KERN_INFO "Lustre: debug daemon will attempt to start writing "
221 "to %s (%lukB max)\n", tracefile, (long)(tracefile_size >> 10));
223 trace_start_thread();
225 tracefile_write_unlock();
232 int trace_read_daemon_file(char *page, char **start, off_t off, int count,
233 int *eof, void *data)
237 tracefile_read_lock();
238 rc = snprintf(page, count, "%s", tracefile);
239 tracefile_read_unlock();
244 int trace_write_debug_mb(struct file *file, const char *buffer,
245 unsigned long count, void *data)
251 if (count >= sizeof(string)) {
252 printk(KERN_ERR "Lustre: value too large (length %lu bytes)\n",
257 if (copy_from_user((void *)string, (void *)buffer, count))
260 max = simple_strtoul(string, NULL, 0);
264 if (max > (num_physpages >> (20 - 2 - CFS_PAGE_SHIFT)) / 5 || max >= 512) {
265 printk(KERN_ERR "Lustre: Refusing to set debug buffer size to "
266 "%dMB, which is more than 80%% of available RAM (%lu)\n",
267 max, (num_physpages >> (20 - 2 - CFS_PAGE_SHIFT)) / 5);
273 for (i = 0; i < NR_CPUS; i++) {
274 struct trace_cpu_data *tcd;
275 tcd = &trace_data[i].tcd;
276 tcd->tcd_max_pages = max << (20 - CFS_PAGE_SHIFT);
281 int trace_read_debug_mb(char *page, char **start, off_t off, int count,
282 int *eof, void *data)
284 struct trace_cpu_data *tcd;
287 tcd = trace_get_tcd();
288 LASSERT (tcd != NULL);
289 rc = snprintf(page, count, "%lu\n",
290 (tcd->tcd_max_pages >> (20 - CFS_PAGE_SHIFT)) * smp_num_cpus);
296 trace_call_on_all_cpus(void (*fn)(void *arg), void *arg)