From: He Chen <he.chen@linux.intel.com>
To: xen-devel@lists.xenproject.org
Cc: wei.liu2@citrix.com, ian.campbell@citrix.com,
stefano.stabellini@eu.citrix.com, andrew.cooper3@citrix.com,
He Chen <he.chen@linux.intel.com>,
ian.jackson@eu.citrix.com, jbeulich@suse.com,
chao.p.peng@linux.intel.com, keir@xen.org
Subject: [PATCH v2 1/4] x86: Support enable CDP by boot parameter and add get CDP status
Date: Wed, 9 Sep 2015 13:16:45 +0800 [thread overview]
Message-ID: <1441775808-29766-2-git-send-email-he.chen@linux.intel.com> (raw)
In-Reply-To: <1441775808-29766-1-git-send-email-he.chen@linux.intel.com>
Intel Code/Data Prioritization(CDP) feature is based on CAT. cdp_enabled
is added to CAT socket info to indicate CDP is on or off on the socket,
note that cos_max would be half when CDP is on. struct psr_cat_cbm is
extended to support CDP operation. Extend psr_get_cat_l3_info sysctl to
get CDP status.
Signed-off-by: He Chen <he.chen@linux.intel.com>
---
xen/arch/x86/psr.c | 84 ++++++++++++++++++++++++++++++++++-------
xen/arch/x86/sysctl.c | 5 ++-
xen/include/asm-x86/msr-index.h | 3 ++
xen/include/asm-x86/psr.h | 11 +++++-
xen/include/public/sysctl.h | 2 +
5 files changed, 89 insertions(+), 16 deletions(-)
diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c
index c0daa2e..ba0f726 100644
--- a/xen/arch/x86/psr.c
+++ b/xen/arch/x86/psr.c
@@ -17,13 +17,21 @@
#include <xen/cpu.h>
#include <xen/err.h>
#include <xen/sched.h>
+#include <xen/domain.h>
#include <asm/psr.h>
#define PSR_CMT (1<<0)
#define PSR_CAT (1<<1)
+#define PSR_CDP (1<<2)
struct psr_cat_cbm {
- uint64_t cbm;
+ union {
+ uint64_t cbm;
+ struct {
+ uint64_t code;
+ uint64_t data;
+ } cdp;
+ } u;
unsigned int ref;
};
@@ -32,6 +40,7 @@ struct psr_cat_socket_info {
unsigned int cos_max;
struct psr_cat_cbm *cos_to_cbm;
spinlock_t cbm_lock;
+ bool_t cdp_enabled;
};
struct psr_assoc {
@@ -43,6 +52,7 @@ struct psr_cmt *__read_mostly psr_cmt;
static unsigned long *__read_mostly cat_socket_enable;
static struct psr_cat_socket_info *__read_mostly cat_socket_info;
+static unsigned long *__read_mostly cdp_socket_enable;
static unsigned int __initdata opt_psr;
static unsigned int __initdata opt_rmid_max = 255;
@@ -94,6 +104,7 @@ static void __init parse_psr_param(char *s)
parse_psr_bool(s, val_str, "cmt", PSR_CMT);
parse_psr_bool(s, val_str, "cat", PSR_CAT);
+ parse_psr_bool(s, val_str, "cdp", PSR_CDP);
if ( val_str && !strcmp(s, "rmid_max") )
opt_rmid_max = simple_strtoul(val_str, NULL, 0);
@@ -262,7 +273,7 @@ static struct psr_cat_socket_info *get_cat_socket_info(unsigned int socket)
}
int psr_get_cat_l3_info(unsigned int socket, uint32_t *cbm_len,
- uint32_t *cos_max)
+ uint32_t *cos_max, uint32_t *flags)
{
struct psr_cat_socket_info *info = get_cat_socket_info(socket);
@@ -272,6 +283,10 @@ int psr_get_cat_l3_info(unsigned int socket, uint32_t *cbm_len,
*cbm_len = info->cbm_len;
*cos_max = info->cos_max;
+ *flags = 0;
+ if ( info->cdp_enabled )
+ *flags |= PSR_CAT_FLAG_L3_CDP;
+
return 0;
}
@@ -282,7 +297,7 @@ int psr_get_l3_cbm(struct domain *d, unsigned int socket, uint64_t *cbm)
if ( IS_ERR(info) )
return PTR_ERR(info);
- *cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].cbm;
+ *cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].u.cbm;
return 0;
}
@@ -313,19 +328,34 @@ static bool_t psr_check_cbm(unsigned int cbm_len, uint64_t cbm)
struct cos_cbm_info
{
unsigned int cos;
- uint64_t cbm;
+ uint64_t cbm_code;
+ uint64_t cbm_data;
+ bool_t cdp;
};
static void do_write_l3_cbm(void *data)
{
struct cos_cbm_info *info = data;
- wrmsrl(MSR_IA32_PSR_L3_MASK(info->cos), info->cbm);
+ if ( info->cdp )
+ {
+ wrmsrl(MSR_IA32_PSR_L3_MASK_CBM_CODE(info->cos), info->cbm_code);
+ wrmsrl(MSR_IA32_PSR_L3_MASK_CBM_DATA(info->cos), info->cbm_data);
+ }
+ else
+ wrmsrl(MSR_IA32_PSR_L3_MASK(info->cos), info->cbm_code);
}
-static int write_l3_cbm(unsigned int socket, unsigned int cos, uint64_t cbm)
+static int write_l3_cbm(unsigned int socket, unsigned int cos,
+ uint64_t cbm_code, uint64_t cbm_data, bool_t cdp)
{
- struct cos_cbm_info info = { .cos = cos, .cbm = cbm };
+ struct cos_cbm_info info =
+ {
+ .cos = cos,
+ .cbm_code = cbm_code,
+ .cbm_data = cbm_data,
+ .cdp = cdp,
+ };
if ( socket == cpu_to_socket(smp_processor_id()) )
do_write_l3_cbm(&info);
@@ -363,7 +393,7 @@ int psr_set_l3_cbm(struct domain *d, unsigned int socket, uint64_t cbm)
/* If still not found, then keep unused one. */
if ( !found && cos != 0 && map[cos].ref == 0 )
found = map + cos;
- else if ( map[cos].cbm == cbm )
+ else if ( map[cos].u.cbm == cbm )
{
if ( unlikely(cos == old_cos) )
{
@@ -387,16 +417,16 @@ int psr_set_l3_cbm(struct domain *d, unsigned int socket, uint64_t cbm)
}
cos = found - map;
- if ( found->cbm != cbm )
+ if ( found->u.cbm != cbm )
{
- int ret = write_l3_cbm(socket, cos, cbm);
+ int ret = write_l3_cbm(socket, cos, cbm, 0, 0);
if ( ret )
{
spin_unlock(&info->cbm_lock);
return ret;
}
- found->cbm = cbm;
+ found->u.cbm = cbm;
}
found->ref++;
@@ -470,6 +500,7 @@ static void cat_cpu_init(void)
struct psr_cat_socket_info *info;
unsigned int socket;
unsigned int cpu = smp_processor_id();
+ uint64_t val;
const struct cpuinfo_x86 *c = cpu_data + cpu;
if ( !cpu_has(c, X86_FEATURE_CAT) || c->cpuid_level < PSR_CPUID_LEVEL_CAT )
@@ -490,13 +521,34 @@ static void cat_cpu_init(void)
info->cos_to_cbm = temp_cos_to_cbm;
temp_cos_to_cbm = NULL;
/* cos=0 is reserved as default cbm(all ones). */
- info->cos_to_cbm[0].cbm = (1ull << info->cbm_len) - 1;
+ info->cos_to_cbm[0].u.cbm = (1ull << info->cbm_len) - 1;
spin_lock_init(&info->cbm_lock);
set_bit(socket, cat_socket_enable);
printk(XENLOG_INFO "CAT: enabled on socket %u, cos_max:%u, cbm_len:%u\n",
socket, info->cos_max, info->cbm_len);
+
+ if ( (ecx & PSR_CAT_CDP_CAPABILITY) && (opt_psr & PSR_CDP) )
+ {
+ if ( test_bit(socket, cdp_socket_enable) )
+ return;
+
+ rdmsrl(MSR_IA32_PSR_L3_QOS_CFG, val);
+ wrmsrl(MSR_IA32_PSR_L3_QOS_CFG, val | 1 << PSR_L3_QOS_CDP_ENABLE_BIT);
+
+ /* No need to write register since CBMs are fully open as default by HW */
+ info->cos_to_cbm[0].u.cdp.code = (1ull << info->cbm_len) - 1;
+ info->cos_to_cbm[0].u.cdp.data = (1ull << info->cbm_len) - 1;
+
+ /* Cut half of cos_max when CDP enabled */
+ info->cos_max = info->cos_max / 2;
+
+ info->cdp_enabled = 1;
+ set_bit(socket, cdp_socket_enable);
+ printk(XENLOG_INFO "CDP: enabled on socket %u, cos_max:%u, cbm_len:%u\n",
+ socket, info->cos_max, info->cbm_len);
+ }
}
}
@@ -508,6 +560,9 @@ static void cat_cpu_fini(unsigned int cpu)
{
struct psr_cat_socket_info *info = cat_socket_info + socket;
+ info->cdp_enabled = 0;
+ clear_bit(socket, cdp_socket_enable);
+
if ( info->cos_to_cbm )
{
xfree(info->cos_to_cbm);
@@ -523,6 +578,8 @@ static void __init psr_cat_free(void)
cat_socket_enable = NULL;
xfree(cat_socket_info);
cat_socket_info = NULL;
+ xfree(cdp_socket_enable);
+ cdp_socket_enable = NULL;
}
static void __init init_psr_cat(void)
@@ -535,8 +592,9 @@ static void __init init_psr_cat(void)
cat_socket_enable = xzalloc_array(unsigned long, BITS_TO_LONGS(nr_sockets));
cat_socket_info = xzalloc_array(struct psr_cat_socket_info, nr_sockets);
+ cdp_socket_enable = xzalloc_array(unsigned long, BITS_TO_LONGS(nr_sockets));
- if ( !cat_socket_enable || !cat_socket_info )
+ if ( !cat_socket_enable || !cat_socket_info || !cdp_socket_enable )
psr_cat_free();
}
diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c
index f36b52f..e42c5e7 100644
--- a/xen/arch/x86/sysctl.c
+++ b/xen/arch/x86/sysctl.c
@@ -177,12 +177,13 @@ long arch_do_sysctl(
case XEN_SYSCTL_PSR_CAT_get_l3_info:
ret = psr_get_cat_l3_info(sysctl->u.psr_cat_op.target,
&sysctl->u.psr_cat_op.u.l3_info.cbm_len,
- &sysctl->u.psr_cat_op.u.l3_info.cos_max);
+ &sysctl->u.psr_cat_op.u.l3_info.cos_max,
+ &sysctl->u.psr_cat_op.u.l3_info.flags);
if ( !ret && __copy_field_to_guest(u_sysctl, sysctl, u.psr_cat_op) )
ret = -EFAULT;
-
break;
+
default:
ret = -EOPNOTSUPP;
break;
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index e9c4723..402e7a7 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -328,7 +328,10 @@
#define MSR_IA32_CMT_EVTSEL 0x00000c8d
#define MSR_IA32_CMT_CTR 0x00000c8e
#define MSR_IA32_PSR_ASSOC 0x00000c8f
+#define MSR_IA32_PSR_L3_QOS_CFG 0x00000c81
#define MSR_IA32_PSR_L3_MASK(n) (0x00000c90 + (n))
+#define MSR_IA32_PSR_L3_MASK_CBM_CODE(n) (0x00000c90 + (n * 2 + 1))
+#define MSR_IA32_PSR_L3_MASK_CBM_DATA(n) (0x00000c90 + (n * 2))
/* Intel Model 6 */
#define MSR_P6_PERFCTR(n) (0x000000c1 + (n))
diff --git a/xen/include/asm-x86/psr.h b/xen/include/asm-x86/psr.h
index 081750f..422b053 100644
--- a/xen/include/asm-x86/psr.h
+++ b/xen/include/asm-x86/psr.h
@@ -27,6 +27,15 @@
/* L3 Monitoring Features */
#define PSR_CMT_L3_OCCUPANCY 0x1
+/* CDP Capability */
+#define PSR_CAT_CDP_CAPABILITY (1u << 2)
+
+/* L3 CDP Enable bit*/
+#define PSR_L3_QOS_CDP_ENABLE_BIT 0x0
+
+/* L3 CDP flag bit */
+#define PSR_CAT_FLAG_L3_CDP (1u << 0)
+
struct psr_cmt_l3 {
unsigned int features;
unsigned int upscaling_factor;
@@ -52,7 +61,7 @@ void psr_free_rmid(struct domain *d);
void psr_ctxt_switch_to(struct domain *d);
int psr_get_cat_l3_info(unsigned int socket, uint32_t *cbm_len,
- uint32_t *cos_max);
+ uint32_t *cos_max, uint32_t *flags);
int psr_get_l3_cbm(struct domain *d, unsigned int socket, uint64_t *cbm);
int psr_set_l3_cbm(struct domain *d, unsigned int socket, uint64_t cbm);
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 58c9be2..4102cd2 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -704,6 +704,8 @@ struct xen_sysctl_psr_cat_op {
struct {
uint32_t cbm_len; /* OUT: CBM length */
uint32_t cos_max; /* OUT: Maximum COS */
+ #define XEN_SYSCTL_PSR_CAT_L3_CDP (1u << 0)
+ uint32_t flags; /* OUT: CAT flags */
} l3_info;
} u;
};
--
1.9.1
next prev parent reply other threads:[~2015-09-09 5:16 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-09 5:16 [PATCH v2 0/4] Intel Code/Data Prioritization(CDP) feature enabling He Chen
2015-09-09 5:16 ` He Chen [this message]
2015-09-09 7:04 ` [PATCH v2 1/4] x86: Support enable CDP by boot parameter and add get CDP status Chao Peng
2015-09-09 7:44 ` He Chen
2015-09-09 5:16 ` [PATCH v2 2/4] x86: add domctl cmd to set/get CDP code/data CBM He Chen
2015-09-09 7:24 ` Chao Peng
2015-09-09 7:35 ` Jan Beulich
2015-09-09 5:16 ` [PATCH v2 3/4] tools: add tools support for Intel CDP He Chen
2015-09-09 7:32 ` Chao Peng
2015-09-09 8:10 ` He Chen
2015-09-09 8:37 ` Jan Beulich
2015-09-09 9:17 ` Chao Peng
2015-09-09 5:16 ` [PATCH v2 4/4] docs: add document to introduce CDP command He Chen
2015-09-09 7:37 ` [PATCH v2 0/4] Intel Code/Data Prioritization(CDP) feature enabling Chao Peng
2015-09-09 12:36 ` Ian Campbell
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=1441775808-29766-2-git-send-email-he.chen@linux.intel.com \
--to=he.chen@linux.intel.com \
--cc=andrew.cooper3@citrix.com \
--cc=chao.p.peng@linux.intel.com \
--cc=ian.campbell@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=keir@xen.org \
--cc=stefano.stabellini@eu.citrix.com \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.