Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751900AbbEBBii (ORCPT ); Fri, 1 May 2015 21:38:38 -0400 Received: from mga14.intel.com ([192.55.52.115]:15124 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751215AbbEBBi0 (ORCPT ); Fri, 1 May 2015 21:38:26 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,353,1427785200"; d="scan'208";a="704068512" From: Vikas Shivappa To: vikas.shivappa@intel.com Cc: linux-kernel@vger.kernel.org, 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, peter.zijlstra@intel.com, h.peter.anvin@intel.com, kanaka.d.juvva@intel.com, vikas.shivappa@linux.intel.com Subject: [PATCH 4/7] x86/intel_rdt: Implement scheduling support for Intel RDT Date: Fri, 1 May 2015 18:36:38 -0700 Message-Id: <1430530601-16319-5-git-send-email-vikas.shivappa@linux.intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1430530601-16319-1-git-send-email-vikas.shivappa@linux.intel.com> References: <1430530601-16319-1-git-send-email-vikas.shivappa@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5220 Lines: 169 Adds support for IA32_PQR_ASSOC MSR writes during task scheduling. The high 32 bits in the per processor MSR IA32_PQR_ASSOC represents the CLOSid. During context switch kernel implements this by writing the CLOSid of the cgroup to which the task belongs to the CPU's IA32_PQR_ASSOC MSR. For Cache Allocation, this would let the task fill in the cache 'subset' represented by the cgroup's Cache bit mask(CBM). Signed-off-by: Vikas Shivappa --- arch/x86/include/asm/intel_rdt.h | 54 ++++++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/switch_to.h | 3 +++ arch/x86/kernel/cpu/intel_rdt.c | 3 +++ kernel/sched/core.c | 1 + kernel/sched/sched.h | 3 +++ 5 files changed, 64 insertions(+) diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h index 9e9dbbe..2fc496f 100644 --- a/arch/x86/include/asm/intel_rdt.h +++ b/arch/x86/include/asm/intel_rdt.h @@ -4,9 +4,13 @@ #ifdef CONFIG_CGROUP_RDT #include + +#define MSR_IA32_PQR_ASSOC 0xc8f #define MAX_CBM_LENGTH 32 #define IA32_L3_CBM_BASE 0xc90 #define CBM_FROM_INDEX(x) (IA32_L3_CBM_BASE + x) +DECLARE_PER_CPU(unsigned int, x86_cpu_clos); +extern struct static_key rdt_enable_key; struct rdt_subsys_info { /* Clos Bitmap to keep track of available CLOSids.*/ @@ -24,6 +28,11 @@ struct clos_cbm_map { unsigned int clos_refcnt; }; +static inline bool rdt_enabled(void) +{ + return static_key_false(&rdt_enable_key); +} + /* * Return rdt group corresponding to this container. */ @@ -37,5 +46,50 @@ static inline struct intel_rdt *parent_rdt(struct intel_rdt *ir) return css_rdt(ir->css.parent); } +/* + * Return rdt group to which this task belongs. + */ +static inline struct intel_rdt *task_rdt(struct task_struct *task) +{ + return css_rdt(task_css(task, rdt_cgrp_id)); +} + +/* + * rdt_sched_in() - Writes the task's CLOSid to IA32_PQR_MSR + * if the current Closid is different than the new one. + */ +static inline void rdt_sched_in(struct task_struct *task) +{ + struct intel_rdt *ir; + unsigned int clos; + + if (!rdt_enabled()) + return; + + /* + * This needs to be fixed + * to cache the whole PQR instead of just CLOSid. + * PQR has closid in high 32 bits and CQM-RMID in low 10 bits. + * Should not write a 0 to the low 10 bits of PQR + * and corrupt RMID. + */ + clos = this_cpu_read(x86_cpu_clos); + + rcu_read_lock(); + ir = task_rdt(task); + if (ir->clos == clos) { + rcu_read_unlock(); + return; + } + + wrmsr(MSR_IA32_PQR_ASSOC, 0, ir->clos); + this_cpu_write(x86_cpu_clos, ir->clos); + rcu_read_unlock(); +} + +#else + +static inline void rdt_sched_in(struct task_struct *task) {} + #endif #endif diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h index 751bf4b..82ef4b3 100644 --- a/arch/x86/include/asm/switch_to.h +++ b/arch/x86/include/asm/switch_to.h @@ -8,6 +8,9 @@ struct tss_struct; void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, struct tss_struct *tss); +#include +#define post_arch_switch(current) rdt_sched_in(current) + #ifdef CONFIG_X86_32 #ifdef CONFIG_CC_STACKPROTECTOR diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c index 58b39d6..74b1e28 100644 --- a/arch/x86/kernel/cpu/intel_rdt.c +++ b/arch/x86/kernel/cpu/intel_rdt.c @@ -34,6 +34,8 @@ 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; +struct static_key __read_mostly rdt_enable_key = STATIC_KEY_INIT_FALSE; +DEFINE_PER_CPU(unsigned int, x86_cpu_clos); /* * Mask of CPUs for writing CBM values. We only need one per-socket. @@ -433,6 +435,7 @@ static int __init rdt_late_init(void) __hotcpu_notifier(rdt_cpu_notifier, 0); cpu_notifier_register_done(); + static_key_slow_inc(&rdt_enable_key); pr_info("Max bitmask length:%u,Max ClosIds: %u\n", cbm_len, maxid); return 0; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index f9123a8..cacb490 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2241,6 +2241,7 @@ static struct rq *finish_task_switch(struct task_struct *prev) prev_state = prev->state; vtime_task_switch(prev); finish_arch_switch(prev); + post_arch_switch(current); perf_event_task_sched_in(prev, current); finish_lock_switch(rq, prev); finish_arch_post_lock_switch(); diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index e0e1299..9153747 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1045,6 +1045,9 @@ static inline int task_on_rq_migrating(struct task_struct *p) #ifndef finish_arch_switch # define finish_arch_switch(prev) do { } while (0) #endif +#ifndef post_arch_switch +# define post_arch_switch(current) do { } while (0) +#endif #ifndef finish_arch_post_lock_switch # define finish_arch_post_lock_switch() do { } while (0) #endif -- 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/