linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Vikas Shivappa <vikas.shivappa@linux.intel.com>
To: linux-kernel@vger.kernel.org
Cc: vikas.shivappa@intel.com, x86@kernel.org, hpa@zytor.com,
	tglx@linutronix.de, mingo@kernel.org, tj@kernel.org,
	peterz@infradead.org, matt.fleming@intel.com,
	will.auld@intel.com, kanaka.d.juvva@intel.com,
	vikas.shivappa@linux.intel.com
Subject: [PATCH 06/10] x86/intel_rdt: Add new cgroup and Class of service management
Date: Thu,  4 Jun 2015 17:01:33 -0700	[thread overview]
Message-ID: <1433462497-27087-7-git-send-email-vikas.shivappa@linux.intel.com> (raw)
In-Reply-To: <1433462497-27087-1-git-send-email-vikas.shivappa@linux.intel.com>

This patch adds a cgroup subsystem for Intel Resource Director
Technology(RDT) feature and Class of service(CLOSid) management which is
part of common RDT framework.  This cgroup would eventually be used by
all sub-features of RDT and hence be associated with the common RDT
framework as well as sub-feature specific framework.  However current
patch series only adds cache allocation sub-feature specific code.

When a cgroup directory is created it has a CLOSid associated with it
which is inherited from its parent.  The Closid is mapped to a
cache_mask which represents the L3 cache allocation to the cgroup.
Tasks belonging to the cgroup get to fill the cache represented by the
cache_mask.

CLOSid is internal to the kernel and not exposed to user.  Kernel uses
several ways to optimize the allocation of Closid and thereby exposing
the available Closids may actually provide wrong information to users as
it may be dynamically changing depending on its usage.

CLOSid allocation is tracked using a separate bitmap. The maximum number
of CLOSids is specified by the h/w during CPUID enumeration and the
kernel simply throws an -ENOSPC when it runs out of CLOSids.  Each
cache_mask(CBM) has an associated CLOSid.  However if multiple cgroups
have the same cache mask they would also have the same CLOSid.  The
reference count parameter in CLOSid-CBM map keeps track of how many
cgroups are using each CLOSid<->CBM mapping.

Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
---

Changes as per Thomas's and Matt's feedback:

 - removed __ prefix to functions like clos_get which were not following
 convention.
 - added code to take action on a WARN_ON in clos_put. Made a few other
 changes to reduce code text.  -updated better readable/Kernel doc
 format comments for the call to rdt_css_alloc, datastructures .
 - removed cgroup_init

 arch/x86/include/asm/intel_rdt.h |  36 +++++++++++
 arch/x86/kernel/cpu/intel_rdt.c  | 132 ++++++++++++++++++++++++++++++++++++++-
 include/linux/cgroup_subsys.h    |   4 ++
 3 files changed, 170 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/intel_rdt.h

diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h
new file mode 100644
index 0000000..2ce3e2c
--- /dev/null
+++ b/arch/x86/include/asm/intel_rdt.h
@@ -0,0 +1,36 @@
+#ifndef _RDT_H_
+#define _RDT_H_
+
+#ifdef CONFIG_CGROUP_RDT
+
+#include <linux/cgroup.h>
+
+struct rdt_subsys_info {
+	unsigned long *closmap;
+};
+
+struct intel_rdt {
+	struct cgroup_subsys_state css;
+	u32 closid;
+};
+
+struct clos_cbm_map {
+	unsigned long cache_mask;
+	unsigned int clos_refcnt;
+};
+
+/*
+ * Return rdt group corresponding to this container.
+ */
+static inline struct intel_rdt *css_rdt(struct cgroup_subsys_state *css)
+{
+	return css ? container_of(css, struct intel_rdt, css) : NULL;
+}
+
+static inline struct intel_rdt *parent_rdt(struct intel_rdt *ir)
+{
+	return css_rdt(ir->css.parent);
+}
+
+#endif
+#endif
diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c
index 3cd6db6..5ba241e 100644
--- a/arch/x86/kernel/cpu/intel_rdt.c
+++ b/arch/x86/kernel/cpu/intel_rdt.c
@@ -24,17 +24,145 @@
 
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/spinlock.h>
+#include <asm/intel_rdt.h>
+
+/*
+ * ccmap maintains 1:1 mapping between CLOSid and cache bitmask.
+ */
+static struct clos_cbm_map *ccmap;
+static struct rdt_subsys_info rdtss_info;
+static DEFINE_MUTEX(rdt_group_mutex);
+struct intel_rdt rdt_root_group;
+
+static inline void closid_get(u32 closid)
+{
+	struct clos_cbm_map *ccm = &ccmap[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_rdt_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);
+	ccmap[closid].cache_mask = 0;
+}
+
+static inline void closid_put(u32 closid)
+{
+	struct clos_cbm_map *ccm = &ccmap[closid];
+
+	lockdep_assert_held(&rdt_group_mutex);
+	if (WARN_ON(!ccm->clos_refcnt))
+		return;
+
+	if (!--ccm->clos_refcnt)
+		closid_free(closid);
+}
+
+static struct cgroup_subsys_state *
+intel_rdt_css_alloc(struct cgroup_subsys_state *parent_css)
+{
+	struct intel_rdt *parent = css_rdt(parent_css);
+	struct intel_rdt *ir;
+
+	/*
+	 * cgroup_init cannot handle failures gracefully.
+	 * Return rdt_root_group.css instead of failure
+	 * always even when Cache allocation is not supported.
+	 */
+	if (!parent)
+		return &rdt_root_group.css;
+
+	ir = kzalloc(sizeof(struct intel_rdt), GFP_KERNEL);
+	if (!ir)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_lock(&rdt_group_mutex);
+	ir->closid = parent->closid;
+	closid_get(ir->closid);
+	mutex_unlock(&rdt_group_mutex);
+
+	return &ir->css;
+}
+
+static void intel_rdt_css_free(struct cgroup_subsys_state *css)
+{
+	struct intel_rdt *ir = css_rdt(css);
+
+	mutex_lock(&rdt_group_mutex);
+	closid_put(ir->closid);
+	kfree(ir);
+	mutex_unlock(&rdt_group_mutex);
+}
 
 static int __init intel_rdt_late_init(void)
 {
 	struct cpuinfo_x86 *c = &boot_cpu_data;
+	static struct clos_cbm_map *ccm;
+	u32 maxid, max_cbm_len;
+	size_t sizeb;
+	int err = 0;
 
-	if (!cpu_has(c, X86_FEATURE_CAT_L3))
+	if (!cpu_has(c, X86_FEATURE_CAT_L3)) {
+		rdt_root_group.css.ss->disabled = 1;
 		return -ENODEV;
+	}
+	maxid = c->x86_rdt_max_closid;
+	max_cbm_len = c->x86_rdt_max_cbm_len;
+
+	sizeb = BITS_TO_LONGS(maxid) * sizeof(long);
+	rdtss_info.closmap = kzalloc(sizeb, GFP_KERNEL);
+	if (!rdtss_info.closmap) {
+		err = -ENOMEM;
+		goto out_err;
+	}
+
+	sizeb = maxid * sizeof(struct clos_cbm_map);
+	ccmap = kzalloc(sizeb, GFP_KERNEL);
+	if (!ccmap) {
+		kfree(rdtss_info.closmap);
+		err = -ENOMEM;
+		goto out_err;
+	}
+
+	set_bit(0, rdtss_info.closmap);
+	rdt_root_group.closid = 0;
+	ccm = &ccmap[0];
+	ccm->cache_mask = (1ULL << max_cbm_len) - 1;
+	ccm->clos_refcnt = 1;
 
 	pr_info("Intel cache allocation enabled\n");
+out_err:
 
-	return 0;
+	return err;
 }
 
 late_initcall(intel_rdt_late_init);
