]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - include/linux/cgroup.h
futex: Mark the begin of futex exit explicitly
[mirror_ubuntu-bionic-kernel.git] / include / linux / cgroup.h
index dddbc29e20098e0a9f0377f64b0945c87691d315..63e124c41342a8aaca8f4cb0c628badf67cc4f18 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/nsproxy.h>
 #include <linux/user_namespace.h>
 #include <linux/refcount.h>
+#include <linux/kernel_stat.h>
 
 #include <linux/cgroup-defs.h>
 
@@ -42,6 +43,9 @@
 /* walk all threaded css_sets in the domain */
 #define CSS_TASK_ITER_THREADED         (1U << 1)
 
+/* internal flags */
+#define CSS_TASK_ITER_SKIPPED          (1U << 16)
+
 /* a css_task_iter should be treated as an opaque object */
 struct css_task_iter {
        struct cgroup_subsys            *ss;
@@ -56,6 +60,7 @@ struct css_task_iter {
        struct list_head                *task_pos;
        struct list_head                *tasks_head;
        struct list_head                *mg_tasks_head;
+       struct list_head                *dying_tasks_head;
 
        struct css_set                  *cur_cset;
        struct css_set                  *cur_dcset;
@@ -118,6 +123,7 @@ extern int cgroup_can_fork(struct task_struct *p);
 extern void cgroup_cancel_fork(struct task_struct *p);
 extern void cgroup_post_fork(struct task_struct *p);
 void cgroup_exit(struct task_struct *p);
+void cgroup_release(struct task_struct *p);
 void cgroup_free(struct task_struct *p);
 
 int cgroup_init_early(void);
@@ -483,7 +489,7 @@ static inline struct cgroup_subsys_state *task_css(struct task_struct *task,
  *
  * Find the css for the (@task, @subsys_id) combination, increment a
  * reference on and return it.  This function is guaranteed to return a
- * valid css.
+ * valid css.  The returned css may already have been offlined.
  */
 static inline struct cgroup_subsys_state *
 task_get_css(struct task_struct *task, int subsys_id)
@@ -493,7 +499,13 @@ task_get_css(struct task_struct *task, int subsys_id)
        rcu_read_lock();
        while (true) {
                css = task_css(task, subsys_id);
-               if (likely(css_tryget_online(css)))
+               /*
+                * Can't use css_tryget_online() here.  A task which has
+                * PF_EXITING set may stay associated with an offline css.
+                * If such task calls this function, css_tryget_online()
+                * will keep failing.
+                */
+               if (likely(css_tryget(css)))
                        break;
                cpu_relax();
        }
@@ -668,6 +680,7 @@ static inline int cgroup_can_fork(struct task_struct *p) { return 0; }
 static inline void cgroup_cancel_fork(struct task_struct *p) {}
 static inline void cgroup_post_fork(struct task_struct *p) {}
 static inline void cgroup_exit(struct task_struct *p) {}
+static inline void cgroup_release(struct task_struct *p) {}
 static inline void cgroup_free(struct task_struct *p) {}
 
 static inline int cgroup_init_early(void) { return 0; }
@@ -689,6 +702,63 @@ static inline void cgroup_path_from_kernfs_id(const union kernfs_node_id *id,
        char *buf, size_t buflen) {}
 #endif /* !CONFIG_CGROUPS */
 
+/*
+ * Basic resource stats.
+ */
+#ifdef CONFIG_CGROUPS
+
+#ifdef CONFIG_CGROUP_CPUACCT
+void cpuacct_charge(struct task_struct *tsk, u64 cputime);
+void cpuacct_account_field(struct task_struct *tsk, int index, u64 val);
+#else
+static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime) {}
+static inline void cpuacct_account_field(struct task_struct *tsk, int index,
+                                        u64 val) {}
+#endif
+
+void __cgroup_account_cputime(struct cgroup *cgrp, u64 delta_exec);
+void __cgroup_account_cputime_field(struct cgroup *cgrp,
+                                   enum cpu_usage_stat index, u64 delta_exec);
+
+static inline void cgroup_account_cputime(struct task_struct *task,
+                                         u64 delta_exec)
+{
+       struct cgroup *cgrp;
+
+       cpuacct_charge(task, delta_exec);
+
+       rcu_read_lock();
+       cgrp = task_dfl_cgroup(task);
+       if (cgroup_parent(cgrp))
+               __cgroup_account_cputime(cgrp, delta_exec);
+       rcu_read_unlock();
+}
+
+static inline void cgroup_account_cputime_field(struct task_struct *task,
+                                               enum cpu_usage_stat index,
+                                               u64 delta_exec)
+{
+       struct cgroup *cgrp;
+
+       cpuacct_account_field(task, index, delta_exec);
+
+       rcu_read_lock();
+       cgrp = task_dfl_cgroup(task);
+       if (cgroup_parent(cgrp))
+               __cgroup_account_cputime_field(cgrp, index, delta_exec);
+       rcu_read_unlock();
+}
+
+#else  /* CONFIG_CGROUPS */
+
+static inline void cgroup_account_cputime(struct task_struct *task,
+                                         u64 delta_exec) {}
+static inline void cgroup_account_cputime_field(struct task_struct *task,
+                                               enum cpu_usage_stat index,
+                                               u64 delta_exec) {}
+
+#endif /* CONFIG_CGROUPS */
+
 /*
  * sock->sk_cgrp_data handling.  For more info, see sock_cgroup_data
  * definition in cgroup-defs.h.