On 10/12, Roland McGrath wrote: > > > No, the return calue from utrace_barrier() does not matter. And, if the > > tracee is killed we don't care. The race is different. > > The utrace_barrier return value should cover exactly the case you describe, > and that is the clean way to do it. It will fail if the tracee is either > dead or detached.
Thanks, I think you are right, and this should work. But. This is connected to https://www.redhat.com/archives/utrace-devel/2009-October/msg00132.html and I still think utrace_barrier() and finish_callback() pathes need more mb's. This case is very similar to the previous pseudo-code. Suppose that utrace_get_signal() calls ->report_signal() which returns UTRACE_DETACH while the tracer does utrace_barrier(). Tracee, finish_callback() path: if (action == UTRACE_DETACH) engine->ops = utrace_detached_ops; utrace->reporting = NULL; no barries, no utrace->lock() in between. Tracer, utrace_barrier() under utrace->lock: if (engine->ops == utrace_detached_ops) return -EXXX; if (utrace->reporting != engine) return 0; Afaics, this is racy and should be fixed in utrace level. What do you think? --- kernel/ptrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) --- PU/kernel/ptrace.c~85_REUSE_RELY_ON_BARRIER 2009-10-13 14:01:43.000000000 +0200 +++ PU/kernel/ptrace.c 2009-10-13 14:15:48.000000000 +0200 @@ -459,8 +459,8 @@ static int ptrace_attach_task(struct tas /* * Make sure we don't race with ptrace_report_signal() */ - utrace_barrier(tracee, engine); - if (engine->ops == &ptrace_utrace_ops) + err = utrace_barrier(tracee, engine); + if (!err) goto finish; } utrace_engine_put(engine);