delayacct.h 5.3 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
2 3 4 5 6 7 8 9
/* delayacct.h - per-task delay accounting
 *
 * Copyright (C) Shailabh Nagar, IBM Corp. 2006
 */

#ifndef _LINUX_DELAYACCT_H
#define _LINUX_DELAYACCT_H

10
#include <uapi/linux/taskstats.h>
11

12 13 14 15 16 17
/*
 * 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 */
B
Balbir Singh 已提交
18
#define DELAYACCT_PF_BLKIO	0x00000002	/* I am waiting on IO */
19

20
#ifdef CONFIG_TASK_DELAY_ACCT
21
struct task_delay_info {
22
	raw_spinlock_t	lock;
23
	unsigned int	flags;	/* Private per-task flags */
24

25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
	/* 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 */
50 51 52 53

	u64 thrashing_start;
	u64 thrashing_delay;	/* wait for thrashing page */

54
	u32 freepages_count;	/* total count of memory reclaim */
55
	u32 thrashing_count;	/* total count of thrash waits */
56 57 58 59 60 61 62
};
#endif

#include <linux/sched.h>
#include <linux/slab.h>

#ifdef CONFIG_TASK_DELAY_ACCT
63
extern int delayacct_on;	/* Delay accounting turned on/off */
64
extern struct kmem_cache *delayacct_cache;
65 66 67
extern void delayacct_init(void);
extern void __delayacct_tsk_init(struct task_struct *);
extern void __delayacct_tsk_exit(struct task_struct *);
68
extern void __delayacct_blkio_start(void);
69
extern void __delayacct_blkio_end(struct task_struct *);
70
extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *);
71
extern __u64 __delayacct_blkio_ticks(struct task_struct *);
72 73
extern void __delayacct_freepages_start(void);
extern void __delayacct_freepages_end(void);
74 75
extern void __delayacct_thrashing_start(void);
extern void __delayacct_thrashing_end(void);
76

B
Balbir Singh 已提交
77 78 79 80 81 82 83 84
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;
}

85
static inline void delayacct_set_flag(struct task_struct *p, int flag)
86
{
87 88
	if (p->delays)
		p->delays->flags |= flag;
89 90
}

91
static inline void delayacct_clear_flag(struct task_struct *p, int flag)
92
{
93 94
	if (p->delays)
		p->delays->flags &= ~flag;
95 96 97 98 99 100
}

static inline void delayacct_tsk_init(struct task_struct *tsk)
{
	/* reinitialize in case parent's non-null pointer was dup'ed*/
	tsk->delays = NULL;
101
	if (delayacct_on)
102 103 104
		__delayacct_tsk_init(tsk);
}

105 106 107 108
/* 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)
109 110
{
	if (tsk->delays)
111 112
		kmem_cache_free(delayacct_cache, tsk->delays);
	tsk->delays = NULL;
113 114
}

115 116
static inline void delayacct_blkio_start(void)
{
117
	delayacct_set_flag(current, DELAYACCT_PF_BLKIO);
118 119 120 121
	if (current->delays)
		__delayacct_blkio_start();
}

122
static inline void delayacct_blkio_end(struct task_struct *p)
123
{
124
	if (p->delays)
125
		__delayacct_blkio_end(p);
126
	delayacct_clear_flag(p, DELAYACCT_PF_BLKIO);
127 128
}

129 130 131
static inline int delayacct_add_tsk(struct taskstats *d,
					struct task_struct *tsk)
{
132
	if (!delayacct_on || !tsk->delays)
133 134 135 136
		return 0;
	return __delayacct_add_tsk(d, tsk);
}

137 138 139 140 141 142 143
static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
{
	if (tsk->delays)
		return __delayacct_blkio_ticks(tsk);
	return 0;
}

144 145 146 147 148 149 150 151 152 153 154 155
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();
}

156 157 158 159 160 161 162 163 164 165 166 167
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();
}

168
#else
169
static inline void delayacct_set_flag(struct task_struct *p, int flag)
170
{}
171
static inline void delayacct_clear_flag(struct task_struct *p, int flag)
172 173 174 175 176
{}
static inline void delayacct_init(void)
{}
static inline void delayacct_tsk_init(struct task_struct *tsk)
{}
177
static inline void delayacct_tsk_free(struct task_struct *tsk)
178
{}
179 180
static inline void delayacct_blkio_start(void)
{}
181
static inline void delayacct_blkio_end(struct task_struct *p)
182
{}
183 184 185
static inline int delayacct_add_tsk(struct taskstats *d,
					struct task_struct *tsk)
{ return 0; }
186 187
static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
{ return 0; }
B
Balbir Singh 已提交
188 189
static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
{ return 0; }
190 191 192 193
static inline void delayacct_freepages_start(void)
{}
static inline void delayacct_freepages_end(void)
{}
194 195 196 197
static inline void delayacct_thrashing_start(void)
{}
static inline void delayacct_thrashing_end(void)
{}
198

199 200 201
#endif /* CONFIG_TASK_DELAY_ACCT */

#endif