summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrivatsa Vaddagiri <vatsa@codeaurora.org>2014-05-12 17:59:05 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 19:59:36 -0700
commit7f78facb9a3dea1bcad4b41a4d253fa698ed07e8 (patch)
treefa6125c562fe3cf49b7351a59169ef55678c5eb1
parent53a4978f8044d16f8e5ecfe353f10cab5ab92022 (diff)
sched: Add new trace events
Add trace events for update_task_ravg(), update_history(), and set_task_cpu(). These tracepoints are useful for monitoring the per-task and per-runqueue demand statistics. Change-Id: Ibec9f945074ff31d1fc1a76ae37c40c8fea8cda9 Signed-off-by: Srivatsa Vaddagiri <vatsa@codeaurora.org>
-rw-r--r--include/linux/sched.h8
-rw-r--r--include/trace/events/sched.h134
-rw-r--r--kernel/sched/core.c16
3 files changed, 152 insertions, 6 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index f22f67de7320..266dca375d59 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -314,6 +314,14 @@ extern char ___assert_task_state[1 - 2*!!(
/* Task command name length */
#define TASK_COMM_LEN 16
+enum task_event {
+ PUT_PREV_TASK = 0,
+ PICK_NEXT_TASK = 1,
+ TASK_WAKE = 2,
+ TASK_MIGRATE = 3,
+ TASK_UPDATE = 4,
+};
+
#include <linux/spinlock.h>
/*
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index 99f93e6a9235..cfe4bc63db7c 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -9,6 +9,7 @@
#include <linux/binfmts.h>
struct rq;
+extern const char *task_event_names[];
/*
* Tracepoint for calling kthread_stop, performed to end a kthread:
@@ -188,6 +189,139 @@ TRACE_EVENT(sched_cpu_load,
#endif /* CONFIG_SCHED_HMP */
+#if defined(CONFIG_SCHED_FREQ_INPUT) || defined(CONFIG_SCHED_HMP)
+
+TRACE_EVENT(sched_update_task_ravg,
+
+ TP_PROTO(struct task_struct *p, struct rq *rq, enum task_event evt,
+ u64 wallclock),
+
+ TP_ARGS(p, rq, evt, wallclock),
+
+ TP_STRUCT__entry(
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ __field( pid_t, cur_pid )
+ __field(unsigned int, cur_freq )
+ __field(unsigned int, cs )
+ __field(unsigned int, ps )
+ __field( u64, wallclock )
+ __field( u64, mark_start )
+ __field( u64, delta_m )
+ __field( u64, win_start )
+ __field( u64, delta )
+ __field(enum task_event, evt )
+ __field(unsigned int, demand )
+ __field(unsigned int, partial_demand )
+ __field(unsigned int, sum )
+ __field(unsigned int, prev_window )
+ __field( int, cpu )
+ ),
+
+ TP_fast_assign(
+ __entry->wallclock = wallclock;
+ __entry->win_start = rq->window_start;
+ __entry->delta = (wallclock - rq->window_start);
+ __entry->evt = evt;
+ __entry->cpu = rq->cpu;
+ __entry->cur_pid = rq->curr->pid;
+ __entry->cur_freq = rq->cur_freq;
+ __entry->cs = rq->curr_runnable_sum;
+ __entry->ps = rq->prev_runnable_sum;
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->pid = p->pid;
+ __entry->mark_start = p->ravg.mark_start;
+ __entry->delta_m = (wallclock - p->ravg.mark_start);
+ __entry->demand = p->ravg.demand;
+ __entry->partial_demand = p->ravg.partial_demand;
+ __entry->sum = p->ravg.sum;
+ __entry->prev_window = p->ravg.prev_window;
+ ),
+
+ TP_printk("wc %llu ws %llu delta %llu event %s cpu %d cur_freq %u cs %u ps %u cur_pid %d task %d (%s) ms %llu delta %llu demand %u partial_demand %u sum %u prev_window %u",
+ __entry->wallclock, __entry->win_start, __entry->delta,
+ task_event_names[__entry->evt], __entry->cpu,
+ __entry->cur_freq, __entry->cs, __entry->ps, __entry->cur_pid,
+ __entry->pid, __entry->comm, __entry->mark_start,
+ __entry->delta_m, __entry->demand, __entry->partial_demand,
+ __entry->sum, __entry->prev_window)
+);
+
+TRACE_EVENT(sched_update_history,
+
+ TP_PROTO(struct rq *rq, struct task_struct *p, u32 runtime, int samples,
+ int update_sum, int new_window, enum task_event evt),
+
+ TP_ARGS(rq, p, runtime, samples, update_sum, new_window, evt),
+
+ TP_STRUCT__entry(
+ __array( char, comm, TASK_COMM_LEN )
+ __field( pid_t, pid )
+ __field(unsigned int, runtime )
+ __field( int, samples )
+ __field( int, update_sum )
+ __field( int, new_window )
+ __field(enum task_event, evt )
+ __field(unsigned int, partial_demand )
+ __field(unsigned int, demand )
+ __array( u32, hist, RAVG_HIST_SIZE )
+ __field(unsigned int, nr_big_tasks )
+ __field(unsigned int, nr_small_tasks )
+ __field( int, cpu )
+ ),
+
+ TP_fast_assign(
+ memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+ __entry->pid = p->pid;
+ __entry->runtime = runtime;
+ __entry->samples = samples;
+ __entry->update_sum = update_sum;
+ __entry->new_window = new_window;
+ __entry->evt = evt;
+ __entry->partial_demand = p->ravg.partial_demand;
+ __entry->demand = p->ravg.demand;
+ memcpy(__entry->hist, p->ravg.sum_history,
+ RAVG_HIST_SIZE*sizeof(u32));
+#ifdef CONFIG_SCHED_HMP
+ __entry->nr_big_tasks = rq->nr_big_tasks;
+ __entry->nr_small_tasks = rq->nr_small_tasks;
+#endif
+ __entry->cpu = rq->cpu;
+ ),
+
+ TP_printk("%d (%s): runtime %u samples %d us %d nw %d event %s partial_demand %u demand %u (hist: %u %u %u %u %u) cpu %d nr_big %u nr_small %u",
+ __entry->pid, __entry->comm,
+ __entry->runtime, __entry->samples, __entry->update_sum,
+ __entry->new_window, task_event_names[__entry->evt],
+ __entry->partial_demand, __entry->demand, __entry->hist[0],
+ __entry->hist[1], __entry->hist[2], __entry->hist[3],
+ __entry->hist[4], __entry->cpu, __entry->nr_big_tasks,
+ __entry->nr_small_tasks)
+);
+
+TRACE_EVENT(sched_migration_update_sum,
+
+ TP_PROTO(struct rq *rq),
+
+ TP_ARGS(rq),
+
+ TP_STRUCT__entry(
+ __field(int, cpu )
+ __field(int, cs )
+ __field(int, ps )
+ ),
+
+ TP_fast_assign(
+ __entry->cpu = cpu_of(rq);
+ __entry->cs = rq->curr_runnable_sum;
+ __entry->ps = rq->prev_runnable_sum;
+ ),
+
+ TP_printk("cpu %d: cs %u ps %u\n", __entry->cpu,
+ __entry->cs, __entry->ps)
+);
+
+#endif /* CONFIG_SCHED_FREQ_INPUT || CONFIG_SCHED_HMP */
/*
* Tracepoint for waking up a task:
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 8888c1081ef3..69f8aef5a849 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -91,6 +91,9 @@
#define CREATE_TRACE_POINTS
#include <trace/events/sched.h>
+const char *task_event_names[] = {"PUT_PREV_TASK", "PICK_NEXT_TASK",
+ "TASK_WAKE", "TASK_MIGRATE", "TASK_UPDATE"};
+
ATOMIC_NOTIFIER_HEAD(migration_notifier_head);
ATOMIC_NOTIFIER_HEAD(load_alert_notifier_head);
@@ -1072,12 +1075,6 @@ void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
rq_clock_skip_update(rq, true);
}
-#define PUT_PREV_TASK 0
-#define PICK_NEXT_TASK 1
-#define TASK_WAKE 2
-#define TASK_MIGRATE 3
-#define TASK_UPDATE 4
-
#if defined(CONFIG_SCHED_FREQ_INPUT) || defined(CONFIG_SCHED_HMP)
/* Window size (in ns) */
@@ -1212,6 +1209,8 @@ compute_demand:
if (p->sched_class == &fair_sched_class)
inc_nr_big_small_task(rq, p);
}
+ trace_sched_update_history(rq, p, runtime, samples, update_sum,
+ new_window, event);
}
static int __init set_sched_ravg_window(char *str)
@@ -1352,6 +1351,8 @@ static void update_task_ravg(struct task_struct *p, struct rq *rq,
if (event == PICK_NEXT_TASK && !p->ravg.sum)
rq->curr_runnable_sum += p->ravg.partial_demand;
+ trace_sched_update_task_ravg(p, rq, event, wallclock);
+
p->ravg.mark_start = wallclock;
}
@@ -1839,6 +1840,9 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
BUG_ON((int)src_rq->prev_runnable_sum < 0);
BUG_ON((int)src_rq->curr_runnable_sum < 0);
+ trace_sched_migration_update_sum(src_rq);
+ trace_sched_migration_update_sum(dest_rq);
+
if (p->state == TASK_WAKING)
double_rq_unlock(src_rq, dest_rq);