WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] Notify xen about Cx acpi info, such a

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] Notify xen about Cx acpi info, such as table returned by _CST/_CSD methods.
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 01 May 2008 03:00:32 -0700
Delivery-date: Thu, 01 May 2008 07:48:13 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1209635587 -3600
# Node ID e97855b90cc280e75c583cc6ac78d924f8cf16b8
# Parent  3c564f80f2ef2b458f9a81598c0928acb72cc891
Notify xen about Cx acpi info, such as table returned by _CST/_CSD methods.

Add notifiers for P/T & hotplug as placeholders.
Add option "xen_processor_pmbits" for enable/disable control.

Signed-off-by: Tian Kevin <kevin.tian@xxxxxxxxx>
Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx>
---
 arch/i386/kernel/acpi/Makefile                |    1 
 arch/i386/kernel/acpi/processor_extcntl_xen.c |  142 ++++++++++++++++++++++++++
 arch/x86_64/kernel/acpi/Makefile              |    2 
 drivers/acpi/Kconfig                          |    1 
 drivers/acpi/processor_extcntl.c              |   26 ++++
 drivers/acpi/processor_idle.c                 |   22 +++-
 include/acpi/processor.h                      |   17 +++
 include/xen/interface/platform.h              |   73 +++++++++++++
 8 files changed, 279 insertions(+), 5 deletions(-)

diff -r 3c564f80f2ef -r e97855b90cc2 arch/i386/kernel/acpi/Makefile
--- a/arch/i386/kernel/acpi/Makefile    Thu May 01 10:52:31 2008 +0100
+++ b/arch/i386/kernel/acpi/Makefile    Thu May 01 10:53:07 2008 +0100
@@ -1,6 +1,7 @@ obj-$(CONFIG_ACPI)              += boot.o
 obj-$(CONFIG_ACPI)             += boot.o
 obj-$(CONFIG_X86_IO_APIC)      += earlyquirk.o
 obj-$(CONFIG_ACPI_SLEEP)       += sleep.o wakeup.o
+obj-$(CONFIG_XEN)              += processor_extcntl_xen.o
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
 obj-y                          += cstate.o processor.o