+
+struct cgroup_subsys intel_rdt_cgrp_subsys = {
+	.css_alloc		= intel_rdt_css_alloc,
+	.css_free		= intel_rdt_css_free,
+	.early_init		= 0,
+};
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index e4a96fb..0339312 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -47,6 +47,10 @@ SUBSYS(net_prio)
 SUBSYS(hugetlb)
 #endif
 
+#if IS_ENABLED(CONFIG_CGROUP_RDT)
+SUBSYS(intel_rdt)
+#endif
+
 /*
  * The following subsystems are not supported on the default hierarchy.
  */
-- 
1.9.1


  parent reply	other threads:[~2015-06-05  0:04 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-05  0:01 [PATCH V8 00/10] New cpumask API and Intel Cache Allocation support Vikas Shivappa
2015-06-05  0:01 ` [PATCH 01/10] cpumask: Introduce cpumask_any_online_but Vikas Shivappa
2015-06-05  0:01 ` [PATCH 02/10] x86/intel_cqm: Modify hot cpu notification handling Vikas Shivappa
2015-06-05  0:01 ` [PATCH 03/10] x86/intel_rapl: Modify hot cpu notification handling for RAPL Vikas Shivappa
2015-06-06  0:43   ` Vikas Shivappa
2015-06-05  0:01 ` [PATCH 04/10] x86/intel_rdt: Cache Allocation documentation and cgroup usage guide Vikas Shivappa
2015-06-05  0:01 ` [PATCH 05/10] x86/intel_rdt: Add support for Cache Allocation detection Vikas Shivappa
2015-06-05  0:01 ` Vikas Shivappa [this message]
2015-06-05  0:01 ` [PATCH 07/10] x86/intel_rdt: Add support for cache bit mask management Vikas Shivappa
2015-06-05  0:01 ` [PATCH 08/10] x86/intel_rdt: Implement scheduling support for Intel RDT Vikas Shivappa
2015-06-06  9:43   ` Thomas Gleixner
2015-06-08 14:37     ` Thomas Gleixner
2015-06-08 16:20       ` Vikas Shivappa
2015-06-08 16:30     ` Vikas Shivappa
2015-06-10 23:38       ` Vikas Shivappa
2015-06-05  0:01 ` [PATCH 09/10] x86/intel_rdt: Hot cpu support for Cache Allocation Vikas Shivappa
2015-06-05  0:01 ` [PATCH 10/10] x86/intel_rdt: Intel haswell Cache Allocation enumeration Vikas Shivappa
  -- strict thread matches above, loose matches on Subject: below --
2015-06-23 22:56 [PATCH V10 00/10] New cpumask API and Intel Cache Allocation support Vikas Shivappa
2015-06-23 22:56 ` [PATCH 06/10] x86/intel_rdt: Add new cgroup and Class of service management Vikas Shivappa
2015-06-12 18:17 [PATCH V9 00/10] New cpumask API and Intel Cache Allocation support Vikas Shivappa
2015-06-12 18:17 ` [PATCH 06/10] x86/intel_rdt: Add new cgroup and Class of service management Vikas Shivappa
2015-06-03 19:09 [PATCH V8 00/10] New cpumask API and Intel Cache Allocation support Vikas Shivappa
2015-06-03 19:09 ` [PATCH 06/10] x86/intel_rdt: Add new cgroup and Class of service management Vikas Shivappa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1433462497-27087-7-git-send-email-vikas.shivappa@linux.intel.com \
    --to=vikas.shivappa@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=kanaka.d.juvva@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matt.fleming@intel.com \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=tj@kernel.org \
    --cc=vikas.shivappa@intel.com \
    --cc=will.auld@intel.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).