# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1196766417 0
# Node ID 8912f55d52c132c80016991cd8fd3b77cdd14672
# Parent 9bb76e0b347ef7f437e752c08f16f32f29386f7e
# Parent 922fc40402646a08e513a4dac04242d112e5bff2
Merge with ia64.
---
include/asm-i386/mach-xen/asm/param.h | 23 ----------
arch/i386/kernel/cpu/cpufreq/powernow-k8.h | 26 ++++--------
drivers/xen/core/evtchn.c | 61 +++++++++++++++++++++++------
drivers/xen/evtchn/evtchn.c | 54 ++++++++++++++++++++++---
4 files changed, 105 insertions(+), 59 deletions(-)
diff -r 9bb76e0b347e -r 8912f55d52c1 arch/i386/kernel/cpu/cpufreq/powernow-k8.h
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h Thu Nov 29 12:20:05
2007 -0700
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h Tue Dec 04 11:06:57
2007 +0000
@@ -1,5 +1,5 @@
/*
- * (c) 2003-2006 Advanced Micro Devices, Inc.
+#* (c) 2003-2006 Advanced Micro Devices, Inc.
* Your use of this code is subject to the terms and conditions of the
* GNU general public license version 2. See "COPYING" or
* http://www.gnu.org/licenses/gpl.html
@@ -10,6 +10,7 @@ struct powernow_k8_data {
u32 numps; /* number of p-states */
u32 batps; /* number of p-states supported on battery */
+ u32 max_hw_pstate; /* maximum legal hardware pstate */
/* these values are constant when the PSB is used to determine
* vid/fid pairings, but are modified during the ->target() call
@@ -21,8 +22,8 @@ struct powernow_k8_data {
u32 plllock; /* pll lock time, units 1 us */
u32 exttype; /* extended interface = 1 */
- /* keep track of the current fid / vid or did */
- u32 currvid, currfid, currdid;
+ /* keep track of the current fid / vid or pstate */
+ u32 currvid, currfid, currpstate;
/* the powernow_table includes all frequency and vid/fid pairings:
* fid are the lower 8 bits of the index, vid are the upper 8 bits.
@@ -88,23 +89,14 @@ struct powernow_k8_data {
/* Hardware Pstate _PSS and MSR definitions */
#define USE_HW_PSTATE 0x00000080
-#define HW_PSTATE_FID_MASK 0x0000003f
-#define HW_PSTATE_DID_MASK 0x000001c0
-#define HW_PSTATE_DID_SHIFT 6
-#define HW_PSTATE_MASK 0x00000007
-#define HW_PSTATE_VALID_MASK 0x80000000
-#define HW_FID_INDEX_SHIFT 8
-#define HW_FID_INDEX_MASK 0x0000ff00
-#define HW_DID_INDEX_SHIFT 16
-#define HW_DID_INDEX_MASK 0x00ff0000
-#define HW_WATTS_MASK 0xff
-#define HW_PWR_DVR_MASK 0x300
-#define HW_PWR_DVR_SHIFT 8
-#define HW_PWR_MAX_MULT 3
-#define MAX_HW_PSTATE 8 /* hw pstate supports up to 8 */
+#define HW_PSTATE_MASK 0x00000007
+#define HW_PSTATE_VALID_MASK 0x80000000
+#define HW_PSTATE_MAX_MASK 0x000000f0
+#define HW_PSTATE_MAX_SHIFT 4
#define MSR_PSTATE_DEF_BASE 0xc0010064 /* base of Pstate MSRs */
#define MSR_PSTATE_STATUS 0xc0010063 /* Pstate Status MSR */
#define MSR_PSTATE_CTRL 0xc0010062 /* Pstate control MSR */
+#define MSR_PSTATE_CUR_LIMIT 0xc0010061 /* pstate current limit MSR */
/* define the two driver architectures */
#define CPU_OPTERON 0
diff -r 9bb76e0b347e -r 8912f55d52c1 drivers/xen/core/evtchn.c
--- a/drivers/xen/core/evtchn.c Thu Nov 29 12:20:05 2007 -0700
+++ b/drivers/xen/core/evtchn.c Tue Dec 04 11:06:57 2007 +0000
@@ -221,15 +221,19 @@ EXPORT_SYMBOL(force_evtchn_callback);
EXPORT_SYMBOL(force_evtchn_callback);
static DEFINE_PER_CPU(unsigned int, upcall_count) = { 0 };
+static DEFINE_PER_CPU(unsigned int, last_processed_l1i) = { BITS_PER_LONG - 1
};
+static DEFINE_PER_CPU(unsigned int, last_processed_l2i) = { BITS_PER_LONG - 1
};
/* NB. Interrupts are disabled on entry. */
asmlinkage void evtchn_do_upcall(struct pt_regs *regs)
{
- unsigned long l1, l2;
- unsigned int l1i, l2i, port, count;
- int irq, cpu = smp_processor_id();
- shared_info_t *s = HYPERVISOR_shared_info;
- vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
+ unsigned long l1, l2;
+ unsigned long masked_l1, masked_l2;
+ unsigned int l1i, l2i, port, count;
+ int irq, cpu = smp_processor_id();
+ shared_info_t *s = HYPERVISOR_shared_info;
+ vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
+
do {
/* Avoid a callback storm when we reenable delivery. */
@@ -244,13 +248,36 @@ asmlinkage void evtchn_do_upcall(struct
rmb();
#endif
l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
+
+ l1i = per_cpu(last_processed_l1i, cpu);
+ l2i = per_cpu(last_processed_l2i, cpu);
+
while (l1 != 0) {
- l1i = __ffs(l1);
- l1 &= ~(1UL << l1i);
-
- while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
- l2i = __ffs(l2);
-
+
+ l1i = (l1i + 1) % BITS_PER_LONG;
+ masked_l1 = l1 & ((~0UL) << l1i);
+
+ if (masked_l1 == 0) { /* if we masked out all events,
wrap around to the beginning */
+ l1i = BITS_PER_LONG - 1;
+ l2i = BITS_PER_LONG - 1;
+ continue;
+ }
+ l1i = __ffs(masked_l1);
+
+ do {
+ l2 = active_evtchns(cpu, s, l1i);
+
+ l2i = (l2i + 1) % BITS_PER_LONG;
+ masked_l2 = l2 & ((~0UL) << l2i);
+
+ if (masked_l2 == 0) { /* if we masked out all
events, move on */
+ l2i = BITS_PER_LONG - 1;
+ break;
+ }
+
+ l2i = __ffs(masked_l2);
+
+ /* process port */
port = (l1i * BITS_PER_LONG) + l2i;
if ((irq = evtchn_to_irq[port]) != -1)
do_IRQ(irq, regs);
@@ -258,7 +285,17 @@ asmlinkage void evtchn_do_upcall(struct
exit_idle();
evtchn_device_upcall(port);
}
- }
+
+ /* if this is the final port processed, we'll
pick up here+1 next time */
+ per_cpu(last_processed_l1i, cpu) = l1i;
+ per_cpu(last_processed_l2i, cpu) = l2i;
+
+ } while (l2i != BITS_PER_LONG - 1);
+
+ l2 = active_evtchns(cpu, s, l1i);
+ if (l2 == 0) /* we handled all ports, so we can clear
the selector bit */
+ l1 &= ~(1UL << l1i);
+
}
/* If there were nested callbacks then we have more to do. */
diff -r 9bb76e0b347e -r 8912f55d52c1 drivers/xen/evtchn/evtchn.c
--- a/drivers/xen/evtchn/evtchn.c Thu Nov 29 12:20:05 2007 -0700
+++ b/drivers/xen/evtchn/evtchn.c Tue Dec 04 11:06:57 2007 +0000
@@ -48,6 +48,7 @@
#include <linux/init.h>
#include <linux/gfp.h>
#include <linux/mutex.h>
+#include <linux/cpu.h>
#include <xen/evtchn.h>
#include <xen/public/evtchn.h>
@@ -231,6 +232,15 @@ static ssize_t evtchn_write(struct file
return rc;
}
+static unsigned int next_bind_cpu(cpumask_t map)
+{
+ static unsigned int bind_cpu;
+ bind_cpu = next_cpu(bind_cpu, map);
+ if (bind_cpu >= NR_CPUS)
+ bind_cpu = first_cpu(map);
+ return bind_cpu;
+}
+
static void evtchn_bind_to_user(struct per_user_data *u, int port)
{
spin_lock_irq(&port_user_lock);
@@ -238,13 +248,8 @@ static void evtchn_bind_to_user(struct p
BUG_ON(port_user[port] != NULL);
port_user[port] = u;
- if (u->bind_cpu == -1) {
- static unsigned int bind_cpu;
- bind_cpu = next_cpu(bind_cpu, cpu_online_map);
- if (bind_cpu >= NR_CPUS)
- bind_cpu = first_cpu(cpu_online_map);
- u->bind_cpu = bind_cpu;
- }
+ if (u->bind_cpu == -1)
+ u->bind_cpu = next_bind_cpu(cpu_online_map);
rebind_evtchn_to_cpu(port, u->bind_cpu);
@@ -483,6 +488,38 @@ static struct miscdevice evtchn_miscdev
.fops = &evtchn_fops,
};
+static int __cpuinit evtchn_cpu_notify(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ int hotcpu = (unsigned long)hcpu;
+ cpumask_t map = cpu_online_map;
+ int port, newcpu;
+ struct per_user_data *u;
+
+ switch (action) {
+ case CPU_DOWN_PREPARE:
+ cpu_clear(hotcpu, map);
+ spin_lock_irq(&port_user_lock);
+ for (port = 0; port < NR_EVENT_CHANNELS; port++) {
+ if ((u = port_user[port]) != NULL &&
+ u->bind_cpu == hotcpu &&
+ (newcpu = next_bind_cpu(map)) < NR_CPUS) {
+ rebind_evtchn_to_cpu(port, newcpu);
+ u->bind_cpu = newcpu;
+ }
+ }
+ spin_unlock_irq(&port_user_lock);
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata evtchn_cpu_nfb = {
+ .notifier_call = evtchn_cpu_notify
+};
+
static int __init evtchn_init(void)
{
int err;
@@ -500,6 +537,8 @@ static int __init evtchn_init(void)
return err;
}
+ register_cpu_notifier(&evtchn_cpu_nfb);
+
printk("Event-channel device installed.\n");
return 0;
@@ -508,6 +547,7 @@ static void evtchn_cleanup(void)
static void evtchn_cleanup(void)
{
misc_deregister(&evtchn_miscdev);
+ unregister_cpu_notifier(&evtchn_cpu_nfb);
}
module_init(evtchn_init);
diff -r 9bb76e0b347e -r 8912f55d52c1 include/asm-i386/mach-xen/asm/param.h
--- a/include/asm-i386/mach-xen/asm/param.h Thu Nov 29 12:20:05 2007 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#ifndef _ASMi386_PARAM_H
-#define _ASMi386_PARAM_H
-
-#ifdef __KERNEL__
-# define HZ CONFIG_HZ /* Internal kernel timer frequency */
-# define USER_HZ 100 /* .. some user interfaces are in
"ticks" */
-# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-#define COMMAND_LINE_SIZE 256
-
-#endif
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|