Skip to content

Commit

Permalink
kthread: add kthread_work tracepoints
Browse files Browse the repository at this point in the history
While migrating some code from wq to kthread_worker, I found that I missed
the execute_start/end tracepoints.  So add similar tracepoints for
kthread_work.  And for completeness, queue_work tracepoint (although this
one differs slightly from the matching workqueue tracepoint).

Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Rob Clark <[email protected]>
Cc: Rob Clark <[email protected]>
Cc: Steven Rostedt <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: "Peter Zijlstra (Intel)" <[email protected]>
Cc: Phil Auld <[email protected]>
Cc: Valentin Schneider <[email protected]>
Cc: Thara Gopinath <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Vincent Donnefort <[email protected]>
Cc: Mel Gorman <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: Marcelo Tosatti <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ilias Stamatis <[email protected]>
Cc: Liang Chen <[email protected]>
Cc: Ben Dooks <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: "J. Bruce Fields" <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
robclark authored and torvalds committed Dec 15, 2020
1 parent 2c85ebc commit f630c7c
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
84 changes: 84 additions & 0 deletions include/trace/events/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_SCHED_H

#include <linux/kthread.h>
#include <linux/sched/numa_balancing.h>
#include <linux/tracepoint.h>
#include <linux/binfmts.h>
Expand Down Expand Up @@ -51,6 +52,89 @@ TRACE_EVENT(sched_kthread_stop_ret,
TP_printk("ret=%d", __entry->ret)
);

/**
* sched_kthread_work_queue_work - called when a work gets queued
* @worker: pointer to the kthread_worker
* @work: pointer to struct kthread_work
*
* This event occurs when a work is queued immediately or once a
* delayed work is actually queued (ie: once the delay has been
* reached).
*/
TRACE_EVENT(sched_kthread_work_queue_work,

TP_PROTO(struct kthread_worker *worker,
struct kthread_work *work),

TP_ARGS(worker, work),

TP_STRUCT__entry(
__field( void *, work )
__field( void *, function)
__field( void *, worker)
),

TP_fast_assign(
__entry->work = work;
__entry->function = work->func;
__entry->worker = worker;
),

TP_printk("work struct=%p function=%ps worker=%p",
__entry->work, __entry->function, __entry->worker)
);

/**
* sched_kthread_work_execute_start - called immediately before the work callback
* @work: pointer to struct kthread_work
*
* Allows to track kthread work execution.
*/
TRACE_EVENT(sched_kthread_work_execute_start,

TP_PROTO(struct kthread_work *work),

TP_ARGS(work),

TP_STRUCT__entry(
__field( void *, work )
__field( void *, function)
),

TP_fast_assign(
__entry->work = work;
__entry->function = work->func;
),

TP_printk("work struct %p: function %ps", __entry->work, __entry->function)
);

/**
* sched_kthread_work_execute_end - called immediately after the work callback
* @work: pointer to struct work_struct
* @function: pointer to worker function
*
* Allows to track workqueue execution.
*/
TRACE_EVENT(sched_kthread_work_execute_end,

TP_PROTO(struct kthread_work *work, kthread_work_func_t function),

TP_ARGS(work, function),

TP_STRUCT__entry(
__field( void *, work )
__field( void *, function)
),

TP_fast_assign(
__entry->work = work;
__entry->function = function;
),

TP_printk("work struct %p: function %ps", __entry->work, __entry->function)
);

/*
* Tracepoint for waking up a task:
*/
Expand Down
9 changes: 9 additions & 0 deletions kernel/kthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,8 +704,15 @@ int kthread_worker_fn(void *worker_ptr)
raw_spin_unlock_irq(&worker->lock);

if (work) {
kthread_work_func_t func = work->func;
__set_current_state(TASK_RUNNING);
trace_sched_kthread_work_execute_start(work);
work->func(work);
/*
* Avoid dereferencing work after this point. The trace
* event only cares about the address.
*/
trace_sched_kthread_work_execute_end(work, func);
} else if (!freezing(current))
schedule();

Expand Down Expand Up @@ -834,6 +841,8 @@ static void kthread_insert_work(struct kthread_worker *worker,
{
kthread_insert_work_sanity_check(worker, work);

trace_sched_kthread_work_queue_work(worker, work);

list_add_tail(&work->node, pos);
work->worker = worker;
if (!worker->current_work && likely(worker->task))
Expand Down

0 comments on commit f630c7c

Please sign in to comment.