lkml.org 
[lkml]   [2009]   [May]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] tracing/workqueue: Get rid of searching last executed worklet in probe_worklet_complete()
    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.

    Signed-off-by: Zhao Lei <zhaolei@cn.fujitsu.com>
    Reported-by: Oleg Nesterov <oleg@redhat.com>
    ---
    kernel/trace/trace_workqueue.c | 37 +++++++++++++------------------------
    1 files changed, 13 insertions(+), 24 deletions(-)

    diff --git a/kernel/trace/trace_workqueue.c b/kernel/trace/trace_workqueue.c
    index c67be60..d90f9ac 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,7 +163,7 @@ 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;
    }
    pr_debug("trace_workqueue: worklet not found\n");
    @@ -180,7 +180,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 +192,11 @@ 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;
    + 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;

    - if (wfnode->work != work)
    - continue;
    -
    - 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



    \
     
     \ /
      Last update: 2009-05-21 12:59    [W:0.027 / U:0.468 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site