Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 135693
b: refs/heads/master
c: b342501
h: refs/heads/master
i:
  135691: 2447280
v: v3
  • Loading branch information
Ingo Molnar committed Feb 26, 2009
1 parent 02e3cc4 commit ac24934
Show file tree
Hide file tree
Showing 15 changed files with 247 additions and 666 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c40c6f85a7594ad842233885386a0ca4cd40eafe
refs/heads/master: b342501cd31e5546d0c9ca8ceff5ded1832f9e5b
1 change: 0 additions & 1 deletion trunk/include/linux/init_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ extern struct cred init_cred;
.nr_cpus_allowed = NR_CPUS, \
}, \
.tasks = LIST_HEAD_INIT(tsk.tasks), \
.pushable_tasks = PLIST_NODE_INIT(tsk.pushable_tasks, MAX_PRIO), \
.ptraced = LIST_HEAD_INIT(tsk.ptraced), \
.ptrace_entry = LIST_HEAD_INIT(tsk.ptrace_entry), \
.real_parent = &tsk, \
Expand Down
10 changes: 1 addition & 9 deletions trunk/include/linux/latencytop.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#ifndef _INCLUDE_GUARD_LATENCYTOP_H_
#define _INCLUDE_GUARD_LATENCYTOP_H_

#include <linux/compiler.h>
#ifdef CONFIG_LATENCYTOP

