2019-05-27 06:55:06 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2006-07-14 07:24:36 +00:00
|
|
|
/* delayacct.h - per-task delay accounting
|
|
|
|
*
|
|
|
|
* Copyright (C) Shailabh Nagar, IBM Corp. 2006
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _LINUX_DELAYACCT_H
|
|
|
|
#define _LINUX_DELAYACCT_H
|
|
|
|
|
2017-02-01 10:58:42 +00:00
|
|
|
#include <uapi/linux/taskstats.h>
|
2006-07-14 07:24:36 +00:00
|
|
|
|
2006-07-14 07:24:37 +00:00
|
|
|
/*
|
|
|
|
* Per-task flags relevant to delay accounting
|
|
|
|
* maintained privately to avoid exhausting similar flags in sched.h:PF_*
|
|
|
|
* Used to set current->delays->flags
|
|
|
|
*/
|
|
|
|
#define DELAYACCT_PF_SWAPIN 0x00000001 /* I am doing a swapin */
|
Add cgroupstats
This patch is inspired by the discussion at
http://lkml.org/lkml/2007/4/11/187 and implements per cgroup statistics
as suggested by Andrew Morton in http://lkml.org/lkml/2007/4/11/263. The
patch is on top of 2.6.21-mm1 with Paul's cgroups v9 patches (forward
ported)
This patch implements per cgroup statistics infrastructure and re-uses
code from the taskstats interface. A new set of cgroup operations are
registered with commands and attributes. It should be very easy to
*extend* per cgroup statistics, by adding members to the cgroupstats
structure.
The current model for cgroupstats is a pull, a push model (to post
statistics on interesting events), should be very easy to add. Currently
user space requests for statistics by passing the cgroup file
descriptor. Statistics about the state of all the tasks in the cgroup
is returned to user space.
TODO's/NOTE:
This patch provides an infrastructure for implementing cgroup statistics.
Based on the needs of each controller, we can incrementally add more statistics,
event based support for notification of statistics, accumulation of taskstats
into cgroup statistics in the future.
Sample output
# ./cgroupstats -C /cgroup/a
sleeping 2, blocked 0, running 1, stopped 0, uninterruptible 0
# ./cgroupstats -C /cgroup/
sleeping 154, blocked 0, running 0, stopped 0, uninterruptible 0
If the approach looks good, I'll enhance and post the user space utility for
the same
Feedback, comments, test results are always welcome!
[akpm@linux-foundation.org: build fix]
Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com>
Cc: Paul Menage <menage@google.com>
Cc: Jay Lan <jlan@engr.sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-10-19 06:39:44 +00:00
|
|
|
#define DELAYACCT_PF_BLKIO 0x00000002 /* I am waiting on IO */
|
2006-07-14 07:24:37 +00:00
|
|
|
|
2006-07-14 07:24:36 +00:00
|
|
|
#ifdef CONFIG_TASK_DELAY_ACCT
|
2017-02-01 17:00:26 +00:00
|
|
|
struct task_delay_info {
|
2018-04-23 16:10:23 +00:00
|
|
|
raw_spinlock_t lock;
|
2017-02-01 17:00:26 +00:00
|
|
|
unsigned int flags; /* Private per-task flags */
|
2006-07-14 07:24:36 +00:00
|
|
|
|
2017-02-01 17:00:26 +00:00
|
|
|
/* For each stat XXX, add following, aligned appropriately
|
|
|
|
*
|
|
|
|
* struct timespec XXX_start, XXX_end;
|
|
|
|
* u64 XXX_delay;
|
|
|
|
* u32 XXX_count;
|
|
|
|
*
|
|
|
|
* Atomicity of updates to XXX_delay, XXX_count protected by
|
|
|
|
* single lock above (split into XXX_lock if contention is an issue).
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX_count is incremented on every XXX operation, the delay
|
|
|
|
* associated with the operation is added to XXX_delay.
|
|
|
|
* XXX_delay contains the accumulated delay time in nanoseconds.
|
|
|
|
*/
|
|
|
|
u64 blkio_start; /* Shared by blkio, swapin */
|
|
|
|
u64 blkio_delay; /* wait for sync block io completion */
|
|
|
|
u64 swapin_delay; /* wait for swapin block io completion */
|
|
|
|
u32 blkio_count; /* total count of the number of sync block */
|
|
|
|
/* io operations performed */
|
|
|
|
u32 swapin_count; /* total count of the number of swapin block */
|
|
|
|
/* io operations performed */
|
|
|
|
|
|
|
|
u64 freepages_start;
|
|
|
|
u64 freepages_delay; /* wait for memory reclaim */
|
2018-10-26 22:06:08 +00:00
|
|
|
|
|
|
|
u64 thrashing_start;
|
|
|
|
u64 thrashing_delay; /* wait for thrashing page */
|
|
|
|
|
2017-02-01 17:00:26 +00:00
|
|
|
u32 freepages_count; /* total count of memory reclaim */
|
2018-10-26 22:06:08 +00:00
|
|
|
u32 thrashing_count; /* total count of thrash waits */
|
2017-02-01 17:00:26 +00:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <linux/sched.h>
|
|
|
|
#include <linux/slab.h>
|
2021-05-04 20:43:36 +00:00
|
|
|
#include <linux/jump_label.h>
|
2017-02-01 17:00:26 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_TASK_DELAY_ACCT
|
2021-05-04 20:43:32 +00:00
|
|
|
DECLARE_STATIC_KEY_FALSE(delayacct_key);
|
2006-07-14 07:24:36 +00:00
|
|
|
extern int delayacct_on; /* Delay accounting turned on/off */
|
2006-12-07 04:33:20 +00:00
|
|
|
extern struct kmem_cache *delayacct_cache;
|
2006-07-14 07:24:36 +00:00
|
|
|
extern void delayacct_init(void);
|
2021-05-10 12:01:00 +00:00
|
|
|
|
|
|
|
extern int sysctl_delayacct(struct ctl_table *table, int write, void *buffer,
|
|
|
|
size_t *lenp, loff_t *ppos);
|
|
|
|
|
2006-07-14 07:24:36 +00:00
|
|
|
extern void __delayacct_tsk_init(struct task_struct *);
|
|
|
|
extern void __delayacct_tsk_exit(struct task_struct *);
|
2006-07-14 07:24:37 +00:00
|
|
|
extern void __delayacct_blkio_start(void);
|
2017-12-18 16:15:10 +00:00
|
|
|
extern void __delayacct_blkio_end(struct task_struct *);
|
2021-05-04 20:43:32 +00:00
|
|
|
extern int delayacct_add_tsk(struct taskstats *, struct task_struct *);
|
2006-07-14 07:24:43 +00:00
|
|
|
extern __u64 __delayacct_blkio_ticks(struct task_struct *);
|
2008-07-25 08:48:52 +00:00
|
|
|
extern void __delayacct_freepages_start(void);
|
|
|
|
extern void __delayacct_freepages_end(void);
|
2018-10-26 22:06:08 +00:00
|
|
|
extern void __delayacct_thrashing_start(void);
|
|
|
|
extern void __delayacct_thrashing_end(void);
|
2006-07-14 07:24:36 +00:00
|
|
|
|
Add cgroupstats
This patch is inspired by the discussion at
http://lkml.org/lkml/2007/4/11/187 and implements per cgroup statistics
as suggested by Andrew Morton in http://lkml.org/lkml/2007/4/11/263. The
patch is on top of 2.6.21-mm1 with Paul's cgroups v9 patches (forward
ported)
This patch implements per cgroup statistics infrastructure and re-uses
code from the taskstats interface. A new set of cgroup operations are
registered with commands and attributes. It should be very easy to
*extend* per cgroup statistics, by adding members to the cgroupstats
structure.
The current model for cgroupstats is a pull, a push model (to post
statistics on interesting events), should be very easy to add. Currently
user space requests for statistics by passing the cgroup file
descriptor. Statistics about the state of all the tasks in the cgroup
is returned to user space.
TODO's/NOTE:
This patch provides an infrastructure for implementing cgroup statistics.
Based on the needs of each controller, we can incrementally add more statistics,
event based support for notification of statistics, accumulation of taskstats
into cgroup statistics in the future.
Sample output
# ./cgroupstats -C /cgroup/a
sleeping 2, blocked 0, running 1, stopped 0, uninterruptible 0
# ./cgroupstats -C /cgroup/
sleeping 154, blocked 0, running 0, stopped 0, uninterruptible 0
If the approach looks good, I'll enhance and post the user space utility for
the same
Feedback, comments, test results are always welcome!
[akpm@linux-foundation.org: build fix]
Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com>
Cc: Paul Menage <menage@google.com>
Cc: Jay Lan <jlan@engr.sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-10-19 06:39:44 +00:00
|
|
|
static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
|
|
|
|
{
|
|
|
|
if (p->delays)
|
|
|
|
return (p->delays->flags & DELAYACCT_PF_BLKIO);
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-05-07 01:05:00 +00:00
|
|
|
static inline void delayacct_set_flag(struct task_struct *p, int flag)
|
2006-07-14 07:24:36 +00:00
|
|
|
{
|
2021-05-07 01:05:00 +00:00
|
|
|
if (p->delays)
|
|
|
|
p->delays->flags |= flag;
|
2006-07-14 07:24:36 +00:00
|
|
|
}
|
|
|
|
|
2021-05-07 01:05:00 +00:00
|
|
|
static inline void delayacct_clear_flag(struct task_struct *p, int flag)
|
2006-07-14 07:24:36 +00:00
|
|
|
{
|
2021-05-07 01:05:00 +00:00
|
|
|
if (p->delays)
|
|
|
|
p->delays->flags &= ~flag;
|
2006-07-14 07:24:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void delayacct_tsk_init(struct task_struct *tsk)
|
|
|
|
{
|
|
|
|
/* reinitialize in case parent's non-null pointer was dup'ed*/
|
|
|
|
tsk->delays = NULL;
|
2006-07-30 10:03:11 +00:00
|
|
|
if (delayacct_on)
|
2006-07-14 07:24:36 +00:00
|
|
|
__delayacct_tsk_init(tsk);
|
|
|
|
}
|
|
|
|
|
2006-09-01 04:27:38 +00:00
|
|
|
/* Free tsk->delays. Called from bad fork and __put_task_struct
|
|
|
|
* where there's no risk of tsk->delays being accessed elsewhere
|
|
|
|
*/
|
|
|
|
static inline void delayacct_tsk_free(struct task_struct *tsk)
|
2006-07-14 07:24:36 +00:00
|
|
|
{
|
|
|
|
if (tsk->delays)
|
2006-09-01 04:27:38 +00:00
|
|
|
kmem_cache_free(delayacct_cache, tsk->delays);
|
|
|
|
tsk->delays = NULL;
|
2006-07-14 07:24:36 +00:00
|
|
|
}
|
|
|
|
|
2006-07-14 07:24:37 +00:00
|
|
|
static inline void delayacct_blkio_start(void)
|
|
|
|
{
|
2021-05-04 20:43:32 +00:00
|
|
|
if (!static_branch_unlikely(&delayacct_key))
|
2021-05-04 20:43:36 +00:00
|
|
|
return;
|
|
|
|
|
2021-05-07 01:05:00 +00:00
|
|
|
delayacct_set_flag(current, DELAYACCT_PF_BLKIO);
|
2006-07-14 07:24:37 +00:00
|
|
|
if (current->delays)
|
|
|
|
__delayacct_blkio_start();
|
|
|
|
}
|
|
|
|
|
2017-12-18 16:15:10 +00:00
|
|
|
static inline void delayacct_blkio_end(struct task_struct *p)
|
2006-07-14 07:24:37 +00:00
|
|
|
{
|
2021-05-04 20:43:32 +00:00
|
|
|
if (!static_branch_unlikely(&delayacct_key))
|
2021-05-04 20:43:36 +00:00
|
|
|
return;
|
|
|
|
|
2018-07-26 23:37:08 +00:00
|
|
|
if (p->delays)
|
2017-12-18 16:15:10 +00:00
|
|
|
__delayacct_blkio_end(p);
|
2021-05-07 01:05:00 +00:00
|
|
|
delayacct_clear_flag(p, DELAYACCT_PF_BLKIO);
|
2006-07-14 07:24:37 +00:00
|
|
|
}
|
|
|
|
|
2006-07-14 07:24:43 +00:00
|
|
|
static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
|
|
|
|
{
|
|
|
|
if (tsk->delays)
|
|
|
|
return __delayacct_blkio_ticks(tsk);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-07-25 08:48:52 +00:00
|
|
|
static inline void delayacct_freepages_start(void)
|
|
|
|
{
|
|
|
|
if (current->delays)
|
|
|
|
__delayacct_freepages_start();
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void delayacct_freepages_end(void)
|
|
|
|
{
|
|
|
|
if (current->delays)
|
|
|
|
__delayacct_freepages_end();
|
|
|
|
}
|
|
|
|
|
2018-10-26 22:06:08 +00:00
|
|
|
static inline void delayacct_thrashing_start(void)
|
|
|
|
{
|
|
|
|
if (current->delays)
|
|
|
|
__delayacct_thrashing_start();
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void delayacct_thrashing_end(void)
|
|
|
|
{
|
|
|
|
if (current->delays)
|
|
|
|
__delayacct_thrashing_end();
|
|
|
|
}
|
|
|
|
|
2006-07-14 07:24:36 +00:00
|
|
|
#else
|
2021-05-07 01:05:00 +00:00
|
|
|
static inline void delayacct_set_flag(struct task_struct *p, int flag)
|
2006-07-14 07:24:36 +00:00
|
|
|
{}
|
2021-05-07 01:05:00 +00:00
|
|
|
static inline void delayacct_clear_flag(struct task_struct *p, int flag)
|
2006-07-14 07:24:36 +00:00
|
|
|
{}
|
|
|
|
static inline void delayacct_init(void)
|
|
|
|
{}
|
|
|
|
static inline void delayacct_tsk_init(struct task_struct *tsk)
|
|
|
|
{}
|
2006-09-01 04:27:38 +00:00
|
|
|
static inline void delayacct_tsk_free(struct task_struct *tsk)
|
2006-07-14 07:24:36 +00:00
|
|
|
{}
|
2006-07-14 07:24:37 +00:00
|
|
|
static inline void delayacct_blkio_start(void)
|
|
|
|
{}
|
2017-12-18 16:15:10 +00:00
|
|
|
static inline void delayacct_blkio_end(struct task_struct *p)
|
2006-07-14 07:24:37 +00:00
|
|
|
{}
|
2006-07-14 07:24:41 +00:00
|
|
|
static inline int delayacct_add_tsk(struct taskstats *d,
|
|
|
|
struct task_struct *tsk)
|
|
|
|
{ return 0; }
|
2006-07-14 07:24:43 +00:00
|
|
|
static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
|
|
|
|
{ return 0; }
|
Add cgroupstats
This patch is inspired by the discussion at
http://lkml.org/lkml/2007/4/11/187 and implements per cgroup statistics
as suggested by Andrew Morton in http://lkml.org/lkml/2007/4/11/263. The
patch is on top of 2.6.21-mm1 with Paul's cgroups v9 patches (forward
ported)
This patch implements per cgroup statistics infrastructure and re-uses
code from the taskstats interface. A new set of cgroup operations are
registered with commands and attributes. It should be very easy to
*extend* per cgroup statistics, by adding members to the cgroupstats
structure.
The current model for cgroupstats is a pull, a push model (to post
statistics on interesting events), should be very easy to add. Currently
user space requests for statistics by passing the cgroup file
descriptor. Statistics about the state of all the tasks in the cgroup
is returned to user space.
TODO's/NOTE:
This patch provides an infrastructure for implementing cgroup statistics.
Based on the needs of each controller, we can incrementally add more statistics,
event based support for notification of statistics, accumulation of taskstats
into cgroup statistics in the future.
Sample output
# ./cgroupstats -C /cgroup/a
sleeping 2, blocked 0, running 1, stopped 0, uninterruptible 0
# ./cgroupstats -C /cgroup/
sleeping 154, blocked 0, running 0, stopped 0, uninterruptible 0
If the approach looks good, I'll enhance and post the user space utility for
the same
Feedback, comments, test results are always welcome!
[akpm@linux-foundation.org: build fix]
Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com>
Cc: Paul Menage <menage@google.com>
Cc: Jay Lan <jlan@engr.sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-10-19 06:39:44 +00:00
|
|
|
static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
|
|
|
|
{ return 0; }
|
2008-07-25 08:48:52 +00:00
|
|
|
static inline void delayacct_freepages_start(void)
|
|
|
|
{}
|
|
|
|
static inline void delayacct_freepages_end(void)
|
|
|
|
{}
|
2018-10-26 22:06:08 +00:00
|
|
|
static inline void delayacct_thrashing_start(void)
|
|
|
|
{}
|
|
|
|
static inline void delayacct_thrashing_end(void)
|
|
|
|
{}
|
2008-07-25 08:48:52 +00:00
|
|
|
|
2006-07-14 07:24:36 +00:00
|
|
|
#endif /* CONFIG_TASK_DELAY_ACCT */
|
|
|
|
|
|
|
|
#endif
|