Re: [PATCH 0/4] utrace-resume fixes

2009-11-20 Thread Oleg Nesterov
On 11/18, Roland McGrath wrote:

 So maybe you will look at this and merge them before I do.

Whatever we do, perhaps it makes sense to apply your patch
in https://www.redhat.com/archives/utrace-devel/2009-November/msg00109.html
first and then do further changes?

This way we will have the working utrace-ptrace branch which passes
ptrace-tests at least, and we can ask Cai to do more testing.

Oleg.



Re: [PATCH 0/4] utrace-resume fixes

2009-11-20 Thread Roland McGrath
 Whatever we do, perhaps it makes sense to apply your patch
 in https://www.redhat.com/archives/utrace-devel/2009-November/msg00109.html
 first and then do further changes?

Ok.  v2.6.32-rc8-245-g3d4f9cf has that.  I'll shelve this 4-patch series
while we keep discussing (one more reply to come from me as of now).  Then
you send me a fresh series done however you think is best given that
discussion.  (So if you want to do more relative to these 4 patches, just
resend them as part of the new series.)


Thanks,
Roland



Re: [PATCH 0/4] utrace-resume fixes

2009-11-20 Thread Roland McGrath
 Somehow I can't really understand this patch. I hope more or less
 I can see what it does, but the resulting code looks even more
 subtle to me.

Well, it was an untested draft and probably needed more comments.

 With this patch, apply_resume_action() is always called after
 utrace_stop(). Well, except for utrace_report_exit(), but I guess
 it could do apply_resume_action() too.

It could, but it just never matters at all.  The only thing that can
possibly be meaningful is UTRACE_INTERRUPT, and for that finish_report has
set TIF_SIGPENDING already anyway.

 Now it is not clear why utrace_control(SINGLESTEP) sets
 TIF_NOTIFY_RESUME, it is not needed after apply_resume_action()
 processes -resume. Yes, we have jctl stops, but we can move
 this code into utrace_finish_stop().

Yes, it is not really needed.  But note that it is actually now possible to
use UTRACE_SINGLESTEP without UTRACE_STOP first--not that it's really
useful, but we don't really have any reason to disallow it.  So in that
case it does make a difference.  We could just do:

@@ -1183,7 +1183,8 @@ int utrace_control(struct task_struct *target,
clear_engine_wants_stop(engine);
if (action  utrace-resume) {
utrace-resume = action;
-   set_notify_resume(target);
+   if (reset)
+   set_notify_resume(target);
}
break;

Since TIF_NOTIFY_RESUME will now always be superfluous when stopped.

 It is not clear to me why apply_resume_action(UTRACE_INTERRUPT) does
 set_tsk_thread_flag(TIF_SIGPENDING). In fact I don't understand why
 apply_resume_action() checks UTRACE_INTERRUPT at all. If it is called
 after utrace_stop(), action == start_report() which never resets
 UTRACE_INTERRUPT.

It's only because this code path is shared with the tail of
finish_resume_report, where it is the only thing processing
UTRACE_INTERRUPT in the real return-to-user cases.  i.e., in paths that
don't call finish_report(), TIF_SIGPENDING won't ever have been set by a
callback return value.  utrace_control does always set it up front, so it
is superfluous when that's how UTRACE_INTERRUPT got set.

 And since we process -resume after stop, it is not clear why we
 set -resume = report-resume_action before stop, apply_resume_action()
 could use min(report-resume_action, utrace-resume). Yes, yes,
 we have the nasty utrace-vfork_stop case, I mean it is not easy to
 understand the logic behind all these -resume changes.

Ok.  Feel free to clean it up if you think it makes things clearer.  To me,
it's just natural to do that MIN operation as soon as you know about it.
utrace_stop() always takes the lock anyway, so it's relatively free.  If
the ambient state is stored early, then e.g. utrace_control() won't bother
to set TIF_SIGPENDING or TIF_NOTIFY_RESUME.

I guess I think the logic is simple: apply a new minimum to -resume as
soon as you know about it.

 And afaics, this can't help to fix the tracehook_report_syscall_exit()
  TIF_SINGLESTEP problems in the multitracing case, UTRACE_INTERRUPT
 destroys UTRACE_SINGLESTEP. Ptrace can reassert it later, but this
 will be too late, the trace has already passed this tracehook.

See the other thread, but what I said there is let's take this case up in
its own thread later.

 I don't understand this skip_notify, utrace_stop() is always called
 with skip_notify == true?

Hmm.  Yes, this patch was unfinished when I sent it because your patches
were crossing paths with what I was doing.  We can skip TIF_NOTIFY_RESUME
when we'll always call apply_resume_action() after utrace_stop() before
user mode (i.e. report_exit doesn't matter).

Since report_exit doesn't matter one way or the other, perhaps it will be
cleaner to roll apply_resume_action() into utrace_stop() in some fashion.
I notice we're now actually using the REPORT() macro only four times, and
one of those is report_exit.  So maybe that and finish_report() could
change somehow too to refactor things.  I'll leave it to you to rework all
those and finish_* to the most useful organization of subroutines.

I think we're mutually clear now on the idea of when to do user_*_step()
calls (i.e. apply_resume_action).


Thanks,
Roland



[PATCH 0/4] utrace-resume fixes

2009-11-18 Thread Oleg Nesterov
On top of your patch in
https://www.redhat.com/archives/utrace-devel/2009-November/msg00109.html

I attached this patch below just in case. As expected, it fixes
the problem with the lost TIF_SINGLESTEP.

Oleg.

--- UTRACE-PTRACE/kernel/utrace.c~__ROLAND_RESUME_FIX   2009-11-18 
21:16:23.0 +0100
+++ UTRACE-PTRACE/kernel/utrace.c   2009-11-19 02:17:26.0 +0100
@@ -1882,8 +1882,18 @@ void utrace_resume(struct task_struct *t
 */
report.action = start_report(utrace);
 
-   if (report.action == UTRACE_REPORT 
-   likely(task-utrace_flags  UTRACE_EVENT(QUIESCE))) {
+   switch (report.action) {
+   case UTRACE_RESUME:
+   /*
+* Anything we might have done was already handled by
+* utrace_get_signal(), or this is an entirely spurious
+* call.  (The arch might use TIF_NOTIFY_RESUME for other
+* purposes as well as calling us.)
+*/
+   return;
+   case UTRACE_REPORT:
+   if (unlikely(!(task-utrace_flags  UTRACE_EVENT(QUIESCE
+   break;
/*
 * Do a simple reporting pass, with no specific
 * callback after report_quiesce.
@@ -1891,13 +1901,15 @@ void utrace_resume(struct task_struct *t
report.action = UTRACE_RESUME;
list_for_each_entry(engine, utrace-attached, entry)
start_callback(utrace, report, engine, task, 0);
-   } else {
+   break;
+   default:
/*
 * Even if this report was truly spurious, there is no need
 * for utrace_reset() now.  TIF_NOTIFY_RESUME was already
 * cleared--it doesn't stay spuriously set.
 */
report.spurious = false;
+   break;
}
 
/*