On Wed, Jul 30, 2008 at 04:19:44PM -0500, David Smith wrote: ...
> @@ -197,14 +224,33 @@ static void __exit exit_crash_suspend(vo > error, t->pid); > } > else { > - int ret = utrace_control(t, engine, UTRACE_DETACH); > + int ret = utrace_set_events(t, engine, > + SHUTDOWN_EVENTS); > WARN_ON(ret); > + > + ret = utrace_control(t, engine, UTRACE_STOP); > + if (ret == -EINPROGRESS) { > + ret = utrace_control(t, engine, > + UTRACE_INTERRUPT); > + WARN_ON(ret); > + } > + else { > + WARN_ON(ret); > + } > ++n; > } > } > rcu_read_unlock(); > > - printk("detached from %d threads, unloading\n", n); > + printk(KERN_INFO "requested %d threads to stop\n", n); > + > + if (wait_event_timeout(crash_suspend_wq, > + (atomic_read(&attach_count) <= 0), > + 60 * HZ) <= 0) { > + printk(KERN_ERR "gave up waiting.\n"); > + } > + printk(KERN_INFO "unloading, %d threads left to stop\n", > + atomic_read(&attach_count)); > } > > module_init(init_crash_suspend); Thinking aloud, utrace_control(UTRACE_STOP) returns -EINPROGRESS for threads not yet stopped a. possibly still in userspace, yet to pass through a quiesce safe point b. blocked in the kernel on a syscall or an exception. Would task_current_syscall() help here? On a -EINPROGRESS return, one can check for a 0 return from task_current_syscall() which'd mean the thread is in the kernel. Wouldn't that mean that the thread will eventually do a report_quiesce? I think this can be a good model to use for non-perturbing quiesce for cases as breakpoint insertion and removal or any applicaton text modification, where one needs to ensure no thread is executing in the vicinity of the said modification. So, even on an -EINPROGRESS on a utrace_control, if the thread is in kernel, manipulating application text is still safe, right? Not sure if a similar model can be used to address the teardown races problem. Thoughts? Ananth