Commit 6a26f9c6 authored by Xiu Jianfeng's avatar Xiu Jianfeng Committed by Tejun Heo
Browse files

cgroup/misc: Introduce misc.events.local



Currently the event counting provided by misc.events is hierarchical,
it's not practical if user is only concerned with events of a
specified cgroup. Therefore, introduce misc.events.local collect events
specific to the given cgroup.

This is analogous to memory.events.local and pids.events.local.

Signed-off-by: default avatarXiu Jianfeng <xiujianfeng@huawei.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent b8247665
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -2680,6 +2680,11 @@ Miscellaneous controller provides 3 interface files. If two misc resources (res_
		The number of times the cgroup's resource usage was
		about to go over the max boundary.

  misc.events.local
        Similar to misc.events but the fields in the file are local to the
        cgroup i.e. not hierarchical. The file modified event generated on
        this file reflects only the local events.

Migration and Ownership
~~~~~~~~~~~~~~~~~~~~~~~

+3 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ struct misc_res {
	atomic64_t watermark;
	atomic64_t usage;
	atomic64_t events;
	atomic64_t events_local;
};

/**
@@ -53,6 +54,8 @@ struct misc_cg {

	/* misc.events */
	struct cgroup_file events_file;
	/* misc.events.local */
	struct cgroup_file events_local_file;

	struct misc_res res[MISC_CG_RES_TYPES];
};
+33 −6
Original line number Diff line number Diff line
@@ -134,6 +134,17 @@ static void misc_cg_update_watermark(struct misc_res *res, u64 new_usage)
	}
}

static void misc_cg_event(enum misc_res_type type, struct misc_cg *cg)
{
	atomic64_inc(&cg->res[type].events_local);
	cgroup_file_notify(&cg->events_local_file);

	for (; parent_misc(cg); cg = parent_misc(cg)) {
		atomic64_inc(&cg->res[type].events);
		cgroup_file_notify(&cg->events_file);
	}
}

/**
 * misc_cg_try_charge() - Try charging the misc cgroup.
 * @type: Misc res type to charge.
@@ -177,10 +188,7 @@ int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg, u64 amount)
	return 0;

err_charge:
	for (j = i; j; j = parent_misc(j)) {
		atomic64_inc(&j->res[type].events);
		cgroup_file_notify(&j->events_file);
	}
	misc_cg_event(type, i);

	for (j = cg; j != i; j = parent_misc(j))
		misc_cg_cancel_charge(type, j, amount);
@@ -368,13 +376,16 @@ static int misc_cg_capacity_show(struct seq_file *sf, void *v)
	return 0;
}

static int misc_events_show(struct seq_file *sf, void *v)
static int __misc_events_show(struct seq_file *sf, bool local)
{
	struct misc_cg *cg = css_misc(seq_css(sf));
	u64 events;
	int i;

	for (i = 0; i < MISC_CG_RES_TYPES; i++) {
		if (local)
			events = atomic64_read(&cg->res[i].events_local);
		else
			events = atomic64_read(&cg->res[i].events);
		if (READ_ONCE(misc_res_capacity[i]) || events)
			seq_printf(sf, "%s.max %llu\n", misc_res_name[i], events);
@@ -382,6 +393,16 @@ static int misc_events_show(struct seq_file *sf, void *v)
	return 0;
}

static int misc_events_show(struct seq_file *sf, void *v)
{
	return __misc_events_show(sf, false);
}

static int misc_events_local_show(struct seq_file *sf, void *v)
{
	return __misc_events_show(sf, true);
}

/* Misc cgroup interface files */
static struct cftype misc_cg_files[] = {
	{
@@ -409,6 +430,12 @@ static struct cftype misc_cg_files[] = {
		.file_offset = offsetof(struct misc_cg, events_file),
		.seq_show = misc_events_show,
	},
	{
		.name = "events.local",
		.flags = CFTYPE_NOT_ON_ROOT,
		.file_offset = offsetof(struct misc_cg, events_local_file),
		.seq_show = misc_events_local_show,
	},
	{}
};