All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
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,
	ian.jackson@eu.citrix.com, jbeulich@suse.com,
	chao.p.peng@linux.intel.com, keir@xen.org
Subject: [PATCH v3 2/4] x86: add domctl cmd to set/get CDP code/data CBM
Date: Mon, 14 Sep 2015 11:27:05 +0800	[thread overview]
Message-ID: <1442201227-8610-3-git-send-email-he.chen@linux.intel.com> (raw)
In-Reply-To: <1442201227-8610-1-git-send-email-he.chen@linux.intel.com>

CDP extends CAT and provides the capacity to control L3 code & data
cache. With CDP, one COS correspond to two CMBs(code & data). cbm_type
is added to support distinguish different CBM operation. Besides, new
domctl cmds are introdunced to support set/get CDP CBM. Some CAT
functions to operation CBMs are extended to support CDP.

Signed-off-by: He Chen <he.chen@linux.intel.com>
---
 xen/arch/x86/domctl.c       |  32 ++++++++-
 xen/arch/x86/psr.c          | 166 ++++++++++++++++++++++++++++++++++----------
 xen/include/asm-x86/psr.h   |  12 +++-
 xen/include/public/domctl.h |   4 ++
 4 files changed, 174 insertions(+), 40 deletions(-)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index bf62a88..734fddb 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -1167,12 +1167,40 @@ long arch_do_domctl(
         {
         case XEN_DOMCTL_PSR_CAT_OP_SET_L3_CBM:
             ret = psr_set_l3_cbm(d, domctl->u.psr_cat_op.target,
-                                 domctl->u.psr_cat_op.data);
+                                 domctl->u.psr_cat_op.data,
+                                 PSR_CBM_TYPE_L3);
+            break;
+
+        case XEN_DOMCTL_PSR_CAT_OP_SET_L3_CODE:
+            ret = psr_set_l3_cbm(d, domctl->u.psr_cat_op.target,
+                                 domctl->u.psr_cat_op.data,
+                                 PSR_CBM_TYPE_L3_CODE);
+            break;
+
+        case XEN_DOMCTL_PSR_CAT_OP_SET_L3_DATA:
+            ret = psr_set_l3_cbm(d, domctl->u.psr_cat_op.target,
+                                 domctl->u.psr_cat_op.data,
+                                 PSR_CBM_TYPE_L3_DATA);
             break;
 
         case XEN_DOMCTL_PSR_CAT_OP_GET_L3_CBM:
             ret = psr_get_l3_cbm(d, domctl->u.psr_cat_op.target,
-                                 &domctl->u.psr_cat_op.data);
+                                 &domctl->u.psr_cat_op.data,
+                                 PSR_CBM_TYPE_L3);
+            copyback = 1;
+            break;
+
+        case XEN_DOMCTL_PSR_CAT_OP_GET_L3_CODE:
+            ret = psr_get_l3_cbm(d, domctl->u.psr_cat_op.target,
+                                 &domctl->u.psr_cat_op.data,
+                                 PSR_CBM_TYPE_L3_CODE);
+            copyback = 1;
+            break;
+
+        case XEN_DOMCTL_PSR_CAT_OP_GET_L3_DATA:
+            ret = psr_get_l3_cbm(d, domctl->u.psr_cat_op.target,
+                                 &domctl->u.psr_cat_op.data,
+                                 PSR_CBM_TYPE_L3_DATA);
             copyback = 1;
             break;
 
diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c
index cf70f90..c55493d 100644
--- a/xen/arch/x86/psr.c
+++ b/xen/arch/x86/psr.c
@@ -288,14 +288,39 @@ int psr_get_cat_l3_info(unsigned int socket, uint32_t *cbm_len,
     return 0;
 }
 
-int psr_get_l3_cbm(struct domain *d, unsigned int socket, uint64_t *cbm)
+int psr_get_l3_cbm(struct domain *d, unsigned int socket,
+                   uint64_t *cbm, enum cbm_type type)
 {
     struct psr_cat_socket_info *info = get_cat_socket_info(socket);
+    bool_t cdp_enabled = test_bit(socket, cdp_socket_enable);
 
     if ( IS_ERR(info) )
         return PTR_ERR(info);
 
-    *cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].u.cbm;
+    if ( type == PSR_CBM_TYPE_L3 && cdp_enabled )
+        return -EXDEV;
+
+    if ( (type == PSR_CBM_TYPE_L3_CODE || type == PSR_CBM_TYPE_L3_DATA)
+        && !cdp_enabled )
+        return -EXDEV;
+
+    switch ( type )
+    {
+        case PSR_CBM_TYPE_L3:
+            *cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].u.cbm;
+            break;
+
+        case PSR_CBM_TYPE_L3_CODE:
+            *cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].u.cdp.code;
+            break;
+
+        case PSR_CBM_TYPE_L3_DATA:
+            *cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].u.cdp.data;
+            break;
+
+        default:
+            return -EINVAL;
+    }
 
     return 0;
 }
