linux/include/linux/posix-timers.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _linux_POSIX_TIMERS_H
   3#define _linux_POSIX_TIMERS_H
   4
   5#include <linux/spinlock.h>
   6#include <linux/list.h>
   7#include <linux/alarmtimer.h>
   8#include <linux/timerqueue.h>
   9#include <linux/task_work.h>
  10
  11struct kernel_siginfo;
  12struct task_struct;
  13
  14/*
  15 * Bit fields within a clockid:
  16 *
  17 * The most significant 29 bits hold either a pid or a file descriptor.
  18 *
  19 * Bit 2 indicates whether a cpu clock refers to a thread or a process.
  20 *
  21 * Bits 1 and 0 give the type: PROF=0, VIRT=1, SCHED=2, or FD=3.
  22 *
  23 * A clockid is invalid if bits 2, 1, and 0 are all set.
  24 */
  25#define CPUCLOCK_PID(clock)             ((pid_t) ~((clock) >> 3))
  26#define CPUCLOCK_PERTHREAD(clock) \
  27        (((clock) & (clockid_t) CPUCLOCK_PERTHREAD_MASK) != 0)
  28
  29#define CPUCLOCK_PERTHREAD_MASK 4
  30#define CPUCLOCK_WHICH(clock)   ((clock) & (clockid_t) CPUCLOCK_CLOCK_MASK)
  31#define CPUCLOCK_CLOCK_MASK     3
  32#define CPUCLOCK_PROF           0
  33#define CPUCLOCK_VIRT           1
  34#define CPUCLOCK_SCHED          2
  35#define CPUCLOCK_MAX            3
  36#define CLOCKFD                 CPUCLOCK_MAX
  37#define CLOCKFD_MASK            (CPUCLOCK_PERTHREAD_MASK|CPUCLOCK_CLOCK_MASK)
  38
  39static inline clockid_t make_process_cpuclock(const unsigned int pid,
  40                const clockid_t clock)
  41{
  42        return ((~pid) << 3) | clock;
  43}
  44static inline clockid_t make_thread_cpuclock(const unsigned int tid,
  45                const clockid_t clock)
  46{
  47        return make_process_cpuclock(tid, clock | CPUCLOCK_PERTHREAD_MASK);
  48}
  49
  50static inline clockid_t fd_to_clockid(const int fd)
  51{
  52        return make_process_cpuclock((unsigned int) fd, CLOCKFD);
  53}
  54
  55static inline int clockid_to_fd(const clockid_t clk)
  56{
  57        return ~(clk >> 3);
  58}
  59
  60#ifdef CONFIG_POSIX_TIMERS
  61
  62/**
  63 * cpu_timer - Posix CPU timer representation for k_itimer
  64 * @node:       timerqueue node to queue in the task/sig
  65 * @head:       timerqueue head on which this timer is queued
  66 * @task:       Pointer to target task
  67 * @elist:      List head for the expiry list
  68 * @firing:     Timer is currently firing
  69 */
  70struct cpu_timer {
  71        struct timerqueue_node  node;
  72        struct timerqueue_head  *head;
  73        struct pid              *pid;
  74        struct list_head        elist;
  75        int                     firing;
  76};
  77
  78static inline bool cpu_timer_enqueue(struct timerqueue_head *head,
  79                                     struct cpu_timer *ctmr)
  80{
  81        ctmr->head = head;
  82        return timerqueue_add(head, &ctmr->node);
  83}
  84
  85static inline bool cpu_timer_queued(struct cpu_timer *ctmr)
  86{
  87        return !!ctmr->head;
  88}
  89
  90static inline bool cpu_timer_dequeue(struct cpu_timer *ctmr)
  91{
  92        if (cpu_timer_queued(ctmr)) {
  93                timerqueue_del(ctmr->head, &ctmr->node);
  94                ctmr->head = NULL;
  95                return true;
  96        }
  97        return false;
  98}
  99
 100static inline u64 cpu_timer_getexpires(struct cpu_timer *ctmr)
 101{
 102        return ctmr->node.expires;
 103}
 104
 105static inline void cpu_timer_setexpires(struct cpu_timer *ctmr, u64 exp)
 106{
 107        ctmr->node.expires = exp;
 108}
 109
 110/**
 111 * posix_cputimer_base - Container per posix CPU clock
 112 * @nextevt:            Earliest-expiration cache
 113 * @tqhead:             timerqueue head for cpu_timers
 114 */
 115struct posix_cputimer_base {
 116        u64                     nextevt;
 117        struct timerqueue_head  tqhead;
 118};
 119
 120/**
 121 * posix_cputimers - Container for posix CPU timer related data
 122 * @bases:              Base container for posix CPU clocks
 123 * @timers_active:      Timers are queued.
 124 * @expiry_active:      Timer expiry is active. Used for
 125 *                      process wide timers to avoid multiple
 126 *                      task trying to handle expiry concurrently
 127 *
 128 * Used in task_struct and signal_struct
 129 */
 130struct posix_cputimers {
 131        struct posix_cputimer_base      bases[CPUCLOCK_MAX];
 132        unsigned int                    timers_active;
 133        unsigned int                    expiry_active;
 134};
 135
 136/**
 137 * posix_cputimers_work - Container for task work based posix CPU timer expiry
 138 * @work:       The task work to be scheduled
 139 * @scheduled:  @work has been scheduled already, no further processing
 140 */
 141struct posix_cputimers_work {
 142        struct callback_head    work;
 143        unsigned int            scheduled;
 144};
 145
 146static inline void posix_cputimers_init(struct posix_cputimers *pct)
 147{
 148        memset(pct, 0, sizeof(*pct));
 149        pct->bases[0].nextevt = U64_MAX;
 150        pct->bases[1].nextevt = U64_MAX;
 151        pct->bases[2].nextevt = U64_MAX;
 152}
 153
 154void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit);
 155
 156static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct,
 157                                               u64 runtime)
 158{
 159        pct->bases[CPUCLOCK_SCHED].nextevt = runtime;
 160}
 161
 162/* Init task static initializer */
 163#define INIT_CPU_TIMERBASE(b) {                                         \
 164        .nextevt        = U64_MAX,                                      \
 165}
 166
 167#define INIT_CPU_TIMERBASES(b) {                                        \
 168        INIT_CPU_TIMERBASE(b[0]),                                       \
 169        INIT_CPU_TIMERBASE(b[1]),                                       \
 170        INIT_CPU_TIMERBASE(b[2]),                                       \
 171}
 172
 173#define INIT_CPU_TIMERS(s)                                              \
 174        .posix_cputimers = {                                            \
 175                .bases = INIT_CPU_TIMERBASES(s.posix_cputimers.bases),  \
 176        },
 177#else
 178struct posix_cputimers { };
 179struct cpu_timer { };
 180#define INIT_CPU_TIMERS(s)
 181static inline void posix_cputimers_init(struct posix_cputimers *pct) { }
 182static inline void posix_cputimers_group_init(struct posix_cputimers *pct,
 183                                              u64 cpu_limit) { }
 184#endif
 185
 186#ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
 187void clear_posix_cputimers_work(struct task_struct *p);
 188void posix_cputimers_init_work(void);
 189#else
 190static inline void clear_posix_cputimers_work(struct task_struct *p) { }
 191static inline void posix_cputimers_init_work(void) { }
 192#endif
 193
 194#define REQUEUE_PENDING 1
 195
 196/**
 197 * struct k_itimer - POSIX.1b interval timer structure.
 198 * @list:               List head for binding the timer to signals->posix_timers
 199 * @t_hash:             Entry in the posix timer hash table
 200 * @it_lock:            Lock protecting the timer
 201 * @kclock:             Pointer to the k_clock struct handling this timer
 202 * @it_clock:           The posix timer clock id
 203 * @it_id:              The posix timer id for identifying the timer
 204 * @it_active:          Marker that timer is active
 205 * @it_overrun:         The overrun counter for pending signals
 206 * @it_overrun_last:    The overrun at the time of the last delivered signal
 207 * @it_requeue_pending: Indicator that timer waits for being requeued on
 208 *                      signal delivery
 209 * @it_sigev_notify:    The notify word of sigevent struct for signal delivery
 210 * @it_interval:        The interval for periodic timers
 211 * @it_signal:          Pointer to the creators signal struct
 212 * @it_pid:             The pid of the process/task targeted by the signal
 213 * @it_process:         The task to wakeup on clock_nanosleep (CPU timers)
 214 * @sigq:               Pointer to preallocated sigqueue
 215 * @it:                 Union representing the various posix timer type
 216 *                      internals.
 217 * @rcu:                RCU head for freeing the timer.
 218 */
 219struct k_itimer {
 220        struct list_head        list;
 221        struct hlist_node       t_hash;
 222        spinlock_t              it_lock;
 223        const struct k_clock    *kclock;
 224        clockid_t               it_clock;
 225        timer_t                 it_id;
 226        int                     it_active;
 227        s64                     it_overrun;
 228        s64                     it_overrun_last;
 229        int                     it_requeue_pending;
 230        int                     it_sigev_notify;
 231        ktime_t                 it_interval;
 232        struct signal_struct    *it_signal;
 233        union {
 234                struct pid              *it_pid;
 235                struct task_struct      *it_process;
 236        };
 237        struct sigqueue         *sigq;
 238        union {
 239                struct {
 240                        struct hrtimer  timer;
 241                } real;
 242                struct cpu_timer        cpu;
 243                struct {
 244                        struct alarm    alarmtimer;
 245                } alarm;
 246        } it;
 247        struct rcu_head         rcu;
 248};
 249
 250void run_posix_cpu_timers(void);
 251void posix_cpu_timers_exit(struct task_struct *task);
 252void posix_cpu_timers_exit_group(struct task_struct *task);
 253void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
 254                           u64 *newval, u64 *oldval);
 255
 256void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
 257
 258void posixtimer_rearm(struct kernel_siginfo *info);
 259#endif
 260