Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1211680 > unrolled thread
| Started by | Vikas Shivappa <vikas.shivappa@linux.intel.com> |
|---|---|
| First post | 2015-08-24 00:50 +0200 |
| Last post | 2015-08-24 00:50 +0200 |
| Articles | 5 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH V1 0/6] cgroup,x86/intel_rdt : *pre h/w* Intel code data prioritization support and cgroup changes Vikas Shivappa <vikas.shivappa@linux.intel.com> - 2015-08-24 00:50 +0200
[PATCH 1/6] cgroup: Adds cgroup_destroy_children Vikas Shivappa <vikas.shivappa@linux.intel.com> - 2015-08-24 00:50 +0200
[PATCH 5/6] x86/intel_rdt: Class of service management for code data prioritization Vikas Shivappa <vikas.shivappa@linux.intel.com> - 2015-08-24 00:50 +0200
[PATCH 6/6] x86/intel_rdt: Support dcache and icache mask for Code data prioritization Vikas Shivappa <vikas.shivappa@linux.intel.com> - 2015-08-24 00:50 +0200
[PATCH 2/6] cgroup: Add css_mount and css_umount Vikas Shivappa <vikas.shivappa@linux.intel.com> - 2015-08-24 00:50 +0200
| From | Vikas Shivappa <vikas.shivappa@linux.intel.com> |
|---|---|
| Date | 2015-08-24 00:50 +0200 |
| Subject | [PATCH V1 0/6] cgroup,x86/intel_rdt : *pre h/w* Intel code data prioritization support and cgroup changes |
| Message-ID | <q0Mfn-62H-3@gated-at.bofh.it> |
This patchset has some preparatory patches to cgroup to add a wrapper to to cgroup_rmdir to destroy the cgroup directories recursively, new mount and umount interfaces for ss. It then has patches to support Intel code data prioritization which is an extension of cache allocation and lets allocate code and data cache seperately. Details of the feature can be found in the Intel SDM june 2015 volume 3, section 17.16. The preparatory patches and some part of enabling are tested but otherwise this is mostly a *pre hardware* patch and I still need to test it once i setup the hardware. This patch is dependent on cache allocation patch series V11. http://marc.info/?l=linux-kernel&m=143526051306160 Known issues: - Need changes to the formating of the change logs - Remove some RDT specific flags in cgroup.c - Patch is for initial testing. Will add more documentation on the new APIs if needed. [PATCH 1/6] cgroup: Adds cgroup_destroy_children [PATCH 2/6] cgroup: Add css_mount and css_umount [PATCH 3/6] x86/intel_rdt: Intel Code Data Prioritization detection [PATCH 4/6] x86/intel_rdt: Adds support to enable CDP [PATCH 5/6] x86/intel_rdt: Class of service management for code data [PATCH 6/6] x86/intel_rdt: Support dcache and icache mask for Code -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Vikas Shivappa <vikas.shivappa@linux.intel.com> |
|---|---|
| Date | 2015-08-24 00:50 +0200 |
| Subject | [PATCH 1/6] cgroup: Adds cgroup_destroy_children |
| Message-ID | <q0Mfo-62H-7@gated-at.bofh.it> |
| In reply to | #1211680 |
cgroup currently does not support removing a cgroup directory if it has
children.
Adds a api cgroup_destroy_children which destroys all the children in
the cgroup hierarchy starting from the bottom. After each cgroup node is
destroyed we wait till the css is offlined and freed.
Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
---
include/linux/cgroup.h | 4 +++
kernel/cgroup.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index b9cb94c..292ed97 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -609,6 +609,7 @@ char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
int cgroup_add_dfl_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
int cgroup_rm_cftypes(struct cftype *cfts);
+void cgroup_destroy_children(struct cgroup_subsys_state *css);
bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor);
@@ -705,6 +706,9 @@ struct cgroup_subsys {
* specifies the mask of subsystems that this one depends on.
*/
unsigned int depends_on;
+
+ /* used to wait for freeing of csses */
+ wait_queue_head_t pending_css_free_waitq;
};
#define SUBSYS(_x) extern struct cgroup_subsys _x ## _cgrp_subsys;
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 469dd54..668f614 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1733,6 +1733,33 @@ out:
return ret;
}
+/*
+ * css_wait_free: Wait till css is freed.
+ * @css: The css that we need to wait for
+ *
+ * Wait for the release_css to call the ss->css_free and goto
+ * quiescent state for a while.
+ * This ensures that stage 4/last stage of css destruction is complete.
+ */
+static void css_wait_free(struct cgroup_subsys_state *css)
+{
+ struct cgroup_subsys *ss;
+ DEFINE_WAIT(wait);
+
+ lockdep_assert_held(&cgroup_mutex);
+
+ if (css && (css->flags & CSS_ONLINE)) {
+ ss = css->ss;
+ prepare_to_wait(&ss->pending_css_free_waitq, &wait,
+ TASK_UNINTERRUPTIBLE);
+ mutex_unlock(&cgroup_mutex);
+ schedule();
+ finish_wait(&ss->pending_css_free_waitq, &wait);
+ msleep(10);
+ mutex_lock(&cgroup_mutex);
+ }
+}
+
static struct dentry *cgroup_mount(struct file_system_type *fs_type,
int flags, const char *unused_dev_name,
void *data)
@@ -4387,6 +4414,7 @@ static void css_free_work_fn(struct work_struct *work)
ss->css_free(css);
cgroup_idr_remove(&ss->css_idr, id);
cgroup_put(cgrp);
+ wake_up_all(&ss->pending_css_free_waitq);
} else {
/* cgroup free path */
atomic_dec(&cgrp->root->nr_cgrps);
@@ -4870,6 +4898,62 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
return 0;
};
+/*
+ * cgroup_destroy_recursive - Destroy the cgroup hierarchy
+ *@css: The css we need to wait for to be freed
+ *
+ * Destroy the cgroup hierarchy bottom-up. After destroying
+ * each directory, and wait for css to be freed before
+ * proceeding to destroy its parent.
+ */
+static void cgroup_destroy_recursive(struct cgroup_subsys_state *css)
+{
+ struct cgroup_subsys_state *prev,*par = css,*tmp;
+
+ lockdep_assert_held(&cgroup_mutex);
+
+ if (!css_has_online_children(css))
+ cgroup_destroy_locked(css->cgroup);
+ else {
+ prev = css_next_child(NULL, par);
+ while(prev) {
+ tmp = css_next_child(prev, par);
+ cgroup_destroy_recursive(prev);
+ prev = tmp;
+ }
+
+ cgroup_destroy_locked(css->cgroup);
+ }
+ css_wait_free(css);
+}
+
+/*
+ * cgroup_destroy_children - Destroy all the children of the cgroup
+ * @css: the css which has the cgroup
+ */
+void cgroup_destroy_children(struct cgroup_subsys_state *css)
+{
+ struct cgroup_subsys_state *tmp,*prev, *par;
+
+ lockdep_assert_held(&cgroup_mutex);
+
+ par = css;
+
+ /*
+ * Since we want to give a chance for the css_release
+ * to call the rcu callback, dont hold a rcu lock here.
+ * We destroy the prev and when destroying prev,
+ * make sure the next one is accessible.
+ */
+ prev = css_next_child(NULL, par);
+
+ while(prev) {
+ tmp = css_next_child(prev, par);
+ cgroup_destroy_recursive(prev);
+ prev = tmp;
+ }
+}
+
static int cgroup_rmdir(struct kernfs_node *kn)
{
struct cgroup *cgrp;
@@ -4910,6 +4994,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)
/* We don't handle early failures gracefully */
BUG_ON(IS_ERR(css));
init_and_link_css(css, ss, &cgrp_dfl_root.cgrp);
+ init_waitqueue_head(&ss->pending_css_free_waitq);
/*
* Root csses are never destroyed and we can't initialize
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Vikas Shivappa <vikas.shivappa@linux.intel.com> |
|---|---|
| Date | 2015-08-24 00:50 +0200 |
| Subject | [PATCH 5/6] x86/intel_rdt: Class of service management for code data prioritization |
| Message-ID | <q0Mfo-62H-9@gated-at.bofh.it> |
| In reply to | #1211680 |
Add support to manage CLOSid(class of service id) for code data
prioritization(CDP). Includes allocating, freeing closid and closid_get
and closid_put.
During mount if the mode is changed between cdp and cache allocation
only, all the CLOSids are freed. When a new cgroup is created it
inherits its parents CLOSid in CDP just like in Cache allocation.
---
arch/x86/kernel/cpu/intel_rdt.c | 127 +++++++++++++++++++++++++---------------
1 file changed, 81 insertions(+), 46 deletions(-)
diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c
index 155ac51..285db1e 100644
--- a/arch/x86/kernel/cpu/intel_rdt.c
+++ b/arch/x86/kernel/cpu/intel_rdt.c
@@ -166,6 +166,85 @@ static void closcbm_map_dump(void)
}
}
+static void closid_map_init(void)
+{
+ u32 maxid = boot_cpu_data.x86_cache_max_closid;
+
+ bitmap_zero(rdtss_info.closmap, maxid);
+}
+
+static inline void closid_get(u32 closid)
+{
+ lockdep_assert_held(&rdt_group_mutex);
+
+ if (!rdtss_info.cdp_enable)
+ cat_cm_map[closid].clos_refcnt++;
+ else
+ cdp_cm_map[closid].clos_refcnt++;
+}
+
+static int closid_alloc(struct intel_rdt *ir)
+{
+ u32 maxid;
+ u32 id;
+
+ lockdep_assert_held(&rdt_group_mutex);
+
+ maxid = boot_cpu_data.x86_cache_max_closid;
+ id = find_next_zero_bit(rdtss_info.closmap, maxid, 0);
+ if (id == maxid)
+ return -ENOSPC;
+
+ set_bit(id, rdtss_info.closmap);
+ closid_get(id);
+ ir->closid = id;
+
+ return 0;
+}
+
+static inline void closid_free(u32 closid)
+{
+ clear_bit(closid, rdtss_info.closmap);
+ if (!rdtss_info.cdp_enable) {
+ cat_cm_map[closid].cache_mask = 0;
+ } else {
+ cdp_cm_map[closid].dcache_mask = 0;
+ cdp_cm_map[closid].icache_mask = 0;
+ }
+}
+
+static inline void closid_cat_put(u32 closid)
+{
+ struct cat_clos_mask_map *ccm = &cat_cm_map[closid];
+
+ lockdep_assert_held(&rdt_group_mutex);
+ if (WARN_ON(!ccm->clos_refcnt))
+ return;
+
+ if (!--ccm->clos_refcnt)
+ closid_free(closid);
+}
+
+static inline void closid_cdp_put(u32 closid)
+{
+ struct cdp_clos_mask_map *ccm = &cdp_cm_map[closid];
+
+ lockdep_assert_held(&rdt_group_mutex);
+ if (WARN_ON(!ccm->clos_refcnt))
+ return;
+
+ if (!--ccm->clos_refcnt)
+ closid_free(closid);
+}
+
+static inline void closid_put(u32 closid)
+{
+ if (!rdtss_info.cdp_enable)
+ closid_cat_put(closid);
+ else
+ closid_cdp_put(closid);
+}
+
static void cdp_cm_map_reset(int maxid, unsigned long max_cbm_mask)
{
size_t sizeb;
@@ -266,6 +345,8 @@ static void rdt_css_mount(void* info)
else
cdp_disable();
+ closid_map_init();
+
rdtss_info.cdp_enable = enable_cdp;
mutex_unlock(&rdt_group_mutex);
}
@@ -288,52 +369,6 @@ static inline void rdt_cdp_init(int cdp_maxid, unsigned long max_cbm_mask)
rdtss_info.cdp_supported = true;
}
-static inline void closid_get(u32 closid)
-{
- struct cat_clos_mask_map *ccm = &cat_cm_map[closid];
-
- lockdep_assert_held(&rdt_group_mutex);
-
- ccm->clos_refcnt++;
-}
-
-static int closid_alloc(struct intel_rdt *ir)
-{
- u32 maxid;
- u32 id;
-
- lockdep_assert_held(&rdt_group_mutex);
-
- maxid = boot_cpu_data.x86_cache_max_closid;
- id = find_next_zero_bit(rdtss_info.closmap, maxid, 0);
- if (id == maxid)
- return -ENOSPC;
-
- set_bit(id, rdtss_info.closmap);
- closid_get(id);
- ir->closid = id;
-
- return 0;
-}
-
-static inline void closid_free(u32 closid)
-{
- clear_bit(closid, rdtss_info.closmap);
- cat_cm_map[closid].cache_mask = 0;
-}
-
-static inline void closid_put(u32 closid)
-{
- struct cat_clos_mask_map *ccm = &cat_cm_map[closid];
-
- lockdep_assert_held(&rdt_group_mutex);
- if (WARN_ON(!ccm->clos_refcnt))
- return;
-
- if (!--ccm->clos_refcnt)
- closid_free(closid);
-}
-
void __intel_rdt_sched_in(void)
{
struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Vikas Shivappa <vikas.shivappa@linux.intel.com> |
|---|---|
| Date | 2015-08-24 00:50 +0200 |
| Subject | [PATCH 6/6] x86/intel_rdt: Support dcache and icache mask for Code data prioritization |
| Message-ID | <q0Mfo-62H-15@gated-at.bofh.it> |
| In reply to | #1211680 |
Add support to read and write the per cgroup data and instruction cache
masks.
- When a new cgroup directory is created it inherits the parents dcache
and icache mask. So a mkdir never fails.
- When user changes the mask, we look to see if we can reuse an
existing CLOSid or else allocate a new one. When we run of CLOSids , we
simply return -ENOSPC.
---
arch/x86/kernel/cpu/intel_rdt.c | 177 ++++++++++++++++++++++++++++++++++++----
1 file changed, 163 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c
index 285db1e..d0eaf04 100644
--- a/arch/x86/kernel/cpu/intel_rdt.c
+++ b/arch/x86/kernel/cpu/intel_rdt.c
@@ -428,6 +428,22 @@ static int intel_cache_alloc_cbm_read(struct seq_file *m, void *v)
return 0;
}
+static int cdp_dcache_read(struct seq_file *m, void *v)
+{
+ struct intel_rdt *ir = css_rdt(seq_css(m));
+
+ seq_printf(m, "%08lx\n", cdp_cm_map[ir->closid].dcache_mask);
+ return 0;
+}
+
+static int cdp_icache_read(struct seq_file *m, void *v)
+{
+ struct intel_rdt *ir = css_rdt(seq_css(m));
+
+ seq_printf(m, "%08lx\n", cdp_cm_map[ir->closid].icache_mask);
+ return 0;
+}
+
static inline bool cbm_is_contiguous(unsigned long var)
{
unsigned long maxcbm = MAX_CBM_LENGTH;
@@ -445,13 +461,24 @@ static inline bool cbm_is_contiguous(unsigned long var)
return true;
}
-static int cbm_validate(struct intel_rdt *ir, unsigned long cbmvalue)
+static int cache_mask_validate(struct intel_rdt *ir, unsigned long cbmvalue)
{
+ u32 max_cbm = boot_cpu_data.x86_cache_max_cbm_len;
struct cgroup_subsys_state *css;
struct intel_rdt *par, *c;
unsigned long *cbm_tmp;
+ u64 max_mask;
int err = 0;
+ if (ir == &rdt_root_group)
+ return -EPERM;
+
+ max_mask = (1ULL << max_cbm) - 1;
+ if (cbmvalue & ~max_mask) {
+ err = -EINVAL;
+ goto out_err;
+ }
+
if (!cbm_is_contiguous(cbmvalue)) {
pr_err("bitmask should have >=%d bits and be contiguous\n",
min_bitmask_len);
@@ -486,10 +513,12 @@ out_err:
static bool cbm_search(unsigned long cbm, u32 *closid)
{
u32 maxid = boot_cpu_data.x86_cache_max_closid;
+ unsigned long cache_mask;
u32 i;
for (i = 0; i < maxid; i++) {
- if (bitmap_equal(&cbm, &cat_cm_map[i].cache_mask, MAX_CBM_LENGTH)) {
+ cache_mask = cat_cm_map[i].cache_mask;
+ if (bitmap_equal(&cbm, &cache_mask, MAX_CBM_LENGTH)) {
*closid = i;
return true;
}
@@ -511,30 +540,19 @@ static bool cbm_search(unsigned long cbm, u32 *closid)
static int intel_cache_alloc_cbm_write(struct cgroup_subsys_state *css,
struct cftype *cft, u64 cbmvalue)
{
- u32 max_cbm = boot_cpu_data.x86_cache_max_cbm_len;
struct intel_rdt *ir = css_rdt(css);
ssize_t err = 0;
- u64 max_mask;
u32 closid;
- if (ir == &rdt_root_group)
- return -EPERM;
-
/*
* Need global mutex as cbm write may allocate a closid.
*/
mutex_lock(&rdt_group_mutex);
- max_mask = (1ULL << max_cbm) - 1;
- if (cbmvalue & ~max_mask) {
- err = -EINVAL;
- goto out;
- }
-
if (cbmvalue == cat_cm_map[ir->closid].cache_mask)
goto out;
- err = cbm_validate(ir, cbmvalue);
+ err = cache_mask_validate(ir, cbmvalue);
if (err)
goto out;
@@ -567,6 +585,133 @@ out:
return err;
}
+static void cdp_clos_map_dump(void)
+{
+ u32 i;
+
+ pr_debug("CBMMAP\n");
+ for (i = 0; i < boot_cpu_data.x86_cache_max_closid; i++) {
+ pr_debug("dcache_mask: 0x%x, icache_mask=0x%x,clos_refcnt:%u\n",
+ (unsigned int)cdp_cm_map[i].dcache_mask,
+ (unsigned int)cdp_cm_map[i].icache_mask,
+ cdp_cm_map[i].clos_refcnt);
+ }
+}
+
+static bool cdp_mask_search(unsigned long dcache_mask,
+ unsigned long icache_mask, u32 *closid)
+{
+ u32 maxid = boot_cpu_data.x86_cache_max_closid;
+ unsigned long dcm, icm;
+ u32 i;
+
+ for (i = 0; i < maxid; i++) {
+ dcm = cdp_cm_map[i].dcache_mask;
+ icm = cdp_cm_map[i].icache_mask;
+ if (bitmap_equal(&dcache_mask, &dcm, MAX_CBM_LENGTH)
+ && bitmap_equal(&icache_mask, &icm, MAX_CBM_LENGTH)) {
+ *closid = i;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static int cdp_mask_write(struct intel_rdt *ir, u64 dcache_mask,
+ u64 icache_mask)
+{
+ int err = 0;
+ u32 closid;
+
+ /*
+ * Try to get a reference for a different CLOSid and release the
+ * reference to the current CLOSid.
+ * Need to put down the reference here and get it back in case we
+ * run out of closids. Otherwise we run into a problem when
+ * we could be using the last closid that could have been available.
+ */
+ closid_put(ir->closid);
+ if (cdp_mask_search(dcache_mask, icache_mask, &closid)) {
+ ir->closid = closid;
+ closid_get(closid);
+ } else {
+ err = closid_alloc(ir);
+ if (err) {
+ closid_get(ir->closid);
+ goto out;
+ }
+ closid = ir->closid;
+ cdp_cm_map[closid].dcache_mask = dcache_mask;
+ cdp_cm_map[closid].icache_mask = icache_mask;
+ msr_update_all(DCACHE_MASK_INDEX(closid), dcache_mask);
+ msr_update_all(ICACHE_MASK_INDEX(closid), icache_mask);
+ }
+out:
+
+ return err;
+}
+
+static int cdp_dcache_write(struct cgroup_subsys_state *css,
+ struct cftype *cft, u64 new_dcache_mask)
+{
+ unsigned long curr_icache_mask, curr_dcache_mask;
+ struct intel_rdt *ir = css_rdt(css);
+ int err = 0;
+
+ /*
+ * Need global mutex as cache mask write may allocate a closid.
+ */
+ mutex_lock(&rdt_group_mutex);
+
+ curr_dcache_mask = cdp_cm_map[ir->closid].dcache_mask;
+ curr_icache_mask = cdp_cm_map[ir->closid].icache_mask;
+
+ if (new_dcache_mask == curr_dcache_mask)
+ goto out;
+
+ err = cache_mask_validate(ir, new_dcache_mask);
+ if (err)
+ goto out;
+
+ err = cdp_mask_write(ir, new_dcache_mask, curr_icache_mask);
+ cdp_clos_map_dump();
+out:
+ mutex_unlock(&rdt_group_mutex);
+
+ return err;
+}
+
+static int cdp_icache_write(struct cgroup_subsys_state *css,
+ struct cftype *cft, u64 new_icache_mask)
+{
+ unsigned long curr_icache_mask, curr_dcache_mask;
+ struct intel_rdt *ir = css_rdt(css);
+ int err = 0;
+
+ /*
+ * Need global mutex as cache mask write may allocate a closid.
+ */
+ mutex_lock(&rdt_group_mutex);
+
+ curr_dcache_mask = cdp_cm_map[ir->closid].dcache_mask;
+ curr_icache_mask = cdp_cm_map[ir->closid].icache_mask;
+
+ if (new_icache_mask == curr_icache_mask)
+ goto out;
+
+ err = cache_mask_validate(ir, new_icache_mask);
+ if (err)
+ goto out;
+
+ err = cdp_mask_write(ir, curr_dcache_mask, new_icache_mask);
+ cdp_clos_map_dump();
+out:
+ mutex_unlock(&rdt_group_mutex);
+
+ return err;
+}
+
static inline bool rdt_cpumask_update(int cpu)
{
static cpumask_t tmp;
@@ -722,10 +867,14 @@ static struct cftype rdt_files[] = {
{
.name = "icache_mask",
.flags = CFTYPE_ONLY_ON_ROOT | CFTYPE_NOT_ON_ROOT,
+ .seq_show = cdp_icache_read,
+ .write_u64 = cdp_icache_write,
},
{
.name = "dcache_mask",
.flags = CFTYPE_ONLY_ON_ROOT | CFTYPE_NOT_ON_ROOT,
+ .seq_show = cdp_dcache_read,
+ .write_u64 = cdp_dcache_write,
},
{ } /* terminate */
};
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Vikas Shivappa <vikas.shivappa@linux.intel.com> |
|---|---|
| Date | 2015-08-24 00:50 +0200 |
| Subject | [PATCH 2/6] cgroup: Add css_mount and css_umount |
| Message-ID | <q0Mfo-62H-17@gated-at.bofh.it> |
| In reply to | #1211680 |
Add subsystem APIs css_mount and css_umount which will be called during
cgroup_mount and umount respectively. This will let the subsystem
perform any specific setup during mount/umount.
This will be used in code data prioritization code later.
Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
---
include/linux/cgroup.h | 2 ++
kernel/cgroup.c | 12 ++++++++++++
2 files changed, 14 insertions(+)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 292ed97..3ded186 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -655,6 +655,8 @@ struct cgroup_subsys {
struct cgroup_subsys_state *old_css,
struct task_struct *task);
void (*bind)(struct cgroup_subsys_state *root_css);
+ void (*css_mount)(void *mount_info);
+ void (*css_umount)(void);
int disabled;
int early_init;
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 668f614..e139504 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1345,6 +1345,7 @@ struct cgroup_sb_opts {
char *name;
/* User explicitly requested empty subsystem */
bool none;
+ void *mount_info;
};
static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
@@ -1787,6 +1788,11 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
if (ret)
goto out_unlock;
+ for_each_subsys(ss, i) {
+ if ((opts.subsys_mask && (1U << i)) && ss->css_mount)
+ ss->css_mount(opts.mount_info);
+ }
+
/* look for a matching existing root */
if (opts.flags & CGRP_ROOT_SANE_BEHAVIOR) {
cgrp_dfl_root_visible = true;
@@ -1928,7 +1934,13 @@ static void cgroup_kill_sb(struct super_block *sb)
{
struct kernfs_root *kf_root = kernfs_root_from_sb(sb);
struct cgroup_root *root = cgroup_root_from_kf(kf_root);
+ struct cgroup_subsys *ss;
+ int i;
+ for_each_subsys(ss, i) {
+ if ((root->subsys_mask && (1U << i)) && ss->css_umount)
+ ss->css_umount();
+ }
/*
* If @root doesn't have any mounts or children, start killing it.
* This prevents new mounts by disabling percpu_ref_tryget_live().
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web