#define LT_SAVECOUNT 32
Expand All @@ -25,14 +24,7 @@ struct latency_record {

struct task_struct;

extern int latencytop_enabled;
void __account_scheduler_latency(struct task_struct *task, int usecs, int inter);
static inline void
account_scheduler_latency(struct task_struct *task, int usecs, int inter)
{
if (unlikely(latencytop_enabled))
__account_scheduler_latency(task, usecs, inter);
}
void account_scheduler_latency(struct task_struct *task, int usecs, int inter);

void clear_all_latency_tracing(struct task_struct *p);

Expand Down
9 changes: 3 additions & 6 deletions trunk/include/linux/plist.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,15 @@ struct plist_node {
# define PLIST_HEAD_LOCK_INIT(_lock)
#endif

#define _PLIST_HEAD_INIT(head) \
.prio_list = LIST_HEAD_INIT((head).prio_list), \
.node_list = LIST_HEAD_INIT((head).node_list)

/**
* PLIST_HEAD_INIT - static struct plist_head initializer
* @head: struct plist_head variable name
* @_lock: lock to initialize for this list
*/
#define PLIST_HEAD_INIT(head, _lock) \
{ \
_PLIST_HEAD_INIT(head), \
.prio_list = LIST_HEAD_INIT((head).prio_list), \
.node_list = LIST_HEAD_INIT((head).node_list), \
PLIST_HEAD_LOCK_INIT(&(_lock)) \
}

Expand All @@ -119,7 +116,7 @@ struct plist_node {
#define PLIST_NODE_INIT(node, __prio) \
{ \
.prio = (__prio), \
.plist = { _PLIST_HEAD_INIT((node).plist) }, \
.plist = PLIST_HEAD_INIT((node).plist, NULL), \
}

/**
Expand Down
17 changes: 11 additions & 6 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,6 @@ struct sched_class {
struct rq *busiest, struct sched_domain *sd,
enum cpu_idle_type idle);
void (*pre_schedule) (struct rq *this_rq, struct task_struct *task);
int (*needs_post_schedule) (struct rq *this_rq);
void (*post_schedule) (struct rq *this_rq);
void (*task_wake_up) (struct rq *this_rq, struct task_struct *task);

Expand Down Expand Up @@ -1053,10 +1052,6 @@ struct sched_entity {
u64 last_wakeup;
u64 avg_overlap;

u64 start_runtime;
u64 avg_wakeup;
u64 nr_migrations;

#ifdef CONFIG_SCHEDSTATS
u64 wait_start;
u64 wait_max;
Expand All @@ -1072,6 +1067,7 @@ struct sched_entity {
u64 exec_max;
u64 slice_max;

u64 nr_migrations;
u64 nr_migrations_cold;
u64 nr_failed_migrations_affine;
u64 nr_failed_migrations_running;
Expand Down Expand Up @@ -1168,7 +1164,6 @@ struct task_struct {
#endif

struct list_head tasks;
struct plist_node pushable_tasks;

struct mm_struct *mm, *active_mm;

Expand Down Expand Up @@ -1675,6 +1670,16 @@ static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask)
return set_cpus_allowed_ptr(p, &new_mask);
}

/*
* Architectures can set this to 1 if they have specified
* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK in their arch Kconfig,
* but then during bootup it turns out that sched_clock()
* is reliable after all:
*/
#ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
extern int sched_clock_stable;
#endif

extern unsigned long long sched_clock(void);

extern void sched_clock_init(void);
Expand Down
1 change: 1 addition & 0 deletions trunk/init/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,7 @@ config SLABINFO

config RT_MUTEXES
boolean
select PLIST

config BASE_SMALL
int
Expand Down
83 changes: 12 additions & 71 deletions trunk/kernel/latencytop.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,6 @@
* as published by the Free Software Foundation; version 2
* of the License.
*/

/*
* CONFIG_LATENCYTOP enables a kernel latency tracking infrastructure that is
* used by the "latencytop" userspace tool. The latency that is tracked is not
* the 'traditional' interrupt latency (which is primarily caused by something
* else consuming CPU), but instead, it is the latency an application encounters
* because the kernel sleeps on its behalf for various reasons.
*
* This code tracks 2 levels of statistics:
* 1) System level latency
* 2) Per process latency
*
* The latency is stored in fixed sized data structures in an accumulated form;
* if the "same" latency cause is hit twice, this will be tracked as one entry
* in the data structure. Both the count, total accumulated latency and maximum
* latency are tracked in this data structure. When the fixed size structure is
* full, no new causes are tracked until the buffer is flushed by writing to
* the /proc file; the userspace tool does this on a regular basis.
*
* A latency cause is identified by a stringified backtrace at the point that
* the scheduler gets invoked. The userland tool will use this string to
* identify the cause of the latency in human readable form.
*
* The information is exported via /proc/latency_stats and /proc/<pid>/latency.
* These files look like this:
*
* Latency Top version : v0.1
* 70 59433 4897 i915_irq_wait drm_ioctl vfs_ioctl do_vfs_ioctl sys_ioctl
* | | | |
* | | | +----> the stringified backtrace
* | | +---------> The maximum latency for this entry in microseconds
* | +--------------> The accumulated latency for this entry (microseconds)
* +-------------------> The number of times this entry is hit
*
* (note: the average latency is the accumulated latency divided by the number
* of times)
*/

#include <linux/latencytop.h>
#include <linux/kallsyms.h>
#include <linux/seq_file.h>
Expand Down Expand Up @@ -110,7 +72,7 @@ account_global_scheduler_latency(struct task_struct *tsk, struct latency_record
firstnonnull = i;
continue;
}
for (q = 0; q < LT_BACKTRACEDEPTH; q++) {
for (q = 0 ; q < LT_BACKTRACEDEPTH ; q++) {
unsigned long record = lat->backtrace[q];

if (latency_record[i].backtrace[q] != record) {
Expand Down Expand Up @@ -139,50 +101,29 @@ account_global_scheduler_latency(struct task_struct *tsk, struct latency_record
memcpy(&latency_record[i], lat, sizeof(struct latency_record));
}

/*
* Iterator to store a backtrace into a latency record entry
*/
static inline void store_stacktrace(struct task_struct *tsk,
struct latency_record *lat)
static inline void store_stacktrace(struct task_struct *tsk, struct latency_record *lat)
{
struct stack_trace trace;

memset(&trace, 0, sizeof(trace));
trace.max_entries = LT_BACKTRACEDEPTH;
trace.entries = &lat->backtrace[0];
trace.skip = 0;
save_stack_trace_tsk(tsk, &trace);
}

/**
* __account_scheduler_latency - record an occured latency
* @tsk - the task struct of the task hitting the latency
* @usecs - the duration of the latency in microseconds
* @inter - 1 if the sleep was interruptible, 0 if uninterruptible
*
* This function is the main entry point for recording latency entries
* as called by the scheduler.
*
* This function has a few special cases to deal with normal 'non-latency'
* sleeps: specifically, interruptible sleep longer than 5 msec is skipped
* since this usually is caused by waiting for events via select() and co.
*
* Negative latencies (caused by time going backwards) are also explicitly
* skipped.
*/
void __sched
__account_scheduler_latency(struct task_struct *tsk, int usecs, int inter)
account_scheduler_latency(struct task_struct *tsk, int usecs, int inter)
{
unsigned long flags;
int i, q;
struct latency_record lat;

/* Long interruptible waits are generally user requested... */
if (inter && usecs > 5000)
if (!latencytop_enabled)
return;

/* Negative sleeps are time going backwards */
/* Zero-time sleeps are non-interesting */
if (usecs <= 0)
/* Long interruptible waits are generally user requested... */
if (inter && usecs > 5000)
return;

memset(&lat, 0, sizeof(lat));
Expand All @@ -202,12 +143,12 @@ __account_scheduler_latency(struct task_struct *tsk, int usecs, int inter)
if (tsk->latency_record_count >= LT_SAVECOUNT)
goto out_unlock;

for (i = 0; i < LT_SAVECOUNT; i++) {
for (i = 0; i < LT_SAVECOUNT ; i++) {
struct latency_record *mylat;
int same = 1;

mylat = &tsk->latency_record[i];
for (q = 0; q < LT_BACKTRACEDEPTH; q++) {
for (q = 0 ; q < LT_BACKTRACEDEPTH ; q++) {
unsigned long record = lat.backtrace[q];

if (mylat->backtrace[q] != record) {
Expand Down Expand Up @@ -245,7 +186,7 @@ static int lstats_show(struct seq_file *m, void *v)
for (i = 0; i < MAXLR; i++) {
if (latency_record[i].backtrace[0]) {
int q;
seq_printf(m, "%i %lu %lu ",
seq_printf(m, "%i %li %li ",
latency_record[i].count,
latency_record[i].time,
latency_record[i].max);
Expand Down Expand Up @@ -282,7 +223,7 @@ static int lstats_open(struct inode *inode, struct file *filp)
return single_open(filp, lstats_show, NULL);
}

static const struct file_operations lstats_fops = {
static struct file_operations lstats_fops = {
.open = lstats_open,
.read = seq_read,
.write = lstats_write,
Expand All @@ -295,4 +236,4 @@ static int __init init_lstats_procfs(void)
proc_create("latency_stats", 0644, NULL, &lstats_fops);
return 0;
}
device_initcall(init_lstats_procfs);
__initcall(init_lstats_procfs);
Loading

0 comments on commit ac24934

Please sign in to comment.