diff -r 3c564f80f2ef -r e97855b90cc2 
arch/i386/kernel/acpi/processor_extcntl_xen.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/i386/kernel/acpi/processor_extcntl_xen.c     Thu May 01 10:53:07 
2008 +0100
@@ -0,0 +1,142 @@
+/*
+ * processor_extcntl_xen.c - interface to notify Xen
+ *
+ *  Copyright (C) 2008, Intel corporation
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/acpi.h>
+#include <linux/pm.h>
+#include <linux/cpu.h>
+
+#include <acpi/processor.h>
+#include <asm/hypercall.h>
+
+static int xen_processor_pmbits;
+static int __init set_xen_processor_pmbits(char *str)
+{
+       get_option(&str, &xen_processor_pmbits);
+
+       return 1;
+}
+__setup("xen_processor_pmbits=", set_xen_processor_pmbits);
+EXPORT_SYMBOL(xen_processor_pmbits);
+
+static int xen_cx_notifier(struct acpi_processor *pr, int action)
+{
+       int ret, count = 0, i;
+       xen_platform_op_t op = {
+               .cmd                    = XENPF_set_processor_pminfo,
+               .interface_version      = XENPF_INTERFACE_VERSION,
+               .u.set_pminfo.id        = pr->acpi_id,
+               .u.set_pminfo.type      = XEN_PM_CX,
+       };
+       struct xen_processor_cx *data, *buf;
+       struct acpi_processor_cx *cx;
+
+       if (action == PROCESSOR_PM_CHANGE)
+               return -EINVAL;
+
+       /* Convert to Xen defined structure and hypercall */
+       buf = kzalloc(pr->power.count * sizeof(struct xen_processor_cx),
+                       GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       data = buf;
+       for (i = 1; i <= pr->power.count; i++) {
+               cx = &pr->power.states[i];
+               /* Skip invalid cstate entry */
+               if (!cx->valid)
+                       continue;
+
+               data->type = cx->type;
+               data->latency = cx->latency;
+               data->power = cx->power;
+               data->reg.space_id = cx->reg.space_id;
+               data->reg.bit_width = cx->reg.bit_width;
+               data->reg.bit_offset = cx->reg.bit_offset;
+               data->reg.access_size = cx->reg.reserved;
+               data->reg.address = cx->reg.address;
+
+               /* Get dependency relationships */
+               if (cx->csd_count) {
+                       printk("Wow! _CSD is found. Not support for now!\n");
+                       kfree(buf);
+                       return -EINVAL;
+               } else {
+                       data->dpcnt = 0;
+                       set_xen_guest_handle(data->dp, NULL);
+               }
+
+               data++;
+               count++;
+       }
+
+       if (!count) {
+               printk("No available Cx info for cpu %d\n", pr->acpi_id);
+               kfree(buf);
+               return -EINVAL;
+       }
+
+       op.u.set_pminfo.power.count = count;
+       op.u.set_pminfo.power.flags.bm_control = pr->flags.bm_control;
+       op.u.set_pminfo.power.flags.bm_check = pr->flags.bm_check;
+       op.u.set_pminfo.power.flags.has_cst = pr->flags.has_cst;
+       op.u.set_pminfo.power.flags.power_setup_done = 
pr->flags.power_setup_done;
+
+       set_xen_guest_handle(op.u.set_pminfo.power.states, buf);
+       ret = HYPERVISOR_platform_op(&op);
+       kfree(buf);
+       return ret;
+}
+
+static int xen_px_notifier(struct acpi_processor *pr, int action)
+{
+       return -EINVAL;
+}
+
+static int xen_tx_notifier(struct acpi_processor *pr, int action)
+{
+       return -EINVAL;
+}
+static int xen_hotplug_notifier(struct acpi_processor *pr, int event)
+{
+       return -EINVAL;
+}
+
+static struct processor_extcntl_ops xen_extcntl_ops = {
+       .hotplug                = xen_hotplug_notifier,
+};
+
+static int __cpuinit xen_init_processor_extcntl(void)
+{
+       if (xen_processor_pmbits & XEN_PROCESSOR_PM_CX)
+               xen_extcntl_ops.pm_ops[PM_TYPE_IDLE] = xen_cx_notifier;
+       if (xen_processor_pmbits & XEN_PROCESSOR_PM_PX)
+               xen_extcntl_ops.pm_ops[PM_TYPE_PERF] = xen_px_notifier;
+       if (xen_processor_pmbits & XEN_PROCESSOR_PM_TX)
+               xen_extcntl_ops.pm_ops[PM_TYPE_THR] = xen_tx_notifier;
+
+       return processor_register_extcntl(&xen_extcntl_ops);
+}
+core_initcall(xen_init_processor_extcntl);
diff -r 3c564f80f2ef -r e97855b90cc2 arch/x86_64/kernel/acpi/Makefile
--- a/arch/x86_64/kernel/acpi/Makefile  Thu May 01 10:52:31 2008 +0100
+++ b/arch/x86_64/kernel/acpi/Makefile  Thu May 01 10:53:07 2008 +0100
@@ -8,4 +8,6 @@ processor-$(CONFIG_XEN) := ../../../i386
 processor-$(CONFIG_XEN)        := ../../../i386/kernel/acpi/processor.o
 endif
 
+obj-$(CONFIG_XEN)      += processor_extcnt_xen.o
+processor_extcnt_xen-$(CONFIG_XEN) := 
../../../i386/kernel/acpi/processor_extcntl_xen.o
 disabled-obj-$(CONFIG_XEN) := wakeup.o
diff -r 3c564f80f2ef -r e97855b90cc2 drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig      Thu May 01 10:52:31 2008 +0100
+++ b/drivers/acpi/Kconfig      Thu May 01 10:53:07 2008 +0100
@@ -371,6 +371,7 @@ config PROCESSOR_EXTERNAL_CONTROL
 config PROCESSOR_EXTERNAL_CONTROL
        bool
        depends on X86 && XEN
