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