Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _linux_POSIX_TIMERS_H
0003 #define _linux_POSIX_TIMERS_H
0004 
0005 #include <linux/spinlock.h>
0006 #include <linux/list.h>
0007 #include <linux/alarmtimer.h>
0008 #include <linux/timerqueue.h>
0009 
0010 struct kernel_siginfo;
0011 struct task_struct;
0012 
0013 /*
0014  * Bit fields within a clockid:
0015  *
0016  * The most significant 29 bits hold either a pid or a file descriptor.
0017  *
0018  * Bit 2 indicates whether a cpu clock refers to a thread or a process.
0019  *
0020  * Bits 1 and 0 give the type: PROF=0, VIRT=1, SCHED=2, or FD=3.
0021  *
0022  * A clockid is invalid if bits 2, 1, and 0 are all set.
0023  */
0024 #define CPUCLOCK_PID(clock)     ((pid_t) ~((clock) >> 3))
0025 #define CPUCLOCK_PERTHREAD(clock) \
0026     (((clock) & (clockid_t) CPUCLOCK_PERTHREAD_MASK) != 0)
0027 
0028 #define CPUCLOCK_PERTHREAD_MASK 4
0029 #define CPUCLOCK_WHICH(clock)   ((clock) & (clockid_t) CPUCLOCK_CLOCK_MASK)
0030 #define CPUCLOCK_CLOCK_MASK 3
0031 #define CPUCLOCK_PROF       0
0032 #define CPUCLOCK_VIRT       1
0033 #define CPUCLOCK_SCHED      2
0034 #define CPUCLOCK_MAX        3
0035 #define CLOCKFD         CPUCLOCK_MAX
0036 #define CLOCKFD_MASK        (CPUCLOCK_PERTHREAD_MASK|CPUCLOCK_CLOCK_MASK)
0037 
0038 static inline clockid_t make_process_cpuclock(const unsigned int pid,
0039         const clockid_t clock)
0040 {
0041     return ((~pid) << 3) | clock;
0042 }
0043 static inline clockid_t make_thread_cpuclock(const unsigned int tid,
0044         const clockid_t clock)
0045 {
0046     return make_process_cpuclock(tid, clock | CPUCLOCK_PERTHREAD_MASK);
0047 }
0048 
0049 static inline clockid_t fd_to_clockid(const int fd)
0050 {
0051     return make_process_cpuclock((unsigned int) fd, CLOCKFD);
0052 }
0053 
0054 static inline int clockid_to_fd(const clockid_t clk)
0055 {
0056     return ~(clk >> 3);
0057 }
0058 
0059 #ifdef CONFIG_POSIX_TIMERS
0060 
0061 /**
0062  * cpu_timer - Posix CPU timer representation for k_itimer
0063  * @node:   timerqueue node to queue in the task/sig
0064  * @head:   timerqueue head on which this timer is queued
0065  * @task:   Pointer to target task
0066  * @elist:  List head for the expiry list
0067  * @firing: Timer is currently firing
0068  */
0069 struct cpu_timer {
0070     struct timerqueue_node  node;
0071     struct timerqueue_head  *head;
0072     struct pid      *pid;
0073     struct list_head    elist;
0074     int         firing;
0075 };
0076 
0077 static inline bool cpu_timer_enqueue(struct timerqueue_head *head,
0078                      struct cpu_timer *ctmr)
0079 {
0080     ctmr->head = head;
0081     return timerqueue_add(head, &ctmr->node);
0082 }
0083 
0084 static inline bool cpu_timer_queued(struct cpu_timer *ctmr)
0085 {
0086     return !!ctmr->head;
0087 }
0088 
0089 static inline bool cpu_timer_dequeue(struct cpu_timer *ctmr)
0090 {
0091     if (cpu_timer_queued(ctmr)) {
0092         timerqueue_del(ctmr->head, &ctmr->node);
0093         ctmr->head = NULL;
0094         return true;
0095     }
0096     return false;
0097 }
0098 
0099 static inline u64 cpu_timer_getexpires(struct cpu_timer *ctmr)
0100 {
0101     return ctmr->node.expires;
0102 }
0103 
0104 static inline void cpu_timer_setexpires(struct cpu_timer *ctmr, u64 exp)
0105 {
0106     ctmr->node.expires = exp;
0107 }
0108 
0109 /**
0110  * posix_cputimer_base - Container per posix CPU clock
0111  * @nextevt:        Earliest-expiration cache
0112  * @tqhead:     timerqueue head for cpu_timers
0113  */
0114 struct posix_cputimer_base {
0115     u64         nextevt;
0116     struct timerqueue_head  tqhead;
0117 };
0118 
0119 /**
0120  * posix_cputimers - Container for posix CPU timer related data
0121  * @bases:      Base container for posix CPU clocks
0122  * @timers_active:  Timers are queued.
0123  * @expiry_active:  Timer expiry is active. Used for
0124  *          process wide timers to avoid multiple
0125  *          task trying to handle expiry concurrently
0126  *
0127  * Used in task_struct and signal_struct
0128  */
0129 struct posix_cputimers {
0130     struct posix_cputimer_base  bases[CPUCLOCK_MAX];
0131     unsigned int            timers_active;
0132     unsigned int            expiry_active;
0133 };
0134 
0135 /**
0136  * posix_cputimers_work - Container for task work based posix CPU timer expiry
0137  * @work:   The task work to be scheduled
0138  * @scheduled:  @work has been scheduled already, no further processing
0139  */
0140 struct posix_cputimers_work {
0141     struct callback_head    work;
0142     unsigned int        scheduled;
0143 };
0144 
0145 static inline void posix_cputimers_init(struct posix_cputimers *pct)
0146 {
0147     memset(pct, 0, sizeof(*pct));
0148     pct->bases[0].nextevt = U64_MAX;
0149     pct->bases[1].nextevt = U64_MAX;
0150     pct->bases[2].nextevt = U64_MAX;
0151 }
0152 
0153 void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit);
0154 
0155 static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct,
0156                            u64 runtime)
0157 {
0158     pct->bases[CPUCLOCK_SCHED].nextevt = runtime;
0159 }
0160 
0161 /* Init task static initializer */
0162 #define INIT_CPU_TIMERBASE(b) {                     \
0163     .nextevt    = U64_MAX,                  \
0164 }
0165 
0166 #define INIT_CPU_TIMERBASES(b) {                    \
0167     INIT_CPU_TIMERBASE(b[0]),                   \
0168     INIT_CPU_TIMERBASE(b[1]),                   \
0169     INIT_CPU_TIMERBASE(b[2]),                   \
0170 }
0171 
0172 #define INIT_CPU_TIMERS(s)                      \
0173     .posix_cputimers = {                        \
0174         .bases = INIT_CPU_TIMERBASES(s.posix_cputimers.bases),  \
0175     },
0176 #else
0177 struct posix_cputimers { };
0178 struct cpu_timer { };
0179 #define INIT_CPU_TIMERS(s)
0180 static inline void posix_cputimers_init(struct posix_cputimers *pct) { }
0181 static inline void posix_cputimers_group_init(struct posix_cputimers *pct,
0182                           u64 cpu_limit) { }
0183 #endif
0184 
0185 #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
0186 void clear_posix_cputimers_work(struct task_struct *p);
0187 void posix_cputimers_init_work(void);
0188 #else
0189 static inline void clear_posix_cputimers_work(struct task_struct *p) { }
0190 static inline void posix_cputimers_init_work(void) { }
0191 #endif
0192 
0193 #define REQUEUE_PENDING 1
0194 
0195 /**
0196  * struct k_itimer - POSIX.1b interval timer structure.
0197  * @list:       List head for binding the timer to signals->posix_timers
0198  * @t_hash:     Entry in the posix timer hash table
0199  * @it_lock:        Lock protecting the timer
0200  * @kclock:     Pointer to the k_clock struct handling this timer
0201  * @it_clock:       The posix timer clock id
0202  * @it_id:      The posix timer id for identifying the timer
0203  * @it_active:      Marker that timer is active
0204  * @it_overrun:     The overrun counter for pending signals
0205  * @it_overrun_last:    The overrun at the time of the last delivered signal
0206  * @it_requeue_pending: Indicator that timer waits for being requeued on
0207  *          signal delivery
0208  * @it_sigev_notify:    The notify word of sigevent struct for signal delivery
0209  * @it_interval:    The interval for periodic timers
0210  * @it_signal:      Pointer to the creators signal struct
0211  * @it_pid:     The pid of the process/task targeted by the signal
0212  * @it_process:     The task to wakeup on clock_nanosleep (CPU timers)
0213  * @sigq:       Pointer to preallocated sigqueue
0214  * @it:         Union representing the various posix timer type
0215  *          internals.
0216  * @rcu:        RCU head for freeing the timer.
0217  */
0218 struct k_itimer {
0219     struct list_head    list;
0220     struct hlist_node   t_hash;
0221     spinlock_t      it_lock;
0222     const struct k_clock    *kclock;
0223     clockid_t       it_clock;
0224     timer_t         it_id;
0225     int         it_active;
0226     s64         it_overrun;
0227     s64         it_overrun_last;
0228     int         it_requeue_pending;
0229     int         it_sigev_notify;
0230     ktime_t         it_interval;
0231     struct signal_struct    *it_signal;
0232     union {
0233         struct pid      *it_pid;
0234         struct task_struct  *it_process;
0235     };
0236     struct sigqueue     *sigq;
0237     union {
0238         struct {
0239             struct hrtimer  timer;
0240         } real;
0241         struct cpu_timer    cpu;
0242         struct {
0243             struct alarm    alarmtimer;
0244         } alarm;
0245     } it;
0246     struct rcu_head     rcu;
0247 };
0248 
0249 void run_posix_cpu_timers(void);
0250 void posix_cpu_timers_exit(struct task_struct *task);
0251 void posix_cpu_timers_exit_group(struct task_struct *task);
0252 void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
0253                u64 *newval, u64 *oldval);
0254 
0255 int update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
0256 
0257 void posixtimer_rearm(struct kernel_siginfo *info);
0258 #endif