MODULE_PARM_DESC(libcfs_subsystem_debug, "Lustre kernel debug subsystem mask");
EXPORT_SYMBOL(libcfs_subsystem_debug);
-unsigned int libcfs_debug = (D_CANTMASK |
- D_NETERROR | D_HA | D_CONFIG | D_IOCTL | D_LFSCK);
+unsigned int libcfs_debug = (D_CANTMASK | D_NETERROR | D_HA | D_CONFIG |
+ D_IOCTL | D_LFSCK | D_TTY);
module_param(libcfs_debug, int, 0644);
MODULE_PARM_DESC(libcfs_debug, "Lustre kernel debug mask");
EXPORT_SYMBOL(libcfs_debug);
if (rc < 0)
return rc;
-/*
- * RHEL6 does not support any kind of locking so we have to provide
- * our own
- */
-#if !defined(HAVE_MODULE_PARAM_LOCKING) && !defined(HAVE_KERNEL_PARAM_LOCK)
- kernel_param_lock(THIS_MODULE);
-#endif
- if (!*((unsigned int *)kp->arg)) {
- *((unsigned int *)kp->arg) = num;
-
-#if !defined(HAVE_MODULE_PARAM_LOCKING) && !defined(HAVE_KERNEL_PARAM_LOCK)
- kernel_param_unlock(THIS_MODULE);
-#endif
- return 0;
- }
-
- rc = cfs_trace_set_debug_mb(num);
+ num = cfs_trace_set_debug_mb(num);
- if (!rc)
- *((unsigned int *)kp->arg) = cfs_trace_get_debug_mb();
+ *((unsigned int *)kp->arg) = num;
+ num = cfs_trace_get_debug_mb();
+ if (num)
+ /* This value is more precise */
+ *((unsigned int *)kp->arg) = num;
-#if !defined(HAVE_MODULE_PARAM_LOCKING) && !defined(HAVE_KERNEL_PARAM_LOCK)
- kernel_param_unlock(THIS_MODULE);
-#endif
- return rc;
+ return 0;
}
/*
{
unsigned int d = *(unsigned int *)kp->arg;
- return sprintf(buffer, "%lu", jiffies_to_msecs(d * 10) / MSEC_PER_SEC);
+ param_get_byte(buffer, kp);
+ return sprintf(buffer, "%lu%c", jiffies_to_msecs(d * 10) / MSEC_PER_SEC,
+ strnchr(buffer, PAGE_SIZE, '\n') ? '\n' : '\0');
}
unsigned int libcfs_console_max_delay;
atomic_t libcfs_kmemory = ATOMIC_INIT(0);
EXPORT_SYMBOL(libcfs_kmemory);
-static wait_queue_head_t debug_ctlwq;
+static DECLARE_COMPLETION(debug_complete);
char libcfs_debug_file_path_arr[PATH_MAX] = LIBCFS_DEBUG_FILE_PATH_DEFAULT;
EXPORT_SYMBOL(libcfs_debug_file_path_arr);
len = 1;
} else { /* space-separated tokens */
for (i = 0; i < 32; i++) {
- if ((mask & (1 << i)) == 0)
+ if ((mask & BIT(i)) == 0)
continue;
token = fn(i);
snprintf(debug_file_name, sizeof(debug_file_name) - 1,
"%s.%lld.%ld", libcfs_debug_file_path_arr,
(s64)current_time, (uintptr_t)arg);
- printk(KERN_ALERT "LustreError: dumping log to %s\n",
- debug_file_name);
+ pr_alert("LustreError: dumping log to %s\n", debug_file_name);
cfs_tracefile_dump_all_pages(debug_file_name);
libcfs_run_debug_log_upcall(debug_file_name);
}
static int libcfs_debug_dumplog_thread(void *arg)
{
libcfs_debug_dumplog_internal(arg);
- wake_up(&debug_ctlwq);
+ complete(&debug_complete);
return 0;
}
+static DEFINE_MUTEX(libcfs_debug_dumplog_lock);
+
void libcfs_debug_dumplog(void)
{
- wait_queue_entry_t wait;
struct task_struct *dumper;
ENTRY;
- /*
- * we're being careful to ensure that the kernel thread is
- * able to set our state to running as it exits before we
- * get to schedule()
- */
- init_waitqueue_entry(&wait, current);
- set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&debug_ctlwq, &wait);
+ if (mutex_trylock(&libcfs_debug_dumplog_lock) == 0)
+ return;
+ /* If a previous call was interrupted, debug_complete->done
+ * might be elevated, and so we won't actually wait here.
+ * So we reinit the completion to ensure we wait for
+ * one thread to complete, though it might not be the one
+ * we start if there are overlaping thread.
+ */
+ reinit_completion(&debug_complete);
dumper = kthread_run(libcfs_debug_dumplog_thread,
- (void *)(long)current_pid(),
+ (void *)(long)current->pid,
"libcfs_debug_dumper");
if (IS_ERR(dumper))
- printk(KERN_ERR "LustreError: cannot start log dump thread:"
- " %ld\n", PTR_ERR(dumper));
+ pr_err("LustreError: cannot start log dump thread: rc = %ld\n",
+ PTR_ERR(dumper));
else
- schedule();
+ wait_for_completion_interruptible(&debug_complete);
- /* be sure to teardown if cfs_create_thread() failed */
- remove_wait_queue(&debug_ctlwq, &wait);
- set_current_state(TASK_RUNNING);
+ mutex_unlock(&libcfs_debug_dumplog_lock);
}
EXPORT_SYMBOL(libcfs_debug_dumplog);
int rc = 0;
unsigned int max = libcfs_debug_mb;
- init_waitqueue_head(&debug_ctlwq);
-
if (libcfs_console_max_delay <= 0 || /* not set by user or */
libcfs_console_min_delay <= 0 || /* set to invalid values */
libcfs_console_min_delay >= libcfs_console_max_delay) {
sizeof(libcfs_debug_file_path_arr));
}
- /*
- * If libcfs_debug_mb is set to an invalid value or uninitialized
- * then just make the total buffers smp_num_cpus * TCD_MAX_PAGES
+ /* If libcfs_debug_mb is uninitialized then just make the
+ * total buffers smp_num_cpus * TCD_MAX_PAGES
*/
- if (max > cfs_trace_max_debug_mb() || max < num_possible_cpus()) {
+ if (max < num_possible_cpus()) {
max = TCD_MAX_PAGES;
} else {
max = (max / num_possible_cpus());
libcfs_register_panic_notifier();
kernel_param_lock(THIS_MODULE);
- libcfs_debug_mb = cfs_trace_get_debug_mb();
+ if (libcfs_debug_mb == 0)
+ libcfs_debug_mb = cfs_trace_get_debug_mb();
kernel_param_unlock(THIS_MODULE);
return rc;
}