cpufreq / sched: SCHED_CPUFREQ_IOWAIT flag to indicate iowait condition
[cascardo/linux.git] / include / linux / sched.h
index d99218a..98fe95f 100644 (file)
@@ -523,6 +523,7 @@ static inline int get_dumpable(struct mm_struct *mm)
 #define MMF_HAS_UPROBES                19      /* has uprobes */
 #define MMF_RECALC_UPROBES     20      /* MMF_HAS_UPROBES can be wrong */
 #define MMF_OOM_REAPED         21      /* mm has been already reaped */
+#define MMF_OOM_NOT_REAPABLE   22      /* mm couldn't be reaped */
 
 #define MMF_INIT_MASK          (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK)
 
@@ -1546,6 +1547,9 @@ struct task_struct {
        /* unserialized, strictly 'current' */
        unsigned in_execve:1; /* bit to tell LSMs we're in execve */
        unsigned in_iowait:1;
+#if !defined(TIF_RESTORE_SIGMASK)
+       unsigned restore_sigmask:1;
+#endif
 #ifdef CONFIG_MEMCG
        unsigned memcg_may_oom:1;
 #ifndef CONFIG_SLOB
@@ -1949,6 +1953,32 @@ static inline int tsk_nr_cpus_allowed(struct task_struct *p)
 #define TNF_FAULT_LOCAL        0x08
 #define TNF_MIGRATE_FAIL 0x10
 
+static inline bool in_vfork(struct task_struct *tsk)
+{
+       bool ret;
+
+       /*
+        * need RCU to access ->real_parent if CLONE_VM was used along with
+        * CLONE_PARENT.
+        *
+        * We check real_parent->mm == tsk->mm because CLONE_VFORK does not
+        * imply CLONE_VM
+        *
+        * CLONE_VFORK can be used with CLONE_PARENT/CLONE_THREAD and thus
+        * ->real_parent is not necessarily the task doing vfork(), so in
+        * theory we can't rely on task_lock() if we want to dereference it.
+        *
+        * And in this case we can't trust the real_parent->mm == tsk->mm
+        * check, it can be false negative. But we do not care, if init or
+        * another oom-unkillable task does this it should blame itself.
+        */
+       rcu_read_lock();
+       ret = tsk->vfork_done && tsk->real_parent->mm == tsk->mm;
+       rcu_read_unlock();
+
+       return ret;
+}
+
 #ifdef CONFIG_NUMA_BALANCING
 extern void task_numa_fault(int last_node, int node, int pages, int flags);
 extern pid_t task_numa_group_id(struct task_struct *p);
@@ -2653,6 +2683,66 @@ extern void sigqueue_free(struct sigqueue *);
 extern int send_sigqueue(struct sigqueue *,  struct task_struct *, int group);
 extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *);
 
+#ifdef TIF_RESTORE_SIGMASK
+/*
+ * Legacy restore_sigmask accessors.  These are inefficient on
+ * SMP architectures because they require atomic operations.
+ */
+
+/**
+ * set_restore_sigmask() - make sure saved_sigmask processing gets done
+ *
+ * This sets TIF_RESTORE_SIGMASK and ensures that the arch signal code
+ * will run before returning to user mode, to process the flag.  For
+ * all callers, TIF_SIGPENDING is already set or it's no harm to set
+ * it.  TIF_RESTORE_SIGMASK need not be in the set of bits that the
+ * arch code will notice on return to user mode, in case those bits
+ * are scarce.  We set TIF_SIGPENDING here to ensure that the arch
+ * signal code always gets run when TIF_RESTORE_SIGMASK is set.
+ */
+static inline void set_restore_sigmask(void)
+{
+       set_thread_flag(TIF_RESTORE_SIGMASK);
+       WARN_ON(!test_thread_flag(TIF_SIGPENDING));
+}
+static inline void clear_restore_sigmask(void)
+{
+       clear_thread_flag(TIF_RESTORE_SIGMASK);
+}
+static inline bool test_restore_sigmask(void)
+{
+       return test_thread_flag(TIF_RESTORE_SIGMASK);
+}
+static inline bool test_and_clear_restore_sigmask(void)
+{
+       return test_and_clear_thread_flag(TIF_RESTORE_SIGMASK);
+}
+
+#else  /* TIF_RESTORE_SIGMASK */
+
+/* Higher-quality implementation, used if TIF_RESTORE_SIGMASK doesn't exist. */
+static inline void set_restore_sigmask(void)
+{
+       current->restore_sigmask = true;
+       WARN_ON(!test_thread_flag(TIF_SIGPENDING));
+}
+static inline void clear_restore_sigmask(void)
+{
+       current->restore_sigmask = false;
+}
+static inline bool test_restore_sigmask(void)
+{
+       return current->restore_sigmask;
+}
+static inline bool test_and_clear_restore_sigmask(void)
+{
+       if (!current->restore_sigmask)
+               return false;
+       current->restore_sigmask = false;
+       return true;
+}
+#endif
+
 static inline void restore_saved_sigmask(void)
 {
        if (test_and_clear_restore_sigmask())
@@ -3379,15 +3469,20 @@ static inline unsigned long rlimit_max(unsigned int limit)
        return task_rlimit_max(current, limit);
 }
 
+#define SCHED_CPUFREQ_RT       (1U << 0)
+#define SCHED_CPUFREQ_DL       (1U << 1)
+#define SCHED_CPUFREQ_IOWAIT   (1U << 2)
+
+#define SCHED_CPUFREQ_RT_DL    (SCHED_CPUFREQ_RT | SCHED_CPUFREQ_DL)
+
 #ifdef CONFIG_CPU_FREQ
 struct update_util_data {
-       void (*func)(struct update_util_data *data,
-                    u64 time, unsigned long util, unsigned long max);
+       void (*func)(struct update_util_data *data, u64 time, unsigned int flags);
 };
 
 void cpufreq_add_update_util_hook(int cpu, struct update_util_data *data,
-                       void (*func)(struct update_util_data *data, u64 time,
-                                    unsigned long util, unsigned long max));
+                       void (*func)(struct update_util_data *data, u64 time,
+                                   unsigned int flags));
 void cpufreq_remove_update_util_hook(int cpu);
 #endif /* CONFIG_CPU_FREQ */