-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* GPL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
char cfs_tracefile[TRACEFILE_NAME_SIZE];
long long cfs_tracefile_size = CFS_TRACEFILE_SIZE;
static struct tracefiled_ctl trace_tctl;
-cfs_semaphore_t cfs_trace_thread_sem;
+cfs_mutex_t cfs_trace_thread_mutex;
static int thread_running = 0;
cfs_atomic_t cfs_tage_allocated = CFS_ATOMIC_INIT(0);
cfs_page_t *page;
struct cfs_trace_page *tage;
+ /* My caller is trying to free memory */
+ if (!cfs_in_interrupt() && cfs_memory_pressure_get())
+ return NULL;
+
/*
* Don't spam console with allocation failures: they will be reported
* by upper layer anyway.
return tage;
}
-int libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, int subsys, int mask,
- const char *file, const char *fn, const int line,
+int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata,
+ const char *format, ...)
+{
+ va_list args;
+ int rc;
+
+ va_start(args, format);
+ rc = libcfs_debug_vmsg2(msgdata, format, args, NULL);
+ va_end(args);
+
+ return rc;
+}
+EXPORT_SYMBOL(libcfs_debug_msg);
+
+int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
const char *format1, va_list args,
const char *format2, ...)
{
int depth;
int i;
int remain;
+ int mask = msgdata->msg_mask;
+ char *file = (char *)msgdata->msg_file;
+ cfs_debug_limit_state_t *cdls = msgdata->msg_cdls;
if (strchr(file, '/'))
file = strrchr(file, '/') + 1;
+ tcd = cfs_trace_get_tcd();
- cfs_set_ptldebug_header(&header, subsys, mask, line, CDEBUG_STACK());
+ /* cfs_trace_get_tcd() grabs a lock, which disables preemption and
+ * pins us to a particular CPU. This avoids an smp_processor_id()
+ * warning on Linux when debugging is enabled. */
+ cfs_set_ptldebug_header(&header, msgdata, CDEBUG_STACK());
- tcd = cfs_trace_get_tcd();
if (tcd == NULL) /* arch may not log in IRQ context */
goto console;
depth = __current_nesting_level();
known_size = strlen(file) + 1 + depth;
- if (fn)
- known_size += strlen(fn) + 1;
+ if (msgdata->msg_fn)
+ known_size += strlen(msgdata->msg_fn) + 1;
if (libcfs_debug_binary)
known_size += sizeof(header);
max_nob = CFS_PAGE_SIZE - tage->used - known_size;
if (max_nob <= 0) {
- printk(CFS_KERN_EMERG "negative max_nob: %i\n",
+ printk(CFS_KERN_EMERG "negative max_nob: %d\n",
max_nob);
mask |= D_ERROR;
cfs_trace_put_tcd(tcd);
}
if (*(string_buf+needed-1) != '\n')
- printk(CFS_KERN_INFO "format at %s:%d:%s doesn't end in newline\n",
- file, line, fn);
+ printk(CFS_KERN_INFO "format at %s:%d:%s doesn't end in "
+ "newline\n", file, msgdata->msg_line, msgdata->msg_fn);
header.ph_len = known_size + needed;
debug_buf = (char *)cfs_page_address(tage->page) + tage->used;
tage->used += strlen(file) + 1;
debug_buf += strlen(file) + 1;
- if (fn) {
- strcpy(debug_buf, fn);
- tage->used += strlen(fn) + 1;
- debug_buf += strlen(fn) + 1;
+ if (msgdata->msg_fn) {
+ strcpy(debug_buf, msgdata->msg_fn);
+ tage->used += strlen(msgdata->msg_fn) + 1;
+ debug_buf += strlen(msgdata->msg_fn) + 1;
}
__LASSERT(debug_buf == string_buf);
if (tcd != NULL) {
cfs_print_to_console(&header, mask, string_buf, needed, file,
- fn);
+ msgdata->msg_fn);
cfs_trace_put_tcd(tcd);
} else {
string_buf = cfs_trace_get_console_buffer();
remain = CFS_TRACE_CONSOLE_BUFFER_SIZE - needed;
if (remain > 0) {
va_start(ap, format2);
- needed += vsnprintf(string_buf+needed, remain, format2, ap);
+ needed += vsnprintf(string_buf+needed, remain,
+ format2, ap);
va_end(ap);
}
}
cfs_print_to_console(&header, mask,
- string_buf, needed, file, fn);
+ string_buf, needed, file, msgdata->msg_fn);
cfs_trace_put_console_buffer(string_buf);
}
string_buf = cfs_trace_get_console_buffer();
needed = snprintf(string_buf, CFS_TRACE_CONSOLE_BUFFER_SIZE,
- "Skipped %d previous similar message%s\n",
- cdls->cdls_count, (cdls->cdls_count > 1) ? "s" : "");
+ "Skipped %d previous similar message%s\n",
+ cdls->cdls_count,
+ (cdls->cdls_count > 1) ? "s" : "");
cfs_print_to_console(&header, mask,
- string_buf, needed, file, fn);
+ string_buf, needed, file, msgdata->msg_fn);
cfs_trace_put_console_buffer(string_buf);
cdls->cdls_count = 0;
EXPORT_SYMBOL(libcfs_debug_vmsg2);
void
-libcfs_assertion_failed(const char *expr, const char *file,
- const char *func, const int line)
+libcfs_assertion_failed(const char *expr, struct libcfs_debug_msg_data *msgdata)
{
- libcfs_debug_msg(NULL, 0, D_EMERG, file, func, line,
- "ASSERTION(%s) failed\n", expr);
+ libcfs_debug_msg(msgdata, "ASSERTION(%s) failed\n", expr);
/* cfs_enter_debugger(); */
- lbug_with_loc(file, func, line);
+ lbug_with_loc(msgdata);
}
EXPORT_SYMBOL(libcfs_assertion_failed);
void
cfs_trace_assertion_failed(const char *str,
- const char *fn, const char *file, int line)
+ struct libcfs_debug_msg_data *msgdata)
{
struct ptldebug_header hdr;
libcfs_catastrophe = 1;
cfs_mb();
- cfs_set_ptldebug_header(&hdr, DEBUG_SUBSYSTEM, D_EMERG, line,
- CDEBUG_STACK());
+ cfs_set_ptldebug_header(&hdr, msgdata, CDEBUG_STACK());
- cfs_print_to_console(&hdr, D_EMERG, str, strlen(str), file, fn);
+ cfs_print_to_console(&hdr, D_EMERG, str, strlen(str),
+ msgdata->msg_file, msgdata->msg_fn);
LIBCFS_PANIC("Lustre debug assertion failure\n");
knl_buffer[nob + 1] = 0; /* terminate */
return 0;
}
+EXPORT_SYMBOL(cfs_trace_copyin_string);
int cfs_trace_copyout_string(char *usr_buffer, int usr_buffer_nob,
const char *knl_buffer, char *append)
struct cfs_trace_cpu_data *tcd;
if (mb < cfs_num_possible_cpus()) {
- printk(KERN_ERR "Cannot set debug_mb to %d, the value should be >= %d\n",
- mb, cfs_num_possible_cpus());
- return -EINVAL;
+ printk(CFS_KERN_WARNING
+ "Lustre: %d MB is too small for debug buffer size, "
+ "setting it to %d MB.\n", mb, cfs_num_possible_cpus());
+ mb = cfs_num_possible_cpus();
}
if (mb > limit) {
- printk(CFS_KERN_ERR "Lustre: Refusing to set debug buffer size "
- "to %dMB - limit is %d\n", mb, limit);
- return -EINVAL;
+ printk(CFS_KERN_WARNING
+ "Lustre: %d MB is too large for debug buffer size, "
+ "setting it to %d MB.\n", mb, limit);
+ mb = limit;
}
mb /= cfs_num_possible_cpus();
printk(CFS_KERN_ERR "total cpus(%d): ",
cfs_num_possible_cpus());
for (i = 0; i < cfs_num_possible_cpus(); i++)
- if (cfs_cpu_online(i))
+ if (cpu_online(i))
printk(CFS_KERN_ERR "%d(on) ", i);
else
printk(CFS_KERN_ERR "%d(off) ", i);
struct tracefiled_ctl *tctl = &trace_tctl;
int rc = 0;
- cfs_mutex_down(&cfs_trace_thread_sem);
+ cfs_mutex_lock(&cfs_trace_thread_mutex);
if (thread_running)
goto out;
cfs_waitq_init(&tctl->tctl_waitq);
cfs_atomic_set(&tctl->tctl_shutdown, 0);
- if (cfs_kernel_thread(tracefiled, tctl, 0) < 0) {
+ if (cfs_create_thread(tracefiled, tctl, 0) < 0) {
rc = -ECHILD;
goto out;
}
cfs_wait_for_completion(&tctl->tctl_start);
thread_running = 1;
out:
- cfs_mutex_up(&cfs_trace_thread_sem);
+ cfs_mutex_unlock(&cfs_trace_thread_mutex);
return rc;
}
{
struct tracefiled_ctl *tctl = &trace_tctl;
- cfs_mutex_down(&cfs_trace_thread_sem);
+ cfs_mutex_lock(&cfs_trace_thread_mutex);
if (thread_running) {
printk(CFS_KERN_INFO
"Lustre: shutting down debug daemon thread...\n");
cfs_wait_for_completion(&tctl->tctl_stop);
thread_running = 0;
}
- cfs_mutex_up(&cfs_trace_thread_sem);
+ cfs_mutex_unlock(&cfs_trace_thread_mutex);
}
int cfs_tracefile_init(int max_pages)