Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88d6ae8d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull cgroup updates from Tejun Heo:
 "cgroup file type addition / removal is updated so that file types are
  added and removed instead of individual files so that dynamic file
  type addition / removal can be implemented by cgroup and used by
  controllers.  blkio controller changes which will come through block
  tree are dependent on this.  Other changes include res_counter cleanup
  and disallowing kthread / PF_THREAD_BOUND threads to be attached to
  non-root cgroups.

  There's a reported bug with the file type addition / removal handling
  which can lead to oops on cgroup umount.  The issue is being looked
  into.  It shouldn't cause problems for most setups and isn't a
  security concern."

Fix up trivial conflict in Documentation/feature-removal-schedule.txt

* 'for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: (21 commits)
  res_counter: Account max_usage when calling res_counter_charge_nofail()
  res_counter: Merge res_counter_charge and res_counter_charge_nofail
  cgroups: disallow attaching kthreadd or PF_THREAD_BOUND threads
  cgroup: remove cgroup_subsys->populate()
  cgroup: get rid of populate for memcg
  cgroup: pass struct mem_cgroup instead of struct cgroup to socket memcg
  cgroup: make css->refcnt clearing on cgroup removal optional
  cgroup: use negative bias on css->refcnt to block css_tryget()
  cgroup: implement cgroup_rm_cftypes()
  cgroup: introduce struct cfent
  cgroup: relocate __d_cgrp() and __d_cft()
  cgroup: remove cgroup_add_file[s]()
  cgroup: convert memcg controller to the new cftype interface
  memcg: always create memsw files if CONFIG_CGROUP_MEM_RES_CTLR_SWAP
  cgroup: convert all non-memcg controllers to the new cftype interface
  cgroup: relocate cftype and cgroup_subsys definitions in controllers
  cgroup: merge cft_release_agent cftype array into the base files array
  cgroup: implement cgroup_add_cftypes() and friends
  cgroup: build list of all cgroups under a given cgroupfs_root
  cgroup: move cgroup_clear_directory() call out of cgroup_populate_dir()
  ...
parents f5c10189 0d4dde1a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -77,11 +77,11 @@ to work with it.
	where the charging failed.

 d. int res_counter_charge_locked
			(struct res_counter *rc, unsigned long val)
			(struct res_counter *rc, unsigned long val, bool force)

	The same as res_counter_charge(), but it must not acquire/release the
	res_counter->lock internally (it must be called with res_counter->lock
	held).
	held). The force parameter indicates whether we can bypass the limit.

 e. void res_counter_uncharge[_locked]
			(struct res_counter *rc, unsigned long val)
+11 −0
Original line number Diff line number Diff line
@@ -556,3 +556,14 @@ Why: The V4L2_CID_VCENTER, V4L2_CID_HCENTER controls have been deprecated
	There are newer controls (V4L2_CID_PAN*, V4L2_CID_TILT*) that provide
	similar	functionality.
Who:	Sylwester Nawrocki <sylvester.nawrocki@gmail.com>

----------------------------

What:	cgroup option updates via remount
When:	March 2013
Why:	Remount currently allows changing bound subsystems and
	release_agent.  Rebinding is hardly useful as it only works
	when the hierarchy is empty and release_agent itself should be
	replaced with conventional fsnotify.

----------------------------
+17 −28
Original line number Diff line number Diff line
@@ -28,34 +28,12 @@ static LIST_HEAD(blkio_list);
struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT };
EXPORT_SYMBOL_GPL(blkio_root_cgroup);

static struct cgroup_subsys_state *blkiocg_create(struct cgroup *);
static int blkiocg_can_attach(struct cgroup *, struct cgroup_taskset *);
static void blkiocg_attach(struct cgroup *, struct cgroup_taskset *);
static void blkiocg_destroy(struct cgroup *);
static int blkiocg_populate(struct cgroup_subsys *, struct cgroup *);

/* for encoding cft->private value on file */
#define BLKIOFILE_PRIVATE(x, val)	(((x) << 16) | (val))
/* What policy owns the file, proportional or throttle */
#define BLKIOFILE_POLICY(val)		(((val) >> 16) & 0xffff)
#define BLKIOFILE_ATTR(val)		((val) & 0xffff)

struct cgroup_subsys blkio_subsys = {
	.name = "blkio",
	.create = blkiocg_create,
	.can_attach = blkiocg_can_attach,
	.attach = blkiocg_attach,
	.destroy = blkiocg_destroy,
	.populate = blkiocg_populate,
#ifdef CONFIG_BLK_CGROUP
	/* note: blkio_subsys_id is otherwise defined in blk-cgroup.h */
	.subsys_id = blkio_subsys_id,
#endif
	.use_id = 1,
	.module = THIS_MODULE,
};
EXPORT_SYMBOL_GPL(blkio_subsys);

static inline void blkio_policy_insert_node(struct blkio_cgroup *blkcg,
					    struct blkio_policy_node *pn)
{
@@ -1537,14 +1515,9 @@ struct cftype blkio_files[] = {
		.read_map = blkiocg_file_read_map,
	},
#endif
	{ }	/* terminate */
};

static int blkiocg_populate(struct cgroup_subsys *subsys, struct cgroup *cgroup)
{
	return cgroup_add_files(cgroup, subsys, blkio_files,
				ARRAY_SIZE(blkio_files));
}

static void blkiocg_destroy(struct cgroup *cgroup)
{
	struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup);
@@ -1658,6 +1631,22 @@ static void blkiocg_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
	}
}

struct cgroup_subsys blkio_subsys = {
	.name = "blkio",
	.create = blkiocg_create,
	.can_attach = blkiocg_can_attach,
	.attach = blkiocg_attach,
	.destroy = blkiocg_destroy,
#ifdef CONFIG_BLK_CGROUP
	/* note: blkio_subsys_id is otherwise defined in blk-cgroup.h */
	.subsys_id = blkio_subsys_id,
#endif
	.base_cftypes = blkio_files,
	.use_id = 1,
	.module = THIS_MODULE,
};
EXPORT_SYMBOL_GPL(blkio_subsys);

void blkio_policy_register(struct blkio_policy_type *blkiop)
{
	spin_lock(&blkio_list_lock);
+55 −26
Original line number Diff line number Diff line
@@ -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
 */

/* 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;
};
+1 −1
Original line number Diff line number Diff line
@@ -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,
Loading