[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.