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#include <linux/jump_label.h>
  62
  63#ifdef CONFIG_TASK_DELAY_ACCT
  64DECLARE_STATIC_KEY_FALSE(delayacct_key);
  65extern int delayacct_on;        /* Delay accounting turned on/off */
  66extern struct kmem_cache *delayacct_cache;
  67extern void delayacct_init(void);
  68
  69extern int sysctl_delayacct(struct ctl_table *table, int write, void *buffer,
  70                            size_t *lenp, loff_t *ppos);
  71
  72extern void __delayacct_tsk_init(struct task_struct *);
  73extern void __delayacct_tsk_exit(struct task_struct *);
  74extern void __delayacct_blkio_start(void);
  75extern void __delayacct_blkio_end(struct task_struct *);
  76extern int delayacct_add_tsk(struct taskstats *, struct task_struct *);
  77extern __u64 __delayacct_blkio_ticks(struct task_struct *);
  78extern void __delayacct_freepages_start(void);
  79extern void __delayacct_freepages_end(void);
  80extern void __delayacct_thrashing_start(void);
  81extern void __delayacct_thrashing_end(void);
  82
  83static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
  84{
  85        if (p->delays)
  86                return (p->delays->flags & DELAYACCT_PF_BLKIO);
  87        else
  88                return 0;
  89}
  90
  91static inline void delayacct_set_flag(struct task_struct *p, int flag)
  92{
  93        if (p->delays)
  94                p->delays->flags |= flag;
  95}
  96
  97static inline void delayacct_clear_flag(struct task_struct *p, int flag)
  98{
  99        if (p->delays)
 100                p->delays->flags &= ~flag;
 101}
 102
 103static inline void delayacct_tsk_init(struct task_struct *tsk)
 104{
 105        /* reinitialize in case parent's non-null pointer was dup'ed*/
 106        tsk->delays = NULL;
 107        if (delayacct_on)
 108                __delayacct_tsk_init(tsk);
 109}
 110
 111/* Free tsk->delays. Called from bad fork and __put_task_struct
 112 * where there's no risk of tsk->delays being accessed elsewhere
 113 */
 114static inline void delayacct_tsk_free(struct task_struct *tsk)
 115{
 116        if (tsk->delays)
 117                kmem_cache_free(delayacct_cache, tsk->delays);
 118        tsk->delays = NULL;
 119}
 120
 121static inline void delayacct_blkio_start(void)
 122{
 123        if (!static_branch_unlikely(&delayacct_key))
 124                return;
 125
 126        delayacct_set_flag(current, DELAYACCT_PF_BLKIO);
 127        if (current->delays)
 128                __delayacct_blkio_start();
 129}
 130
 131static inline void delayacct_blkio_end(struct task_struct *p)
 132{
 133        if (!static_branch_unlikely(&delayacct_key))
 134                return;
 135
 136        if (p->delays)
 137                __delayacct_blkio_end(p);
 138        delayacct_clear_flag(p, DELAYACCT_PF_BLKIO);
 139}
 140
 141static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
 142{
 143        if (tsk->delays)
 144                return __delayacct_blkio_ticks(tsk);
 145        return 0;
 146}
 147
 148static inline void delayacct_freepages_start(void)
 149{
 150        if (current->delays)
 151                __delayacct_freepages_start();
 152}
 153
 154static inline void delayacct_freepages_end(void)
 155{
 156        if (current->delays)
 157                __delayacct_freepages_end();
 158}
 159
 160static inline void delayacct_thrashing_start(void)
 161{
 162        if (current->delays)
 163                __delayacct_thrashing_start();
 164}
 165
 166static inline void delayacct_thrashing_end(void)
 167{
 168        if (current->delays)
 169                __delayacct_thrashing_end();
 170}
 171
 172#else
 173static inline void delayacct_set_flag(struct task_struct *p, int flag)
 174{}
 175static inline void delayacct_clear_flag(struct task_struct *p, int flag)
 176{}
 177static inline void delayacct_init(void)
 178{}
 179static inline void delayacct_tsk_init(struct task_struct *tsk)
 180{}
 181static inline void delayacct_tsk_free(struct task_struct *tsk)
 182{}
 183static inline void delayacct_blkio_start(void)
 184{}
 185static inline void delayacct_blkio_end(struct task_struct *p)
 186{}
 187static inline int delayacct_add_tsk(struct taskstats *d,
 188                                        struct task_struct *tsk)
 189{ return 0; }
 190static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
 191{ return 0; }
 192static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
 193{ return 0; }
 194static inline void delayacct_freepages_start(void)
 195{}
 196static inline void delayacct_freepages_end(void)
 197{}
 198static inline void delayacct_thrashing_start(void)
 199{}
 200static inline void delayacct_thrashing_end(void)
 201{}
 202
 203#endif /* CONFIG_TASK_DELAY_ACCT */
 204
 205#endif
 206