@@ -369,10 +394,53 @@ static int write_l3_cbm(unsigned int socket, unsigned int cos,
     return 0;
 }
 
-int psr_set_l3_cbm(struct domain *d, unsigned int socket, uint64_t cbm)
+static int find_cos(struct psr_cat_cbm *map, int cos_max,
+                    uint64_t cbm_code, uint64_t cbm_data, bool_t cdp_enabled)
 {
-    unsigned int old_cos, cos;
-    struct psr_cat_cbm *map, *found = NULL;
+    unsigned int cos;
+
+    if ( !cdp_enabled )
+    {
+        for ( cos = 0; cos <= cos_max; cos++ )
+            if ( map[cos].ref && map[cos].u.cbm == cbm_code )
+                return cos;
+    }
+    else
+    {
+        for ( cos = 0; cos <= cos_max; cos++ )
+            if ( map[cos].ref && map[cos].u.cdp.code == cbm_code &&
+                 map[cos].u.cdp.data == cbm_data )
+                return cos;
+    }
+
+    return -ENOENT;
+}
+
+static int pick_avail_cos(struct psr_cat_cbm *map, int cos_max, int old_cos)
+{
+    int cos;
+
+    /* If old cos is referred only by the domain, then use it. */
+    if ( map[old_cos].ref == 1 )
+        return old_cos;
+
+    /* Find an unused one other than cos0 */
+    for ( cos = 1; cos <= cos_max; cos++ )
+        if ( map[cos].ref == 0 )
+            return cos;
+
+    return -ENOENT;
+}
+
+int psr_set_l3_cbm(struct domain *d, unsigned int socket,
+                   uint64_t cbm, enum cbm_type type)
+{
+    unsigned int old_cos, cos_max;
+    int cos, ret;
+    uint64_t cbm_data, cbm_code;
+    bool_t need_write = 1;
+    bool_t cdp_enabled = test_bit(socket, cdp_socket_enable);
+    struct psr_cat_cbm *map;
     struct psr_cat_socket_info *info = get_cat_socket_info(socket);
 
     if ( IS_ERR(info) )
@@ -381,53 +449,79 @@ int psr_set_l3_cbm(struct domain *d, unsigned int socket, uint64_t cbm)
     if ( !psr_check_cbm(info->cbm_len, cbm) )
         return -EINVAL;
 
+    if ( !cdp_enabled && (type == PSR_CBM_TYPE_L3_CODE ||
+        type == PSR_CBM_TYPE_L3_DATA) )
+        return -EINVAL;
+
+    cos_max = info->cos_max;
     old_cos = d->arch.psr_cos_ids[socket];
     map = info->cos_to_cbm;
 
-    spin_lock(&info->cbm_lock);
 
-    for ( cos = 0; cos <= info->cos_max; cos++ )
+    switch( type )
     {
-        /* If still not found, then keep unused one. */
-        if ( !found && cos != 0 && map[cos].ref == 0 )
-            found = map + cos;
-        else if ( map[cos].u.cbm == cbm )
-        {
-            if ( unlikely(cos == old_cos) )
-            {
-                ASSERT(cos == 0 || map[cos].ref != 0);
-                spin_unlock(&info->cbm_lock);
-                return 0;
-            }
-            found = map + cos;
+        case PSR_CBM_TYPE_L3:
+            cbm_code = cbm;
+            cbm_data = cbm;
             break;
-        }
-    }
 
-    /* If old cos is referred only by the domain, then use it. */
-    if ( !found && map[old_cos].ref == 1 )
-        found = map + old_cos;
+        case PSR_CBM_TYPE_L3_CODE:
+            cbm_code = cbm;
+            cbm_data = map[old_cos].u.cdp.data;
+            break;
 
-    if ( !found )
-    {
-        spin_unlock(&info->cbm_lock);
-        return -EOVERFLOW;
+        case PSR_CBM_TYPE_L3_DATA:
+            cbm_code = map[old_cos].u.cdp.code;
+            cbm_data = cbm;
+            break;
+
+        default:
+            return -EINVAL;
     }
 
-    cos = found - map;
-    if ( found->u.cbm != cbm )
+    spin_lock(&info->cbm_lock);
+    cos = find_cos(map, cos_max, cbm_code, cbm_data, cdp_enabled);
+    if ( cos >= 0 )
     {
-        int ret = write_l3_cbm(socket, cos, cbm, 0, 0);
-
-        if ( ret )
+        if ( unlikely(cos == old_cos) )
         {
             spin_unlock(&info->cbm_lock);
-            return ret;
+            return 0;
+        }
+    }
+    else
+    {
+        cos = pick_avail_cos(map, cos_max, old_cos);
+        if ( cos < 0 )
+        {
+            spin_unlock(&info->cbm_lock);
+            return cos;
+        }
+
+        /* We try to avoid writing MSR */
+        if ( cdp_enabled )
+        {
+            if ( map[cos].u.cdp.code == cbm_code &&
+                 map[cos].u.cdp.data == cbm_data )
+                need_write = 0;
+        }
+        else
+            need_write = map[cos].u.cbm == cbm_code ? 0 : 1;
+
+        if ( need_write )
+        {
+            ret = write_l3_cbm(socket, cos, cbm_code, cbm_data, cdp_enabled);
+            if ( ret )
+            {
+                spin_unlock(&info->cbm_lock);
+                return ret;
+            }
+            map[cos].u.cdp.code = cbm_code;
+            map[cos].u.cdp.data = cbm_data;
         }
-        found->u.cbm = cbm;
     }
 
-    found->ref++;
+    map[cos].ref++;
     map[old_cos].ref--;
     spin_unlock(&info->cbm_lock);
 
diff --git a/xen/include/asm-x86/psr.h b/xen/include/asm-x86/psr.h
index 422b053..c0b3f66 100644
--- a/xen/include/asm-x86/psr.h
+++ b/xen/include/asm-x86/psr.h
@@ -49,6 +49,12 @@ struct psr_cmt {
     struct psr_cmt_l3 l3;
 };
 
+enum cbm_type {
+    PSR_CBM_TYPE_L3         = 1,
+    PSR_CBM_TYPE_L3_CODE    = 2,
+    PSR_CBM_TYPE_L3_DATA    = 3,
+};
+
 extern struct psr_cmt *psr_cmt;
 
 static inline bool_t psr_cmt_enabled(void)
@@ -62,8 +68,10 @@ 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 *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);
+int psr_get_l3_cbm(struct domain *d, unsigned int socket,
+                   uint64_t *cbm, enum cbm_type type);
+int psr_set_l3_cbm(struct domain *d, unsigned int socket,
+                   uint64_t cbm, enum cbm_type type);
 
 int psr_domain_init(struct domain *d);
 void psr_domain_free(struct domain *d);
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 675f021..f438cae 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -1056,6 +1056,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_monitor_op_t);
 struct xen_domctl_psr_cat_op {
 #define XEN_DOMCTL_PSR_CAT_OP_SET_L3_CBM     0
 #define XEN_DOMCTL_PSR_CAT_OP_GET_L3_CBM     1
+#define XEN_DOMCTL_PSR_CAT_OP_SET_L3_CODE    2
+#define XEN_DOMCTL_PSR_CAT_OP_SET_L3_DATA    3
+#define XEN_DOMCTL_PSR_CAT_OP_GET_L3_CODE    4
+#define XEN_DOMCTL_PSR_CAT_OP_GET_L3_DATA    5
     uint32_t cmd;       /* IN: XEN_DOMCTL_PSR_CAT_OP_* */
     uint32_t target;    /* IN */
     uint64_t data;      /* IN/OUT */
-- 
1.9.1

  parent reply	other threads:[~2015-09-14  3:26 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-14  3:27 [PATCH v3 0/4] Intel Code and Data Prioritization (CDP) feature enabling He Chen
2015-09-14  3:27 ` [PATCH v3 1/4] x86: Support enable CDP by boot parameter and add get CDP status He Chen
2015-09-14  8:39   ` Chao Peng
2015-09-14 14:12   ` Jan Beulich
2015-09-14  3:27 ` He Chen [this message]
2015-09-14  9:04   ` [PATCH v3 2/4] x86: add domctl cmd to set/get CDP code/data CBM Chao Peng
2015-09-14 14:28   ` Jan Beulich
2015-09-14  3:27 ` [PATCH v3 3/4] tools: add tools support for Intel CDP He Chen
2015-09-14  9:11   ` Chao Peng
2015-09-14  3:27 ` [PATCH v3 4/4] docs: add document to introduce CDP command He Chen
2015-09-14  9:35   ` Chao Peng
2015-09-14  9:48 ` [PATCH v3 0/4] Intel Code and Data Prioritization (CDP) feature enabling Chao Peng

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=1442201227-8610-3-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.