posix-cpu-timers: Move state tracking to struct posix_cputimers
[sfrench/cifs-2.6.git] / include / linux / posix-timers.h
index b20798fc5191da497f50c602c58f1943218660c2..a9e3f69d2db4d1c08d97b740f227ab1d31169cca 100644 (file)
@@ -4,11 +4,10 @@
 
 #include <linux/spinlock.h>
 #include <linux/list.h>
-#include <linux/sched.h>
-#include <linux/timex.h>
 #include <linux/alarmtimer.h>
 
-struct siginfo;
+struct kernel_siginfo;
+struct task_struct;
 
 struct cpu_timer_list {
        struct list_head entry;
@@ -63,6 +62,78 @@ static inline int clockid_to_fd(const clockid_t clk)
        return ~(clk >> 3);
 }
 
+#ifdef CONFIG_POSIX_TIMERS
+
+/**
+ * posix_cputimer_base - Container per posix CPU clock
+ * @nextevt:           Earliest-expiration cache
+ * @cpu_timers:                List heads to queue posix CPU timers
+ */
+struct posix_cputimer_base {
+       u64                     nextevt;
+       struct list_head        cpu_timers;
+};
+
+/**
+ * posix_cputimers - Container for posix CPU timer related data
+ * @bases:             Base container for posix CPU clocks
+ * @timers_active:     Timers are queued.
+ * @expiry_active:     Timer expiry is active. Used for
+ *                     process wide timers to avoid multiple
+ *                     task trying to handle expiry concurrently
+ *
+ * Used in task_struct and signal_struct
+ */
+struct posix_cputimers {
+       struct posix_cputimer_base      bases[CPUCLOCK_MAX];
+       unsigned int                    timers_active;
+       unsigned int                    expiry_active;
+};
+
+static inline void posix_cputimers_init(struct posix_cputimers *pct)
+{
+       pct->timers_active = 0;
+       pct->expiry_active = 0;
+       pct->bases[0].nextevt = U64_MAX;
+       pct->bases[1].nextevt = U64_MAX;
+       pct->bases[2].nextevt = U64_MAX;
+       INIT_LIST_HEAD(&pct->bases[0].cpu_timers);
+       INIT_LIST_HEAD(&pct->bases[1].cpu_timers);
+       INIT_LIST_HEAD(&pct->bases[2].cpu_timers);
+}
+
+void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit);
+
+static inline void posix_cputimers_rt_watchdog(struct posix_cputimers *pct,
+                                              u64 runtime)
+{
+       pct->bases[CPUCLOCK_SCHED].nextevt = runtime;
+}
+
+/* Init task static initializer */
+#define INIT_CPU_TIMERBASE(b) {                                                \
+       .nextevt        = U64_MAX,                                      \
+       .cpu_timers     = LIST_HEAD_INIT(b.cpu_timers),                 \
+}
+
+#define INIT_CPU_TIMERBASES(b) {                                       \
+       INIT_CPU_TIMERBASE(b[0]),                                       \
+       INIT_CPU_TIMERBASE(b[1]),                                       \
+       INIT_CPU_TIMERBASE(b[2]),                                       \
+}
+
+#define INIT_CPU_TIMERS(s)                                             \
+       .posix_cputimers = {                                            \
+               .bases = INIT_CPU_TIMERBASES(s.posix_cputimers.bases),  \
+       },
+#else
+struct posix_cputimers { };
+#define INIT_CPU_TIMERS(s)
+static inline void posix_cputimers_init(struct posix_cputimers *pct) { }
+static inline void posix_cputimers_group_init(struct posix_cputimers *pct,
+                                             u64 cpu_limit) { }
+#endif
+
 #define REQUEUE_PENDING 1
 
 /**
@@ -85,7 +156,8 @@ static inline int clockid_to_fd(const clockid_t clk)
  * @it_process:                The task to wakeup on clock_nanosleep (CPU timers)
  * @sigq:              Pointer to preallocated sigqueue
  * @it:                        Union representing the various posix timer type
- *                     internals. Also used for rcu freeing the timer.
+ *                     internals.
+ * @rcu:               RCU head for freeing the timer.
  */
 struct k_itimer {
        struct list_head        list;
@@ -114,11 +186,11 @@ struct k_itimer {
                struct {
                        struct alarm    alarmtimer;
                } alarm;
-               struct rcu_head         rcu;
        } it;
+       struct rcu_head         rcu;
 };
 
-void run_posix_cpu_timers(struct task_struct *task);
+void run_posix_cpu_timers(void);
 void posix_cpu_timers_exit(struct task_struct *task);
 void posix_cpu_timers_exit_group(struct task_struct *task);
 void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,