summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/cgroup.h81
-rw-r--r--include/linux/res_counter.h2
-rw-r--r--include/net/sock.h12
-rw-r--r--include/net/tcp_memcontrol.h4
4 files changed, 64 insertions, 35 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 5a85b34..d3f5fba 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -16,6 +16,7 @@
#include <linux/prio_heap.h>
#include <linux/rwsem.h>
#include <linux/idr.h>
+#include <linux/workqueue.h>
#ifdef CONFIG_CGROUPS
@@ -76,12 +77,16 @@ struct cgroup_subsys_state {
unsigned long flags;
/* ID for this css, if possible */
struct css_id __rcu *id;
+
+ /* Used to put @cgroup->dentry on the last css_put() */
+ struct work_struct dput_work;
};
/* bits in struct cgroup_subsys_state flags field */
enum {
CSS_ROOT, /* This CSS is the root of the subsystem */
CSS_REMOVED, /* This CSS is dead */
+ CSS_CLEAR_CSS_REFS, /* @ss->__DEPRECATED_clear_css_refs */
};
/* Caller must verify that the css is not for root cgroup */
@@ -115,16 +120,12 @@ static inline bool css_is_removed(struct cgroup_subsys_state *css)
* the css has been destroyed.
*/
+extern bool __css_tryget(struct cgroup_subsys_state *css);
static inline bool css_tryget(struct cgroup_subsys_state *css)
{
if (test_bit(CSS_ROOT, &css->flags))
return true;
- while (!atomic_inc_not_zero(&css->refcnt)) {
- if (test_bit(CSS_REMOVED, &css->flags))
- return false;
- cpu_relax();
- }
- return true;
+ return __css_tryget(css);
}
/*
@@ -132,11 +133,11 @@ static inline bool css_tryget(struct cgroup_subsys_state *css)
* css_get() or css_tryget()
*/
-extern void __css_put(struct cgroup_subsys_state *css, int count);
+extern void __css_put(struct cgroup_subsys_state *css);
static inline void css_put(struct cgroup_subsys_state *css)
{
if (!test_bit(CSS_ROOT, &css->flags))
- __css_put(css, 1);
+ __css_put(css);
}
/* bits in struct cgroup flags field */
@@ -175,6 +176,7 @@ struct cgroup {
*/
struct list_head sibling; /* my parent's children */
struct list_head children; /* my children */
+ struct list_head files; /* my files */
struct cgroup *parent; /* my parent */
struct dentry __rcu *dentry; /* cgroup fs entry, RCU protected */
@@ -191,6 +193,9 @@ struct cgroup {
*/
struct list_head css_sets;
+ struct list_head allcg_node; /* cgroupfs_root->allcg_list */
+ struct list_head cft_q_node; /* used during cftype add/rm */
+
/*
* Linked list running through all cgroups that can
* potentially be reaped by the release agent. Protected by
@@ -275,11 +280,17 @@ struct cgroup_map_cb {
* - the 'cftype' of the file is file->f_dentry->d_fsdata
*/
-#define MAX_CFTYPE_NAME 64
+/* cftype->flags */
+#define CFTYPE_ONLY_ON_ROOT (1U << 0) /* only create on root cg */
+#define CFTYPE_NOT_ON_ROOT (1U << 1) /* don't create onp root cg */
+
+#define MAX_CFTYPE_NAME 64
+
struct cftype {
/*
* By convention, the name should begin with the name of the
- * subsystem, followed by a period
+ * subsystem, followed by a period. Zero length string indicates
+ * end of cftype array.
*/
char name[MAX_CFTYPE_NAME];
int private;
@@ -295,6 +306,9 @@ struct cftype {
*/
size_t max_write_len;
+ /* CFTYPE_* flags */
+ unsigned int flags;
+
int (*open)(struct inode *inode, struct file *file);
ssize_t (*read)(struct cgroup *cgrp, struct cftype *cft,
struct file *file,
@@ -373,6 +387,16 @@ struct cftype {
struct eventfd_ctx *eventfd);
};
+/*
+ * cftype_sets describe cftypes belonging to a subsystem and are chained at
+ * cgroup_subsys->cftsets. Each cftset points to an array of cftypes
+ * terminated by zero length name.
+ */
+struct cftype_set {
+ struct list_head node; /* chained at subsys->cftsets */
+ const struct cftype *cfts;
+};
+
struct cgroup_scanner {
struct cgroup *cg;
int (*test_task)(struct task_struct *p, struct cgroup_scanner *scan);
@@ -382,21 +406,8 @@ struct cgroup_scanner {
void *data;
};
-/*
- * Add a new file to the given cgroup directory. Should only be
- * called by subsystems from within a populate() method
- */
-int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys,
- const struct cftype *cft);
-
-/*
- * Add a set of new files to the given cgroup directory. Should
- * only be called by subsystems from within a populate() method
- */
-int cgroup_add_files(struct cgroup *cgrp,
- struct cgroup_subsys *subsys,
- const struct cftype cft[],
- int count);
+int cgroup_add_cftypes(struct cgroup_subsys *ss, const struct cftype *cfts);
+int cgroup_rm_cftypes(struct cgroup_subsys *ss, const struct cftype *cfts);
int cgroup_is_removed(const struct cgroup *cgrp);
@@ -461,7 +472,6 @@ struct cgroup_subsys {
void (*fork)(struct task_struct *task);
void (*exit)(struct cgroup *cgrp, struct cgroup *old_cgrp,
struct task_struct *task);
- int (*populate)(struct cgroup_subsys *ss, struct cgroup *cgrp);
void (*post_clone)(struct cgroup *cgrp);
void (*bind)(struct cgroup *root);
@@ -474,6 +484,18 @@ struct cgroup_subsys {
* (not available in early_init time.)
*/
bool use_id;
+
+ /*
+ * If %true, cgroup removal will try to clear css refs by retrying
+ * ss->pre_destroy() until there's no css ref left. This behavior
+ * is strictly for backward compatibility and will be removed as
+ * soon as the current user (memcg) is updated.
+ *
+ * If %false, ss->pre_destroy() can't fail and cgroup removal won't
+ * wait for css refs to drop to zero before proceeding.
+ */
+ bool __DEPRECATED_clear_css_refs;
+
#define MAX_CGROUP_TYPE_NAMELEN 32
const char *name;
@@ -500,6 +522,13 @@ struct cgroup_subsys {
struct idr idr;
spinlock_t id_lock;
+ /* list of cftype_sets */
+ struct list_head cftsets;
+
+ /* base cftypes, automatically [de]registered with subsys itself */
+ struct cftype *base_cftypes;
+ struct cftype_set base_cftset;
+
/* should be defined only by modular subsystems */
struct module *module;
};
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index da81af0..fb20189 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -116,7 +116,7 @@ void res_counter_init(struct res_counter *counter, struct res_counter *parent);
*/
int __must_check res_counter_charge_locked(struct res_counter *counter,
- unsigned long val);
+ unsigned long val, bool force);
int __must_check res_counter_charge(struct res_counter *counter,
unsigned long val, struct res_counter **limit_fail_at);
int __must_check res_counter_charge_nofail(struct res_counter *counter,
diff --git a/include/net/sock.h b/include/net/sock.h
index da93155..d89f058 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -70,16 +70,16 @@
struct cgroup;
struct cgroup_subsys;
#ifdef CONFIG_NET
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp);
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg);
#else
static inline
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
static inline
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp)
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg)
{
}
#endif
@@ -914,9 +914,9 @@ struct proto {
* This function has to setup any files the protocol want to
* appear in the kmem cgroup filesystem.
*/
- int (*init_cgroup)(struct cgroup *cgrp,
+ int (*init_cgroup)(struct mem_cgroup *memcg,
struct cgroup_subsys *ss);
- void (*destroy_cgroup)(struct cgroup *cgrp);
+ void (*destroy_cgroup)(struct mem_cgroup *memcg);
struct cg_proto *(*proto_cgroup)(struct mem_cgroup *memcg);
#endif
};
diff --git a/include/net/tcp_memcontrol.h b/include/net/tcp_memcontrol.h
index 48410ff..7df18bc 100644
--- a/include/net/tcp_memcontrol.h
+++ b/include/net/tcp_memcontrol.h
@@ -12,8 +12,8 @@ struct tcp_memcontrol {
};
struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg);
-int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void tcp_destroy_cgroup(struct cgroup *cgrp);
+int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
+void tcp_destroy_cgroup(struct mem_cgroup *memcg);
unsigned long long tcp_max_memory(const struct mem_cgroup *memcg);
void tcp_prot_mem(struct mem_cgroup *memcg, long val, int idx);
#endif /* _TCP_MEMCG_H */