From: Frederic Weisbecker <fweisbec@gmail.com>
To: Zhaolei <zhaolei@cn.fujitsu.com>
Cc: Steven Rostedt <rostedt@goodmis.org>, Ingo Molnar <mingo@elte.hu>,
Tom Zanussi <tzanussi@gmail.com>, Oleg Nesterov <oleg@redhat.com>,
LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2] tracing/workqueue: Get rid of searching last executed worklet in probe_worklet_complete()
Date: Sun, 24 May 2009 23:30:30 +0200 [thread overview]
Message-ID: <20090524213028.GE6471@nowhere> (raw)
In-Reply-To: <4A1610B6.7010203@cn.fujitsu.com>
On Fri, May 22, 2009 at 10:40:54AM +0800, Zhaolei wrote:
> We don't need search workqueue's worklet list for worklet which was latest
> executed, instead, we can use a pointer in cpu_workqueue_stats to remember
> which worklet was just executed.
>
> Thanks Oleg for pointing it out.
>
> Changelog:
> v1->v2: Oleg pointed out that if searching executed workfunc_stats failed
> in probe_worklet_execute(), for example, workfunc_stats's memory allocation
> failed previously, cpu_workqueue_stats->last_workfunc is not set to correct
> value, and it will cause wrong accessing in probe_worklet_complete().
> This problem is fixed in v2.
>
> Signed-off-by: Zhao Lei <zhaolei@cn.fujitsu.com>
> Reported-by: Oleg Nesterov <oleg@redhat.com>
Looks good, thanks!
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
Frederic.
> ---
> kernel/trace/trace_workqueue.c | 39 ++++++++++++++++-----------------------
> 1 files changed, 16 insertions(+), 23 deletions(-)
>
> diff --git a/kernel/trace/trace_workqueue.c b/kernel/trace/trace_workqueue.c
> index c67be60..740de3b 100644
> --- a/kernel/trace/trace_workqueue.c
> +++ b/kernel/trace/trace_workqueue.c
> @@ -25,13 +25,6 @@ struct workfunc_stats {
> unsigned int inserted;
> unsigned int executed;
>
> - /*
> - * save latest work_struct's pointer to use as identifier in
> - * probe_worklet_complete, because we can't use work_struct->...
> - * after worklet got executed
> - */
> - void *work;
> -
> /* save execution time temporarily for calculate executed time */
> u64 start_time;
> u64 max_executed_time;
> @@ -46,10 +39,17 @@ struct cpu_workqueue_stats {
> /* Protected by cpu workqueue lock */
> unsigned int inserted;
> unsigned int executed;
> +
> /* list of struct workfunc_stats in this workqueue */
> struct list_head workfunclist;
>
> /*
> + * pointer to last executed worklet's workfunc_stats in this workqueue,
> + * used by probe_worklet_complete()
> + */
> + struct workfunc_stats *last_workfunc;
> +
> + /*
> * the task maybe destroyed when we read stat file
> * we define it to void * because we only use it as a identifier
> */
> @@ -163,9 +163,10 @@ found_wq:
> if (wfnode->func == work->func) {
> wfnode->executed++;
> wfnode->start_time = trace_clock_global();
> - wfnode->work = work;
> + node->last_workfunc = wfnode;
> goto found_wf;
> }
> + node->last_workfunc = NULL;
> pr_debug("trace_workqueue: worklet not found\n");
> goto end;
>
> @@ -180,7 +181,7 @@ probe_worklet_complete(struct task_struct *wq_thread, void *work)
> {
> int cpu = cpumask_first(&wq_thread->cpus_allowed);
> struct cpu_workqueue_stats *node;
> - struct workfunc_stats *wfnode;
> + u64 executed_time;
> unsigned long flags;
>
> spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
> @@ -192,22 +193,14 @@ probe_worklet_complete(struct task_struct *wq_thread, void *work)
> goto end;
>
> found_wq:
> - list_for_each_entry(wfnode, &node->workfunclist, list) {
> - u64 executed_time;
> + if (!node->last_workfunc)
> + goto end;
>
> - if (wfnode->work != work)
> - continue;
> + executed_time = trace_clock_global() - node->last_workfunc->start_time;
> + node->last_workfunc->total_time += executed_time;
> + if (executed_time > node->last_workfunc->max_executed_time)
> + node->last_workfunc->max_executed_time = executed_time;
>
> - executed_time = trace_clock_global() - wfnode->start_time;
> - wfnode->total_time += executed_time;
> - if (executed_time > wfnode->max_executed_time)
> - wfnode->max_executed_time = executed_time;
> - goto found_wf;
> - }
> - pr_debug("trace_workqueue: worklet not found\n");
> - goto end;
> -
> -found_wf:
> end:
> spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
> }
> --
> 1.5.5.3
>
>
prev parent reply other threads:[~2009-05-24 21:30 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-21 10:56 [PATCH] tracing/workqueue: Get rid of searching last executed worklet in probe_worklet_complete() Zhaolei
2009-05-21 13:05 ` Oleg Nesterov
2009-05-22 0:42 ` [PATCH] tracing/workqueue: Get rid of searching last executedworklet " Zhaolei
2009-05-22 2:40 ` [PATCH v2] tracing/workqueue: Get rid of searching last executed worklet " Zhaolei
2009-05-22 18:37 ` Oleg Nesterov
2009-05-26 20:23 ` Frederic Weisbecker
2009-05-27 18:32 ` Oleg Nesterov
2009-05-24 21:30 ` Frederic Weisbecker [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090524213028.GE6471@nowhere \
--to=fweisbec@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=oleg@redhat.com \
--cc=rostedt@goodmis.org \
--cc=tzanussi@gmail.com \
--cc=zhaolei@cn.fujitsu.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.