+       select ACPI_PROCESSOR
        default y
 endif  # ACPI
 
diff -r 3c564f80f2ef -r e97855b90cc2 drivers/acpi/processor_extcntl.c
--- a/drivers/acpi/processor_extcntl.c  Thu May 01 10:52:31 2008 +0100
+++ b/drivers/acpi/processor_extcntl.c  Thu May 01 10:53:07 2008 +0100
@@ -30,6 +30,7 @@
 
 #include <acpi/processor.h>
 
+static int processor_extcntl_parse_csd(struct acpi_processor *pr);
 /*
  * External processor control logic may register with its own set of
  * ops to get ACPI related notification. One example is like VMM.
@@ -107,5 +108,30 @@ int processor_unregister_extcntl(struct 
  */
 int processor_extcntl_init(struct acpi_processor *pr)
 {
+       /* parse cstate dependency information */
+       processor_extcntl_parse_csd(pr);
+
        return 0;
 }
+
+/*
+ * Currently no _CSD is implemented which is why existing ACPI code
+ * doesn't parse _CSD at all. But to keep interface complete with
+ * external control logic, we put a placeholder here for future
+ * compatibility.
+ */
+static int processor_extcntl_parse_csd(struct acpi_processor *pr)
+{
+       int i;
+
+       for (i = 0; i < pr->power.count; i++) {
+               if (!pr->power.states[i].valid)
+                       continue;
+
+               /* No dependency by default */
+               pr->power.states[i].domain_info = NULL;
+               pr->power.states[i].csd_count = 0;
+       }
+
+       return 0;
+}
diff -r 3c564f80f2ef -r e97855b90cc2 drivers/acpi/processor_idle.c
--- a/drivers/acpi/processor_idle.c     Thu May 01 10:52:31 2008 +0100
+++ b/drivers/acpi/processor_idle.c     Thu May 01 10:53:07 2008 +0100
@@ -714,8 +714,12 @@ static int acpi_processor_get_power_info
                    (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
                        continue;
 
-               cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ?
-                   0 : reg->address;
+               if (!processor_pm_external())
+                       cx.address = (reg->space_id ==
+                                     ACPI_ADR_SPACE_FIXED_HARDWARE) ?
+                                     0 : reg->address;
+               else
+                       cx.address = reg->address;
 
                /* There should be an easy way to extract an integer... */
                obj = (union acpi_object *)&(element->package.elements[1]);
@@ -724,9 +728,11 @@ static int acpi_processor_get_power_info
 
                cx.type = obj->integer.value;
 
-               if ((cx.type != ACPI_STATE_C1) &&
-                   (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
-                       continue;
+               /* Following check doesn't apply to external control case */
+               if (!processor_pm_external())
+                       if ((cx.type != ACPI_STATE_C1) &&
+                           (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
+                               continue;
 
                if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3))
                        continue;
@@ -742,6 +748,12 @@ static int acpi_processor_get_power_info
                        continue;
 
                cx.power = obj->integer.value;
+
+#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
+               /* cache control methods to notify external logic */
+               if (processor_pm_external())
+                       memcpy(&cx.reg, reg, sizeof(*reg));
+#endif
 
                current_count++;
                memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx));
diff -r 3c564f80f2ef -r e97855b90cc2 include/acpi/processor.h
--- a/include/acpi/processor.h  Thu May 01 10:52:31 2008 +0100
+++ b/include/acpi/processor.h  Thu May 01 10:53:07 2008 +0100
@@ -32,6 +32,17 @@
 /* Power Management */
 
 struct acpi_processor_cx;
+
+#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
+struct acpi_csd_package {
+       acpi_integer num_entries;
+       acpi_integer revision;
+       acpi_integer domain;
+       acpi_integer coord_type;
+       acpi_integer num_processors;
+       acpi_integer index;
+} __attribute__ ((packed));
+#endif
 
 struct acpi_power_register {
        u8 descriptor;
@@ -63,6 +74,12 @@ struct acpi_processor_cx {
        u32 power;
        u32 usage;
        u64 time;
+#ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
+       /* Require raw information for external control logic */
+       struct acpi_power_register reg;
+       u32 csd_count;
+       struct acpi_csd_package *domain_info;
+#endif
        struct acpi_processor_cx_policy promotion;
        struct acpi_processor_cx_policy demotion;
 };
diff -r 3c564f80f2ef -r e97855b90cc2 include/xen/interface/platform.h
--- a/include/xen/interface/platform.h  Thu May 01 10:52:31 2008 +0100
+++ b/include/xen/interface/platform.h  Thu May 01 10:53:07 2008 +0100
@@ -199,6 +199,78 @@ typedef struct xenpf_getidletime xenpf_g
 typedef struct xenpf_getidletime xenpf_getidletime_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t);
 
+#define XENPF_set_processor_pminfo      54
+
+/* ability bits */
+#define XEN_PROCESSOR_PM_CX    1
+#define XEN_PROCESSOR_PM_PX    2
+#define XEN_PROCESSOR_PM_TX    4
+
+/* cmd type */
+#define XEN_PM_CX   0
+#define XEN_PM_PX   1
+#define XEN_PM_TX   2
+
+struct xen_power_register {
+    uint32_t     space_id;
+    uint32_t     bit_width;
+    uint32_t     bit_offset;
+    uint32_t     access_size;
+    uint64_t     address;
+};
+
+struct xen_processor_csd {
+    uint32_t    domain;      /* domain number of one dependent group */
+    uint32_t    coord_type;  /* coordination type */
+    uint32_t    num;         /* number of processors in same domain */
+};
+typedef struct xen_processor_csd xen_processor_csd_t;
+DEFINE_XEN_GUEST_HANDLE(xen_processor_csd_t);
+
+struct xen_processor_cx {
+    struct xen_power_register  reg; /* GAS for Cx trigger register */
+    uint8_t     type;     /* cstate value, c0: 0, c1: 1, ... */
+    uint32_t    latency;  /* worst latency (ms) to enter/exit this cstate */
+    uint32_t    power;    /* average power consumption(mW) */
+    uint32_t    dpcnt;    /* number of dependency entries */
+    XEN_GUEST_HANDLE(xen_processor_csd_t) dp; /* NULL if no dependency */
+};
+typedef struct xen_processor_cx xen_processor_cx_t;
+DEFINE_XEN_GUEST_HANDLE(xen_processor_cx_t);
+
+struct xen_processor_flags {
+    uint8_t bm_control:1;
+    uint8_t bm_check:1;
+    uint8_t has_cst:1;
+    uint8_t power_setup_done:1;
+    uint8_t bm_rld_set:1;
+};
+
+struct xen_processor_power {
+    uint32_t count;  /* number of C state entries in array below */
+    struct xen_processor_flags flags;  /* global flags of this processor */
+    XEN_GUEST_HANDLE(xen_processor_cx_t) states; /* supported c states */
+};
+
+struct xen_processor_performance {
+};
+
+struct xen_processor_throttling {
+};
+
+struct xenpf_set_processor_pminfo {
+    /* IN variables */
+    uint32_t id;    /* ACPI CPU ID */
+    uint32_t type;  /* {XEN_PM_CX, XEN_PM_PX, XEN_PM_TX} */
+    union {
+        struct xen_processor_power          power;/* Cx: _CST/_CSD */
+        struct xen_processor_performance    perf; /* Px: _PPC/_PCT/_PSS/_PSD */
+        struct xen_processor_throttling     throt;/* Tx: _TPC/_PTC/_TSS/_TSD */
+    };
+};
+typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_set_processor_pminfo_t);
+
 struct xen_platform_op {
     uint32_t cmd;
     uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
@@ -213,6 +285,7 @@ struct xen_platform_op {
         struct xenpf_enter_acpi_sleep  enter_acpi_sleep;
         struct xenpf_change_freq       change_freq;
         struct xenpf_getidletime       getidletime;
+        struct xenpf_set_processor_pminfo set_pminfo;
         uint8_t                        pad[128];
     } u;
 };

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] Notify xen about Cx acpi info, such as table returned by _CST/_CSD methods., Xen patchbot-linux-2.6.18-xen <=