1/* delayacct.h - per-task delay accounting
2 *
3 * Copyright (C) Shailabh Nagar, IBM Corp. 2006
4 *
5 * This program is free software;  you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY;  without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13 * the GNU General Public License for more details.
14 *
15 */
16
17#ifndef _LINUX_DELAYACCT_H
18#define _LINUX_DELAYACCT_H
19
20#include <linux/sched.h>
21#include <linux/slab.h>
22
23/*
24 * Per-task flags relevant to delay accounting
25 * maintained privately to avoid exhausting similar flags in sched.h:PF_*
26 * Used to set current->delays->flags
27 */
28#define DELAYACCT_PF_SWAPIN	0x00000001	/* I am doing a swapin */
29#define DELAYACCT_PF_BLKIO	0x00000002	/* I am waiting on IO */
30
31#ifdef CONFIG_TASK_DELAY_ACCT
32
33extern int delayacct_on;	/* Delay accounting turned on/off */
34extern struct kmem_cache *delayacct_cache;
35extern void delayacct_init(void);
36extern void __delayacct_tsk_init(struct task_struct *);
37extern void __delayacct_tsk_exit(struct task_struct *);
38extern void __delayacct_blkio_start(void);
39extern void __delayacct_blkio_end(void);
40extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *);
41extern __u64 __delayacct_blkio_ticks(struct task_struct *);
42extern void __delayacct_freepages_start(void);
43extern void __delayacct_freepages_end(void);
44
45static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
46{
47	if (p->delays)
48		return (p->delays->flags & DELAYACCT_PF_BLKIO);
49	else
50		return 0;
51}
52
53static inline void delayacct_set_flag(int flag)
54{
55	if (current->delays)
56		current->delays->flags |= flag;
57}
58
59static inline void delayacct_clear_flag(int flag)
60{
61	if (current->delays)
62		current->delays->flags &= ~flag;
63}
64
65static inline void delayacct_tsk_init(struct task_struct *tsk)
66{
67	/* reinitialize in case parent's non-null pointer was dup'ed*/
68	tsk->delays = NULL;
69	if (delayacct_on)
70		__delayacct_tsk_init(tsk);
71}
72
73/* Free tsk->delays. Called from bad fork and __put_task_struct
74 * where there's no risk of tsk->delays being accessed elsewhere
75 */
76static inline void delayacct_tsk_free(struct task_struct *tsk)
77{
78	if (tsk->delays)
79		kmem_cache_free(delayacct_cache, tsk->delays);
80	tsk->delays = NULL;
81}
82
83static inline void delayacct_blkio_start(void)
84{
85	delayacct_set_flag(DELAYACCT_PF_BLKIO);
86	if (current->delays)
87		__delayacct_blkio_start();
88}
89
90static inline void delayacct_blkio_end(void)
91{
92	if (current->delays)
93		__delayacct_blkio_end();
94	delayacct_clear_flag(DELAYACCT_PF_BLKIO);
95}
96
97static inline int delayacct_add_tsk(struct taskstats *d,
98					struct task_struct *tsk)
99{
100	if (!delayacct_on || !tsk->delays)
101		return 0;
102	return __delayacct_add_tsk(d, tsk);
103}
104
105static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
106{
107	if (tsk->delays)
108		return __delayacct_blkio_ticks(tsk);
109	return 0;
110}
111
112static inline void delayacct_freepages_start(void)
113{
114	if (current->delays)
115		__delayacct_freepages_start();
116}
117
118static inline void delayacct_freepages_end(void)
119{
120	if (current->delays)
121		__delayacct_freepages_end();
122}
123
124#else
125static inline void delayacct_set_flag(int flag)
126{}
127static inline void delayacct_clear_flag(int flag)
128{}
129static inline void delayacct_init(void)
130{}
131static inline void delayacct_tsk_init(struct task_struct *tsk)
132{}
133static inline void delayacct_tsk_free(struct task_struct *tsk)
134{}
135static inline void delayacct_blkio_start(void)
136{}
137static inline void delayacct_blkio_end(void)
138{}
139static inline int delayacct_add_tsk(struct taskstats *d,
140					struct task_struct *tsk)
141{ return 0; }
142static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
143{ return 0; }
144static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
145{ return 0; }
146static inline void delayacct_freepages_start(void)
147{}
148static inline void delayacct_freepages_end(void)
149{}
150
151#endif /* CONFIG_TASK_DELAY_ACCT */
152
153#endif
154