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;
+ num = cfs_trace_set_debug_mb(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);
-
- 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;
}
/*
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);
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) {