[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] merge with linux-2.6.18-xen.hg (staging)
# HG changeset patch # User Alex Williamson <alex.williamson@xxxxxx> # Date 1189195055 21600 # Node ID 8aa8af371be0e9c46b22615ba7e8990ed738ea12 # Parent e1466633683cf0bdba9ef905d0a79702ba05a751 # Parent 2a214d4ef5b175708d01ac5ce15de7745c48b756 merge with linux-2.6.18-xen.hg (staging) --- drivers/acpi/hardware/hwsleep.c | 13 ++++++-- drivers/xen/core/evtchn.c | 19 ++++++------ drivers/xen/core/gnttab.c | 9 +++++- drivers/xen/core/reboot.c | 36 ++++++++++-------------- drivers/xen/evtchn/evtchn.c | 59 ++++++++++++++++++++++++++++++++++++++++ include/xen/evtchn.h | 12 ++++++++ include/xen/gnttab.h | 6 ---- include/xen/xenbus.h | 1 8 files changed, 114 insertions(+), 41 deletions(-) diff -r e1466633683c -r 8aa8af371be0 drivers/acpi/hardware/hwsleep.c --- a/drivers/acpi/hardware/hwsleep.c Thu Sep 06 14:33:25 2007 -0600 +++ b/drivers/acpi/hardware/hwsleep.c Fri Sep 07 13:57:35 2007 -0600 @@ -338,10 +338,6 @@ acpi_status asmlinkage acpi_enter_sleep_ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); -#else - status = acpi_notify_hypervisor_state(sleep_state, - PM1Acontrol, PM1Bcontrol); -#endif if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -383,6 +379,15 @@ acpi_status asmlinkage acpi_enter_sleep_ } while (!in_value); return_ACPI_STATUS(AE_OK); +#else + /* PV ACPI just need check hypercall return value */ + status = acpi_notify_hypervisor_state(sleep_state, + PM1Acontrol, PM1Bcontrol); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + else + return_ACPI_STATUS(AE_OK); +#endif } ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) diff -r e1466633683c -r 8aa8af371be0 drivers/xen/core/evtchn.c --- a/drivers/xen/core/evtchn.c Thu Sep 06 14:33:25 2007 -0600 +++ b/drivers/xen/core/evtchn.c Fri Sep 07 13:57:35 2007 -0600 @@ -125,12 +125,15 @@ static inline unsigned long active_evtch ~sh->evtchn_mask[idx]); } -static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) -{ +void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) +{ + shared_info_t *s = HYPERVISOR_shared_info; int irq = evtchn_to_irq[chn]; - BUG_ON(irq == -1); - set_native_irq_info(irq, cpumask_of_cpu(cpu)); + BUG_ON(!test_bit(chn, s->evtchn_mask)); + + if (irq != -1) + set_native_irq_info(irq, cpumask_of_cpu(cpu)); clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]); set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]); @@ -160,10 +163,6 @@ static inline unsigned long active_evtch unsigned int idx) { return (sh->evtchn_pending[idx] & ~sh->evtchn_mask[idx]); -} - -static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) -{ } static void init_evtchn_cpu_bindings(void) @@ -607,7 +606,7 @@ static void rebind_irq_to_cpu(unsigned i * virq or IPI channel, which don't actually need to be rebound. Ignore * it, but don't do the xenlinux-level rebind in that case. */ - if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0) + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) == 0) bind_evtchn_to_cpu(evtchn, tcpu); } @@ -626,7 +625,7 @@ int resend_irq_on_evtchn(unsigned int ir if (!VALID_EVTCHN(evtchn)) return 1; - masked = synch_test_and_set_bit(evtchn, s->evtchn_mask); + masked = test_and_set_evtchn_mask(evtchn); synch_set_bit(evtchn, s->evtchn_pending); if (!masked) unmask_evtchn(evtchn); diff -r e1466633683c -r 8aa8af371be0 drivers/xen/core/gnttab.c --- a/drivers/xen/core/gnttab.c Thu Sep 06 14:33:25 2007 -0600 +++ b/drivers/xen/core/gnttab.c Fri Sep 07 13:57:35 2007 -0600 @@ -587,7 +587,14 @@ out: put_page(page); return err; } -EXPORT_SYMBOL(gnttab_copy_grant_page); +EXPORT_SYMBOL_GPL(gnttab_copy_grant_page); + +void gnttab_reset_grant_page(struct page *page) +{ + init_page_count(page); + reset_page_mapcount(page); +} +EXPORT_SYMBOL_GPL(gnttab_reset_grant_page); /* * Keep track of foreign pages marked as PageForeign so that we don't diff -r e1466633683c -r 8aa8af371be0 drivers/xen/core/reboot.c --- a/drivers/xen/core/reboot.c Thu Sep 06 14:33:25 2007 -0600 +++ b/drivers/xen/core/reboot.c Fri Sep 07 13:57:35 2007 -0600 @@ -8,7 +8,6 @@ #include <asm/hypervisor.h> #include <xen/xenbus.h> #include <linux/kmod.h> -#include <linux/kthread.h> #include <linux/slab.h> #include <linux/workqueue.h> @@ -68,36 +67,31 @@ static int shutdown_process(void *__unus static int xen_suspend(void *__unused) { - int err = __xen_suspend(fast_suspend); + int err; + + daemonize("suspend"); + err = set_cpus_allowed(current, cpumask_of_cpu(0)); + if (err) { + printk(KERN_ERR "Xen suspend can't run on CPU0 (%d)\n", err); + goto out; + } + + err = __xen_suspend(fast_suspend); if (err) printk(KERN_ERR "Xen suspend failed (%d)\n", err); + + out: shutting_down = SHUTDOWN_INVALID; return 0; } -static int kthread_create_on_cpu(int (*f)(void *arg), - void *arg, - const char *name, - int cpu) -{ - struct task_struct *p; - p = kthread_create(f, arg, name); - if (IS_ERR(p)) - return PTR_ERR(p); - kthread_bind(p, cpu); - wake_up_process(p); - return 0; -} - static void __shutdown_handler(void *unused) { int err; - if (shutting_down != SHUTDOWN_SUSPEND) - err = kernel_thread(shutdown_process, NULL, - CLONE_FS | CLONE_FILES); - else - err = kthread_create_on_cpu(xen_suspend, NULL, "suspend", 0); + err = kernel_thread((shutting_down == SHUTDOWN_SUSPEND) ? + xen_suspend : shutdown_process, + NULL, CLONE_FS | CLONE_FILES); if (err < 0) { printk(KERN_WARNING "Error creating shutdown process (%d): " diff -r e1466633683c -r 8aa8af371be0 drivers/xen/evtchn/evtchn.c --- a/drivers/xen/evtchn/evtchn.c Thu Sep 06 14:33:25 2007 -0600 +++ b/drivers/xen/evtchn/evtchn.c Fri Sep 07 13:57:35 2007 -0600 @@ -62,6 +62,9 @@ struct per_user_data { /* Processes wait on this queue when ring is empty. */ wait_queue_head_t evtchn_wait; struct fasync_struct *evtchn_async_queue; + + int bind_cpu; + int nr_event_wrong_delivery; }; /* Who's bound to each port? */ @@ -93,6 +96,45 @@ void evtchn_device_upcall(int port) spin_unlock(&port_user_lock); } +static void evtchn_rebind_cpu(evtchn_port_t port, unsigned int cpu) +{ + struct evtchn_bind_vcpu ebv = { .port = port, .vcpu = cpu }; + int masked; + + masked = test_and_set_evtchn_mask(port); + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &ebv) == 0) + bind_evtchn_to_cpu(port, cpu); + if (!masked) + unmask_evtchn(port); +} + +static void evtchn_check_wrong_delivery(struct per_user_data *u) +{ + evtchn_port_t port; + unsigned int current_cpu = smp_processor_id(); + + /* Delivered to correct CPU? All is good. */ + if (u->bind_cpu == current_cpu) { + u->nr_event_wrong_delivery = 0; + return; + } + + /* Tolerate up to 100 consecutive misdeliveries. */ + if (++u->nr_event_wrong_delivery < 100) + return; + + spin_lock_irq(&port_user_lock); + + for (port = 0; port < NR_EVENT_CHANNELS; port++) + if (port_user[port] == u) + evtchn_rebind_cpu(port, current_cpu); + + u->bind_cpu = current_cpu; + u->nr_event_wrong_delivery = 0; + + spin_unlock_irq(&port_user_lock); +} + static ssize_t evtchn_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -153,6 +195,8 @@ static ssize_t evtchn_read(struct file * ((bytes2 != 0) && copy_to_user(&buf[bytes1], &u->ring[0], bytes2))) goto unlock_out; + + evtchn_check_wrong_delivery(u); u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t); rc = bytes1 + bytes2; @@ -202,9 +246,22 @@ static void evtchn_bind_to_user(struct p static void evtchn_bind_to_user(struct per_user_data *u, int port) { spin_lock_irq(&port_user_lock); + 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; + } + + evtchn_rebind_cpu(port, u->bind_cpu); + unmask_evtchn(port); + spin_unlock_irq(&port_user_lock); } @@ -385,6 +442,8 @@ static int evtchn_open(struct inode *ino mutex_init(&u->ring_cons_mutex); filp->private_data = u; + + u->bind_cpu = -1; return 0; } diff -r e1466633683c -r 8aa8af371be0 include/xen/evtchn.h --- a/include/xen/evtchn.h Thu Sep 06 14:33:25 2007 -0600 +++ b/include/xen/evtchn.h Fri Sep 07 13:57:35 2007 -0600 @@ -104,6 +104,18 @@ void mask_evtchn(int port); void mask_evtchn(int port); void unmask_evtchn(int port); +#ifdef CONFIG_SMP +void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu); +#else +#define bind_evtchn_to_cpu(chn, cpu) ((void)0) +#endif + +static inline int test_and_set_evtchn_mask(int port) +{ + shared_info_t *s = HYPERVISOR_shared_info; + return synch_test_and_set_bit(port, s->evtchn_mask); +} + static inline void clear_evtchn(int port) { shared_info_t *s = HYPERVISOR_shared_info; diff -r e1466633683c -r 8aa8af371be0 include/xen/gnttab.h --- a/include/xen/gnttab.h Thu Sep 06 14:33:25 2007 -0600 +++ b/include/xen/gnttab.h Fri Sep 07 13:57:35 2007 -0600 @@ -108,11 +108,7 @@ static inline void __gnttab_dma_unmap_pa { } -static inline void gnttab_reset_grant_page(struct page *page) -{ - init_page_count(page); - reset_page_mapcount(page); -} +void gnttab_reset_grant_page(struct page *page); int gnttab_suspend(void); int gnttab_resume(void); diff -r e1466633683c -r 8aa8af371be0 include/xen/xenbus.h --- a/include/xen/xenbus.h Thu Sep 06 14:33:25 2007 -0600 +++ b/include/xen/xenbus.h Fri Sep 07 13:57:35 2007 -0600 @@ -39,6 +39,7 @@ #include <linux/mutex.h> #include <linux/completion.h> #include <linux/init.h> +#include <linux/err.h> #include <xen/interface/xen.h> #include <xen/interface/grant_table.h> #include <xen/interface/io/xenbus.h> _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |