Every time we set ->report, we also set ->slow_path. This complication is not necessary. Instead we can change start_report() to check both flags. This is free, gcc is good enough. This code
void test_func(struct utrace *utrace) { if (utrace->slow_path || utrace->report) do_something(); } is compiled to test_func: pushq %rbp testb $-126, 96(%rdi), movq %rsp, %rbp, jne .L449, leave ret .L449: call do_something leave ret Perhaps it makes sense to rename ->slow_path, with it only means that splice_attaching() is needed and nothing more. Signed-off-by: Oleg Nesterov <o...@redhat.com> --- kernel/utrace.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) --- __UTRACE/kernel/utrace.c~6_DONT_ABUSE_SLOW_WORK 2009-09-06 18:07:14.000000000 +0200 +++ __UTRACE/kernel/utrace.c 2009-09-06 18:15:39.000000000 +0200 @@ -644,7 +644,7 @@ static bool utrace_do_stop(struct task_s } spin_unlock_irq(&target->sighand->siglock); } else if (!utrace->report && !utrace->interrupt) { - utrace->report = utrace->slow_path = 1; + utrace->report = 1; set_notify_resume(target); } @@ -773,7 +773,7 @@ relock: /* * Ensure a reporting pass when we're resumed. */ - utrace->report = utrace->slow_path = 1; + utrace->report = 1; set_thread_flag(TIF_NOTIFY_RESUME); } @@ -1096,7 +1096,7 @@ int utrace_control(struct task_struct *t */ clear_engine_wants_stop(engine); if (!utrace->report && !utrace->interrupt) { - utrace->report = utrace->slow_path = 1; + utrace->report = 1; set_notify_resume(target); } break; @@ -1266,14 +1266,13 @@ struct utrace_report { /* * We are now making the report, so clear the flag saying we need one. - * When ->report is set, ->slow_path is always set too. When there is a - * new attach, ->slow_path is set even without ->report, just so we will - * know to do splice_attaching() here before the callback loop. + * When there is a new attach, ->slow_path is set without ->report, just + * so we will know to do splice_attaching() here before the callback loop. */ static void start_report(struct utrace *utrace) { BUG_ON(utrace->stopped); - if (utrace->slow_path) { + if (utrace->report || utrace->slow_path) { spin_lock(&utrace->lock); splice_attaching(utrace); utrace->report = 0; @@ -1310,7 +1309,7 @@ static void finish_report(struct utrace_ utrace->interrupt = 1; set_tsk_thread_flag(task, TIF_SIGPENDING); } else { - utrace->report = utrace->slow_path = 1; + utrace->report = 1; set_tsk_thread_flag(task, TIF_NOTIFY_RESUME); } spin_unlock(&utrace->lock);