linux/include/linux/delayacct.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/* delayacct.h - per-task delay accounting
   3 *
   4 * Copyright (C) Shailabh Nagar, IBM Corp. 2006
   5 */
   6
   7#ifndef _LINUX_DELAYACCT_H
   8#define _LINUX_DELAYACCT_H
   9
  10#include <uapi/linux/taskstats.h>
  11
  12/*
  13 * Per-task flags relevant to delay accounting
  14 * maintained privately to avoid exhausting similar flags in sched.h:PF_*
  15 * Used to set current->delays->flags
  16 */
  17#define DELAYACCT_PF_SWAPIN     0x00000001      /* I am doing a swapin */
  18#define DELAYACCT_PF_BLKIO      0x00000002      /* I am waiting on IO */
  19
  20#ifdef CONFIG_TASK_DELAY_ACCT
  21struct task_delay_info {
  22        raw_spinlock_t  lock;
  23        unsigned int    flags;  /* Private per-task flags */
  24
  25        /* For each stat XXX, add following, aligned appropriately
  26         *
  27         * struct timespec XXX_start, XXX_end;
  28         * u64 XXX_delay;
  29         * u32 XXX_count;
  30         *
  31         * Atomicity of updates to XXX_delay, XXX_count protected by
  32         * single lock above (split into XXX_lock if contention is an issue).
  33         */
  34
  35        /*
  36         * XXX_count is incremented on every XXX operation, the delay
  37         * associated with the operation is added to XXX_delay.
  38         * XXX_delay contains the accumulated delay time in nanoseconds.
  39         */
  40        u64 blkio_start;        /* Shared by blkio, swapin */
  41        u64 blkio_delay;        /* wait for sync block io completion */
  42        u64 swapin_delay;       /* wait for swapin block io completion */
  43        u32 blkio_count;        /* total count of the number of sync block */
  44                                /* io operations performed */
  45        u32 swapin_count;       /* total count of the number of swapin block */
  46                                /* io operations performed */
  47
  48        u64 freepages_start;
  49        u64 freepages_delay;    /* wait for memory reclaim */
  50
  51        u64 thrashing_start;
  52        u64 thrashing_delay;    /* wait for thrashing page */
  53
  54        u32 freepages_count;    /* total count of memory reclaim */
  55        u32 thrashing_count;    /* total count of thrash waits */
  56};
  57#endif
  58
  59#include <linux/sched.h>
  60#include <linux/slab.h>
  61
  62#ifdef CONFIG_TASK_DELAY_ACCT
  63extern int delayacct_on;        /* Delay accounting turned on/off */
  64extern struct kmem_cache *delayacct_cache;
  65extern void delayacct_init(void);
  66extern void __delayacct_tsk_init(struct task_struct *);
  67extern void __delayacct_tsk_exit(struct task_struct *);
  68extern void __delayacct_blkio_start(void);
  69extern void __delayacct_blkio_end(struct task_struct *);
  70extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *);
  71extern __u64 __delayacct_blkio_ticks(struct task_struct *);
  72extern void __delayacct_freepages_start(void);
  73extern void __delayacct_freepages_end(void);
  74extern void __delayacct_thrashing_start(void);
  75extern void __delayacct_thrashing_end(void);
  76
  77static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
  78{
  79        if (p->delays)
  80                return (p->delays->flags & DELAYACCT_PF_BLKIO);
  81        else
  82                return 0;
  83}
  84
  85static inline void delayacct_set_flag(int flag)
  86{
  87        if (current->delays)
  88                current->delays->flags |= flag;
  89}
  90
  91static inline void delayacct_clear_flag(int flag)
  92{
  93        if (current->delays)
  94                current->delays->flags &= ~flag;
  95}
  96
  97static inline void delayacct_tsk_init(struct task_struct *tsk)
  98{
  99        /* reinitialize in case parent's non-null pointer was dup'ed*/
 100        tsk->delays = NULL;
 101        if (delayacct_on)
 102                __delayacct_tsk_init(tsk);
 103}
 104
 105/* Free tsk->delays. Called from bad fork and __put_task_struct
 106 * where there's no risk of tsk->delays being accessed elsewhere
 107 */
 108static inline void delayacct_tsk_free(struct task_struct *tsk)
 109{
 110        if (tsk->delays)
 111                kmem_cache_free(delayacct_cache, tsk->delays);
 112        tsk->delays = NULL;
 113}
 114
 115static inline void delayacct_blkio_start(void)
 116{
 117        delayacct_set_flag(DELAYACCT_PF_BLKIO);
 118        if (current->delays)
 119                __delayacct_blkio_start();
 120}
 121
 122static inline void delayacct_blkio_end(struct task_struct *p)
 123{
 124        if (p->delays)
 125                __delayacct_blkio_end(p);
 126        delayacct_clear_flag(DELAYACCT_PF_BLKIO);
 127}
 128
 129static inline int delayacct_add_tsk(struct taskstats *d,
 130                                        struct task_struct *tsk)
 131{
 132        if (!delayacct_on || !tsk->delays)
 133                return 0;
 134        return __delayacct_add_tsk(d, tsk);
 135}
 136
 137static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
 138{
 139        if (tsk->delays)
 140                return __delayacct_blkio_ticks(tsk);
 141        return 0;
 142}
 143
 144static inline void delayacct_freepages_start(void)
 145{
 146        if (current->delays)
 147                __delayacct_freepages_start();
 148}
 149
 150static inline void delayacct_freepages_end(void)
 151{
 152        if (current->delays)
 153                __delayacct_freepages_end();
 154}
 155
 156static inline void delayacct_thrashing_start(void)
 157{
 158        if (current->delays)
 159                __delayacct_thrashing_start();
 160}
 161
 162static inline void delayacct_thrashing_end(void)
 163{
 164        if (current->delays)
 165                __delayacct_thrashing_end();
 166}
 167
 168#else
 169static inline void delayacct_set_flag(int flag)
 170{}
 171static inline void delayacct_clear_flag(int flag)
 172{}
 173static inline void delayacct_init(void)
 174{}
 175static inline void delayacct_tsk_init(struct task_struct *tsk)
 176{}
 177static inline void delayacct_tsk_free(struct task_struct *tsk)
 178{}
 179static inline void delayacct_blkio_start(void)
 180{}
 181static inline void delayacct_blkio_end(struct task_struct *p)
 182{}
 183static inline int delayacct_add_tsk(struct taskstats *d,
 184                                        struct task_struct *tsk)
 185{ return 0; }
 186static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
 187{ return 0; }
 188static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
 189{ return 0; }
 190static inline void delayacct_freepages_start(void)
 191{}
 192static inline void delayacct_freepages_end(void)
 193{}
 194static inline void delayacct_thrashing_start(void)
 195{}
 196static inline void delayacct_thrashing_end(void)
 197{}
 198
 199#endif /* CONFIG_TASK_DELAY_ACCT */
 200
 201#endif
 202