[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



# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1228356137 -32400
# Node ID 17adc5c344fe10169ad00b4e9a78ea4dcf8b041e
# Parent  6743af9fffc6f531a73af66a86738aa3ab4a2366
# Parent  ca213a56dba1f15a86d6edddf1aae39bf9b4a2a5
merge with linux-2.6.18-xen.hg
---
 arch/i386/kernel/io_apic-xen.c   |   14 +++++++-
 arch/i386/mm/hypervisor.c        |   43 ++++++++++++++++++++++---
 arch/i386/mm/pgtable-xen.c       |    8 ++++
 arch/x86_64/kernel/io_apic-xen.c |    6 ++-
 arch/x86_64/mm/pageattr-xen.c    |    8 ++++
 drivers/pci/msi-xen.c            |   52 ++++++++++++++----------------
 drivers/pci/pci.h                |    1 
 drivers/pci/quirks.c             |    3 +
 drivers/pci/setup-bus.c          |    2 -
 drivers/pci/setup-res.c          |   10 +++++
 drivers/xen/blkback/blkback.c    |   10 ++---
 drivers/xen/blktap/blktap.c      |   10 ++---
 drivers/xen/core/evtchn.c        |   66 +++++++++++++++++++++++++++++++--------
 drivers/xen/core/gnttab.c        |    5 +-
 drivers/xen/netback/netback.c    |    6 +--
 include/asm-ia64/maddr.h         |    1 
 include/linux/page-flags.h       |    6 +--
 include/xen/interface/physdev.h  |   15 ++++++++
 mm/page_alloc.c                  |    4 +-
 19 files changed, 197 insertions(+), 73 deletions(-)

diff -r 6743af9fffc6 -r 17adc5c344fe arch/i386/kernel/io_apic-xen.c
--- a/arch/i386/kernel/io_apic-xen.c    Wed Dec 03 11:38:32 2008 +0900
+++ b/arch/i386/kernel/io_apic-xen.c    Thu Dec 04 11:02:17 2008 +0900
@@ -87,8 +87,10 @@ int (*ioapic_renumber_irq)(int ioapic, i
 int (*ioapic_renumber_irq)(int ioapic, int irq);
 atomic_t irq_mis_count;
 
+#ifndef CONFIG_XEN
 /* Where if anywhere is the i8259 connect in external int mode */
 static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
+#endif
 
 static DEFINE_SPINLOCK(ioapic_lock);
 static DEFINE_SPINLOCK(vector_lock);
@@ -793,6 +795,7 @@ static int find_irq_entry(int apic, int 
        return -1;
 }
 
+#ifndef CONFIG_XEN
 /*
  * Find the pin to which IRQ[irq] (ISA) is connected
  */
@@ -842,6 +845,7 @@ static int __init find_isa_irq_apic(int 
 
        return -1;
 }
+#endif
 
 /*
  * Find a specific PCI IRQ entry.
@@ -1687,7 +1691,9 @@ static void __init enable_IO_APIC(void)
 static void __init enable_IO_APIC(void)
 {
        union IO_APIC_reg_01 reg_01;
+#ifndef CONFIG_XEN
        int i8259_apic, i8259_pin;
+#endif
        int i, apic;
        unsigned long flags;
 
@@ -1708,6 +1714,7 @@ static void __init enable_IO_APIC(void)
                spin_unlock_irqrestore(&ioapic_lock, flags);
                nr_ioapic_registers[apic] = reg_01.bits.entries+1;
        }
+#ifndef CONFIG_XEN
        for(apic = 0; apic < nr_ioapics; apic++) {
                int pin;
                /* See if any of the pins is in ExtINT mode */
@@ -1749,6 +1756,7 @@ static void __init enable_IO_APIC(void)
        {
                printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
        }
+#endif
 
        /*
         * Do not trust the IO-APIC being empty at bootup
@@ -2517,6 +2525,8 @@ static int __init io_apic_bug_finalize(v
 
 late_initcall(io_apic_bug_finalize);
 
+#ifndef CONFIG_XEN
+
 struct sysfs_ioapic_data {
        struct sys_device dev;
        struct IO_APIC_route_entry entry[0];
@@ -2570,10 +2580,8 @@ static int ioapic_resume(struct sys_devi
 
 static struct sysdev_class ioapic_sysdev_class = {
        set_kset_name("ioapic"),
-#ifndef CONFIG_XEN
        .suspend = ioapic_suspend,
        .resume = ioapic_resume,
-#endif
 };
 
 static int __init ioapic_init_sysfs(void)
@@ -2611,6 +2619,8 @@ static int __init ioapic_init_sysfs(void
 
 device_initcall(ioapic_init_sysfs);
 
+#endif /* CONFIG_XEN */
+
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
    -------------------------------------------------------------------------- 
*/
diff -r 6743af9fffc6 -r 17adc5c344fe arch/i386/mm/hypervisor.c
--- a/arch/i386/mm/hypervisor.c Wed Dec 03 11:38:32 2008 +0900
+++ b/arch/i386/mm/hypervisor.c Thu Dec 04 11:02:17 2008 +0900
@@ -374,6 +374,15 @@ void xen_destroy_contiguous_region(unsig
 }
 EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
 
+static void undo_limit_pages(struct page *pages, unsigned int order)
+{
+       BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
+       BUG_ON(order > MAX_CONTIG_ORDER);
+       xen_limit_pages_to_max_mfn(pages, order, 0);
+       ClearPageForeign(pages);
+       __free_pages(pages, order);
+}
+
 int xen_limit_pages_to_max_mfn(
        struct page *pages, unsigned int order, unsigned int address_bits)
 {
@@ -402,16 +411,28 @@ int xen_limit_pages_to_max_mfn(
        if (unlikely(order > MAX_CONTIG_ORDER))
                return -ENOMEM;
 
-       bitmap_zero(limit_map, 1U << order);
+       if (address_bits) {
+               if (address_bits < PAGE_SHIFT)
+                       return -EINVAL;
+               bitmap_zero(limit_map, 1U << order);
+       } else if (order) {
+               BUILD_BUG_ON(sizeof(pages->index) != sizeof(*limit_map));
+               for (i = 0; i < BITS_TO_LONGS(1U << order); ++i)
+                       limit_map[i] = pages[i + 1].index;
+       } else
+               __set_bit(0, limit_map);
+
        set_xen_guest_handle(exchange.in.extent_start, in_frames);
        set_xen_guest_handle(exchange.out.extent_start, out_frames);
 
        /* 0. Scrub the pages. */
        for (i = 0, n = 0; i < 1U<<order ; i++) {
                page = &pages[i];
-               if (!(pfn_to_mfn(page_to_pfn(page)) >> (address_bits - 
PAGE_SHIFT)))
-                       continue;
-               __set_bit(i, limit_map);
+               if (address_bits) {
+                       if (!(pfn_to_mfn(page_to_pfn(page)) >> (address_bits - 
PAGE_SHIFT)))
+                               continue;
+                       __set_bit(i, limit_map);
+               }
 
                if (!PageHighMem(page))
                        scrub_pages(page_address(page), 1);
@@ -497,7 +518,19 @@ int xen_limit_pages_to_max_mfn(
 
        balloon_unlock(flags);
 
-       return success ? 0 : -ENOMEM;
+       if (!success)
+               return -ENOMEM;
+
+       if (address_bits) {
+               if (order) {
+                       BUILD_BUG_ON(sizeof(*limit_map) != 
sizeof(pages->index));
+                       for (i = 0; i < BITS_TO_LONGS(1U << order); ++i)
+                               pages[i + 1].index = limit_map[i];
+               }
+               SetPageForeign(pages, undo_limit_pages);
+       }
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(xen_limit_pages_to_max_mfn);
 
diff -r 6743af9fffc6 -r 17adc5c344fe arch/i386/mm/pgtable-xen.c
--- a/arch/i386/mm/pgtable-xen.c        Wed Dec 03 11:38:32 2008 +0900
+++ b/arch/i386/mm/pgtable-xen.c        Thu Dec 04 11:02:17 2008 +0900
@@ -152,6 +152,12 @@ pte_t *pte_alloc_one_kernel(struct mm_st
        return pte;
 }
 
+static void _pte_free(struct page *page, unsigned int order)
+{
+       BUG_ON(order);
+       pte_free(page);
+}
+
 struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
        struct page *pte;
@@ -162,7 +168,7 @@ struct page *pte_alloc_one(struct mm_str
        pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 #endif
        if (pte) {
-               SetPageForeign(pte, pte_free);
+               SetPageForeign(pte, _pte_free);
                init_page_count(pte);
        }
        return pte;
diff -r 6743af9fffc6 -r 17adc5c344fe arch/x86_64/kernel/io_apic-xen.c
--- a/arch/x86_64/kernel/io_apic-xen.c  Wed Dec 03 11:38:32 2008 +0900
+++ b/arch/x86_64/kernel/io_apic-xen.c  Thu Dec 04 11:02:17 2008 +0900
@@ -2054,6 +2054,8 @@ void __init setup_IO_APIC(void)
                print_IO_APIC();
 }
 
+#ifndef CONFIG_XEN
+
 struct sysfs_ioapic_data {
        struct sys_device dev;
        struct IO_APIC_route_entry entry[0];
@@ -2107,10 +2109,8 @@ static int ioapic_resume(struct sys_devi
 
 static struct sysdev_class ioapic_sysdev_class = {
        set_kset_name("ioapic"),
-#ifndef CONFIG_XEN
        .suspend = ioapic_suspend,
        .resume = ioapic_resume,
-#endif
 };
 
 static int __init ioapic_init_sysfs(void)
@@ -2148,6 +2148,8 @@ static int __init ioapic_init_sysfs(void
 
 device_initcall(ioapic_init_sysfs);
 
+#endif /* CONFIG_XEN */
+
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
    -------------------------------------------------------------------------- 
*/
diff -r 6743af9fffc6 -r 17adc5c344fe arch/x86_64/mm/pageattr-xen.c
--- a/arch/x86_64/mm/pageattr-xen.c     Wed Dec 03 11:38:32 2008 +0900
+++ b/arch/x86_64/mm/pageattr-xen.c     Thu Dec 04 11:02:17 2008 +0900
@@ -248,13 +248,19 @@ void _arch_exit_mmap(struct mm_struct *m
                mm_unpin(mm);
 }
 
+static void _pte_free(struct page *page, unsigned int order)
+{
+       BUG_ON(order);
+       pte_free(page);
+}
+
 struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
        struct page *pte;
 
        pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
        if (pte) {
-               SetPageForeign(pte, pte_free);
+               SetPageForeign(pte, _pte_free);
                init_page_count(pte);
        }
        return pte;
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/pci/msi-xen.c
--- a/drivers/pci/msi-xen.c     Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/pci/msi-xen.c     Thu Dec 04 11:02:17 2008 +0900
@@ -42,6 +42,8 @@ struct msi_dev_list {
        struct list_head list;
        spinlock_t pirq_list_lock;
        struct list_head pirq_list_head;
+       /* Used for saving/restoring MSI-X tables */
+       void __iomem *mask_base;
 };
 
 struct msi_pirq_entry {
@@ -50,7 +52,6 @@ struct msi_pirq_entry {
        int entry_nr;
 #ifdef CONFIG_PM
        /* PM save area for MSIX address/data */
-       void __iomem *mask_base;
        u32     address_hi_save;
        u32     address_lo_save;
        u32     data_save;
@@ -90,7 +91,7 @@ static struct msi_dev_list *get_msi_dev_
        return ret;
 }
 
-static int attach_pirq_entry(int pirq, int entry_nr, u64 table_base,
+static int attach_pirq_entry(int pirq, int entry_nr,
                              struct msi_dev_list *msi_dev_entry)
 {
        struct msi_pirq_entry *entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
@@ -100,9 +101,6 @@ static int attach_pirq_entry(int pirq, i
                return -ENOMEM;
        entry->pirq = pirq;
        entry->entry_nr = entry_nr;
-#ifdef COMFIG_PM
-       entry->mask_base = table_base;
-#endif
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        list_add_tail(&entry->list, &msi_dev_entry->pirq_list_head);
        spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
@@ -381,17 +379,24 @@ int pci_save_msix_state(struct pci_dev *
        unsigned long flags;
        struct msi_dev_list *msi_dev_entry;
        struct msi_pirq_entry *pirq_entry;
+       void __iomem *base;
 
        pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
        if (pos <= 0 || dev->no_msi)
                return 0;
-
-       printk(KERN_CRIT "Saving MSIX cap\n");
 
        /* save the capability */
        pci_read_config_word(dev, msi_control_reg(pos), &control);
        if (!(control & PCI_MSIX_FLAGS_ENABLE))
                return 0;
+
+       msi_dev_entry = get_msi_dev_pirq_list(dev);
+       /* If we failed to map the MSI-X table at pci_enable_msix,
+        * We could not support saving them here.
+        */
+       if (!(base = msi_dev_entry->mask_base))
+               return -ENOMEM;
+
        save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u16),
                GFP_KERNEL);
        if (!save_state) {
@@ -400,19 +405,12 @@ int pci_save_msix_state(struct pci_dev *
        }
        *((u16 *)&save_state->data[0]) = control;
 
-       msi_dev_entry = get_msi_dev_pirq_list(dev);
-
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        list_for_each_entry(pirq_entry, &msi_dev_entry->pirq_list_head, list) {
                int j;
-               void __iomem *base;
 
                /* save the table */
-               base = pirq_entry->mask_base;
                j = pirq_entry->entry_nr;
-               printk(KERN_CRIT "Save msix table entry %d pirq %x base %p\n",
-                      j, pirq_entry->pirq, base);
-
                pirq_entry->address_lo_save =
                        readl(base + j * PCI_MSIX_ENTRY_SIZE +
                              PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
@@ -443,7 +441,6 @@ void pci_restore_msix_state(struct pci_d
        save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX);
        if (!save_state)
                return;
-       printk(KERN_CRIT "Restoring MSIX cap\n");
 
        save = *((u16 *)&save_state->data[0]);
        pci_remove_saved_cap(save_state);
@@ -454,15 +451,12 @@ void pci_restore_msix_state(struct pci_d
                return;
 
        msi_dev_entry = get_msi_dev_pirq_list(dev);
+       base = msi_dev_entry->mask_base;
 
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        list_for_each_entry(pirq_entry, &msi_dev_entry->pirq_list_head, list) {
                /* route the table */
-               base = pirq_entry->mask_base;
                j = pirq_entry->entry_nr;
-
-               printk(KERN_CRIT "Restore msix table entry %d pirq %x base 
%p\n",
-                      j, pirq_entry->pirq, base);
                writel(pirq_entry->address_lo_save,
                        base + j * PCI_MSIX_ENTRY_SIZE +
                        PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
@@ -523,7 +517,8 @@ static int msix_capability_init(struct p
                                struct msix_entry *entries, int nvec)
 {
        u64 table_base;
-       int pirq, i, j, mapped, pos;
+       u16 control;
+       int pirq, i, j, mapped, pos, nr_entries;
        struct msi_dev_list *msi_dev_entry = get_msi_dev_pirq_list(dev);
        struct msi_pirq_entry *pirq_entry;
 
@@ -534,6 +529,12 @@ static int msix_capability_init(struct p
        table_base = find_table_base(dev, pos);
        if (!table_base)
                return -ENODEV;
+
+       pci_read_config_word(dev, msi_control_reg(pos), &control);
+       nr_entries = multi_msix_capable(control);
+       if (!msi_dev_entry->mask_base)
+               msi_dev_entry->mask_base = 
+                       ioremap_nocache(table_base, nr_entries * 
PCI_MSIX_ENTRY_SIZE);
 
        /* MSI-X Table Initialization */
        for (i = 0; i < nvec; i++) {
@@ -554,7 +555,7 @@ static int msix_capability_init(struct p
                pirq = msi_map_vector(dev, entries[i].entry, table_base);
                if (pirq < 0)
                        break;
-               attach_pirq_entry(pirq, entries[i].entry, table_base, 
msi_dev_entry);
+               attach_pirq_entry(pirq, entries[i].entry, msi_dev_entry);
                (entries + i)->vector = pirq;
        }
 
@@ -739,7 +740,7 @@ int pci_enable_msix(struct pci_dev* dev,
                        if (mapped)
                                continue;
                        irq = evtchn_map_pirq(-1, entries[i].vector);
-                       attach_pirq_entry(irq, entries[i].entry, 0, 
msi_dev_entry);
+                       attach_pirq_entry(irq, entries[i].entry, msi_dev_entry);
                        entries[i].vector = irq;
                }
         return 0;
@@ -857,18 +858,15 @@ void msi_remove_pci_irq_vectors(struct p
 
        spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
        if (!list_empty(&msi_dev_entry->pirq_list_head))
-       {
-               printk(KERN_WARNING "msix pirqs for dev %02x:%02x:%01x are not 
freed \
-                      before acquire again.\n", dev->bus->number, 
PCI_SLOT(dev->devfn),
-                          PCI_FUNC(dev->devfn));
                list_for_each_entry_safe(pirq_entry, tmp,
                                         &msi_dev_entry->pirq_list_head, list) {
                        msi_unmap_pirq(dev, pirq_entry->pirq);
                        list_del(&pirq_entry->list);
                        kfree(pirq_entry);
                }
-       }
        spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
+       iounmap(msi_dev_entry->mask_base);
+       msi_dev_entry->mask_base = NULL;
        dev->irq = dev->irq_old;
 }
 
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/pci/pci.h
--- a/drivers/pci/pci.h Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/pci/pci.h Thu Dec 04 11:02:17 2008 +0900
@@ -104,5 +104,4 @@ extern void pci_disable_bridge_window(st
 extern void pci_disable_bridge_window(struct pci_dev *dev);
 #else
 #define is_reassigndev(dev) 0
-static inline void pci_disable_bridge_window(struct pci_dev *dev) {}
 #endif
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/pci/quirks.c
--- a/drivers/pci/quirks.c      Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/pci/quirks.c      Thu Dec 04 11:02:17 2008 +0900
@@ -24,6 +24,7 @@
 #include "pci.h"
 
 
+#ifdef CONFIG_PCI_REASSIGN
 /*
  * This quirk function disables the device and releases resources
  * which is specified by kernel's boot parameter 'reassigndev'.
@@ -66,10 +67,10 @@ static void __devinit quirk_release_reso
                    (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
                        pci_disable_bridge_window(dev);
                }
-               return;
        }
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_release_resources);
+#endif  /* CONFIG_PCI_REASSIGN */
 
 /* The Mellanox Tavor device gives false positive parity errors
  * Mark this device with a broken_parity_status, to allow
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/pci/setup-bus.c
--- a/drivers/pci/setup-bus.c   Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/pci/setup-bus.c   Thu Dec 04 11:02:17 2008 +0900
@@ -355,7 +355,7 @@ pbus_size_mem(struct pci_bus *bus, unsig
                                continue;
                        r_size = r->end - r->start + 1;
 
-                       if (reassign)
+                       if ((i < PCI_BRIDGE_RESOURCES) && reassign)
                                r_size = ALIGN(r_size, PAGE_SIZE);
 
                        /* For bridges size != alignment */
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/pci/setup-res.c
--- a/drivers/pci/setup-res.c   Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/pci/setup-res.c   Thu Dec 04 11:02:17 2008 +0900
@@ -234,6 +234,7 @@ pdev_sort_resources(struct pci_dev *dev,
 pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
 {
        int i;
+       int reassigndev = is_reassigndev(dev);
 
        for (i = 0; i < PCI_NUM_RESOURCES; i++) {
                struct resource *r;
@@ -245,6 +246,11 @@ pdev_sort_resources(struct pci_dev *dev,
                
                if (!(r->flags) || r->parent)
                        continue;
+               
+               if (i < PCI_BRIDGE_RESOURCES && (r->flags & IORESOURCE_MEM) &&
+                   reassigndev)
+                       r_align = ALIGN(r_align, PAGE_SIZE);
+
                if (!r_align) {
                        printk(KERN_WARNING "PCI: Ignore bogus resource %d "
                                "[%llx:%llx] of %s\n",
@@ -263,6 +269,10 @@ pdev_sort_resources(struct pci_dev *dev,
                                align = (idx < PCI_BRIDGE_RESOURCES) ?
                                        ln->res->end - ln->res->start + 1 :
                                        ln->res->start;
+                               if ((idx < PCI_BRIDGE_RESOURCES) &&
+                                   (ln->res->flags & IORESOURCE_MEM) &&
+                                   is_reassigndev(ln->dev))
+                                       align = ALIGN(align, PAGE_SIZE);
                        }
                        if (r_align > align) {
                                tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/xen/blkback/blkback.c
--- a/drivers/xen/blkback/blkback.c     Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/xen/blkback/blkback.c     Thu Dec 04 11:02:17 2008 +0900
@@ -317,14 +317,14 @@ static int do_block_io_op(blkif_t *blkif
                if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc))
                        break;
 
+               if (kthread_should_stop()) {
+                       more_to_do = 1;
+                       break;
+               }
+
                pending_req = alloc_req();
                if (NULL == pending_req) {
                        blkif->st_oo_req++;
-                       more_to_do = 1;
-                       break;
-               }
-
-               if (kthread_should_stop()) {
                        more_to_do = 1;
                        break;
                }
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/xen/blktap/blktap.c
--- a/drivers/xen/blktap/blktap.c       Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/xen/blktap/blktap.c       Thu Dec 04 11:02:17 2008 +0900
@@ -1286,14 +1286,14 @@ static int do_block_io_op(blkif_t *blkif
                        break;          
                }
 
+               if (kthread_should_stop()) {
+                       more_to_do = 1;
+                       break;
+               }
+
                pending_req = alloc_req();
                if (NULL == pending_req) {
                        blkif->st_oo_req++;
-                       more_to_do = 1;
-                       break;
-               }
-
-               if (kthread_should_stop()) {
                        more_to_do = 1;
                        break;
                }
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/xen/core/evtchn.c
--- a/drivers/xen/core/evtchn.c Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/xen/core/evtchn.c Thu Dec 04 11:02:17 2008 +0900
@@ -123,9 +123,6 @@ DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS])
 /* Reference counts for bindings to IRQs. */
 static int irq_bindcount[NR_IRQS];
 
-/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
-static DECLARE_BITMAP(pirq_needs_eoi, NR_PIRQS);
-
 #ifdef CONFIG_SMP
 
 static u8 cpu_evtchn[NR_EVENT_CHANNELS];
@@ -756,16 +753,48 @@ static struct hw_interrupt_type dynirq_t
        .retrigger = resend_irq_on_evtchn,
 };
 
-static inline void pirq_unmask_notify(int irq)
+/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
+static int pirq_eoi_does_unmask;
+static DECLARE_BITMAP(pirq_needs_eoi, ALIGN(NR_PIRQS, PAGE_SIZE * 8))
+       __attribute__ ((__section__(".bss.page_aligned"), 
__aligned__(PAGE_SIZE)));
+
+static void pirq_unmask_and_notify(unsigned int evtchn, unsigned int irq)
 {
        struct physdev_eoi eoi = { .irq = evtchn_get_xen_pirq(irq) };
-       if (unlikely(test_bit(irq - PIRQ_BASE, pirq_needs_eoi)))
-               VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
+
+       if (pirq_eoi_does_unmask) {
+               if (test_bit(eoi.irq, pirq_needs_eoi))
+                       VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
+               else
+                       unmask_evtchn(evtchn);
+       } else if (test_bit(irq - PIRQ_BASE, pirq_needs_eoi)) {
+               if (smp_processor_id() != cpu_from_evtchn(evtchn)) {
+                       struct evtchn_unmask unmask = { .port = evtchn };
+                       struct multicall_entry mcl[2];
+
+                       mcl[0].op = __HYPERVISOR_event_channel_op;
+                       mcl[0].args[0] = EVTCHNOP_unmask;
+                       mcl[0].args[1] = (unsigned long)&unmask;
+                       mcl[1].op = __HYPERVISOR_physdev_op;
+                       mcl[1].args[0] = PHYSDEVOP_eoi;
+                       mcl[1].args[1] = (unsigned long)&eoi;
+
+                       if (HYPERVISOR_multicall(mcl, 2))
+                               BUG();
+               } else {
+                       unmask_evtchn(evtchn);
+                       VOID(HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi));
+               }
+       } else
+               unmask_evtchn(evtchn);
 }
 
 static inline void pirq_query_unmask(int irq)
 {
        struct physdev_irq_status_query irq_status;
+
+       if (pirq_eoi_does_unmask)
+               return;
        irq_status.irq = evtchn_get_xen_pirq(irq);
        if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status))
                irq_status.flags = 0;
@@ -806,8 +835,7 @@ static unsigned int startup_pirq(unsigne
        irq_info[irq] = mk_irq_info(IRQT_PIRQ, bind_pirq.pirq, evtchn);
 
  out:
-       unmask_evtchn(evtchn);
-       pirq_unmask_notify(irq);
+       pirq_unmask_and_notify(evtchn, irq);
 
        return 0;
 }
@@ -859,10 +887,8 @@ static void end_pirq(unsigned int irq)
        if ((irq_desc[irq].status & (IRQ_DISABLED|IRQ_PENDING)) ==
            (IRQ_DISABLED|IRQ_PENDING)) {
                shutdown_pirq(irq);
-       } else if (VALID_EVTCHN(evtchn)) {
-               unmask_evtchn(evtchn);
-               pirq_unmask_notify(irq);
-       }
+       } else if (VALID_EVTCHN(evtchn))
+               pirq_unmask_and_notify(evtchn, irq);
 }
 
 static struct hw_interrupt_type pirq_type = {
@@ -1011,6 +1037,15 @@ void irq_resume(void)
        unsigned int cpu, irq, evtchn;
 
        init_evtchn_cpu_bindings();
+
+       if (pirq_eoi_does_unmask) {
+               struct physdev_pirq_eoi_gmfn eoi_gmfn;
+
+               eoi_gmfn.gmfn = arbitrary_virt_to_machine(pirq_needs_eoi)
+                       >> PAGE_SHIFT;
+               if (HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_gmfn, &eoi_gmfn))
+                       BUG();
+       }
 
        /* New event-channel space is not 'live' yet. */
        for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
@@ -1098,8 +1133,15 @@ void __init xen_init_IRQ(void)
 void __init xen_init_IRQ(void)
 {
        unsigned int i;
+       struct physdev_pirq_eoi_gmfn eoi_gmfn;
 
        init_evtchn_cpu_bindings();
+
+       BUG_ON(!bitmap_empty(pirq_needs_eoi, PAGE_SIZE * 8));
+       eoi_gmfn.gmfn = arbitrary_virt_to_machine(pirq_needs_eoi)
+               >> PAGE_SHIFT;
+       if (HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_gmfn, &eoi_gmfn) == 0)
+               pirq_eoi_does_unmask = 1;
 
        /* No event channels are 'live' right now. */
        for (i = 0; i < NR_EVENT_CHANNELS; i++)
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/xen/core/gnttab.c
--- a/drivers/xen/core/gnttab.c Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/xen/core/gnttab.c Thu Dec 04 11:02:17 2008 +0900
@@ -505,8 +505,9 @@ static int gnttab_map(unsigned int start
        return 0;
 }
 
-static void gnttab_page_free(struct page *page)
-{
+static void gnttab_page_free(struct page *page, unsigned int order)
+{
+       BUG_ON(order);
        ClearPageForeign(page);
        gnttab_reset_grant_page(page);
        put_page(page);
diff -r 6743af9fffc6 -r 17adc5c344fe drivers/xen/netback/netback.c
--- a/drivers/xen/netback/netback.c     Wed Dec 03 11:38:32 2008 +0900
+++ b/drivers/xen/netback/netback.c     Thu Dec 04 11:02:17 2008 +0900
@@ -55,7 +55,6 @@ struct netbk_tx_pending_inuse {
 };
 
 static void netif_idx_release(u16 pending_idx);
-static void netif_page_release(struct page *page);
 static void make_tx_response(netif_t *netif, 
                             netif_tx_request_t *txp,
                             s8       st);
@@ -1436,8 +1435,9 @@ static void netif_idx_release(u16 pendin
        tasklet_schedule(&net_tx_tasklet);
 }
 
-static void netif_page_release(struct page *page)
-{
+static void netif_page_release(struct page *page, unsigned int order)
+{
+       BUG_ON(order);
        netif_idx_release(netif_page_index(page));
 }
 
diff -r 6743af9fffc6 -r 17adc5c344fe include/asm-ia64/maddr.h
--- a/include/asm-ia64/maddr.h  Wed Dec 03 11:38:32 2008 +0900
+++ b/include/asm-ia64/maddr.h  Thu Dec 04 11:02:17 2008 +0900
@@ -99,6 +99,7 @@ mfn_to_local_pfn(unsigned long mfn)
 #define mfn_to_virt(mfn) (__va((mfn) << PAGE_SHIFT))
 #define virt_to_mfn(virt) (__pa(virt) >> PAGE_SHIFT)
 #define virt_to_machine(virt) __pa(virt) /* for tpmfront.c */
+#define arbitrary_virt_to_machine(virt) virt_to_machine(ia64_imva(virt))
 
 #define set_phys_to_machine(pfn, mfn) do { } while (0)
 
diff -r 6743af9fffc6 -r 17adc5c344fe include/linux/page-flags.h
--- a/include/linux/page-flags.h        Wed Dec 03 11:38:32 2008 +0900
+++ b/include/linux/page-flags.h        Thu Dec 04 11:02:17 2008 +0900
@@ -252,15 +252,15 @@
 #define PageForeign(page)      test_bit(PG_foreign, &(page)->flags)
 #define SetPageForeign(_page, dtor) do {               \
        set_bit(PG_foreign, &(_page)->flags);           \
-       BUG_ON((dtor) == (void (*)(struct page *))0);   \
+       BUG_ON((dtor) == (void (*)(struct page *, unsigned int))0); \
        (_page)->index = (long)(dtor);                  \
 } while (0)
 #define ClearPageForeign(page) do {                    \
        clear_bit(PG_foreign, &(page)->flags);          \
        (page)->index = 0;                              \
 } while (0)
-#define PageForeignDestructor(_page)                   \
-       ((void (*)(struct page *))(_page)->index)(_page)
+#define PageForeignDestructor(_page, order)            \
+       ((void (*)(struct page *, unsigned int))(_page)->index)(_page, order)
 
 struct page;   /* forward declaration */
 
diff -r 6743af9fffc6 -r 17adc5c344fe include/xen/interface/physdev.h
--- a/include/xen/interface/physdev.h   Wed Dec 03 11:38:32 2008 +0900
+++ b/include/xen/interface/physdev.h   Thu Dec 04 11:02:17 2008 +0900
@@ -41,6 +41,21 @@ DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
 DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t);
 
 /*
+ * Register a shared page for the hypervisor to indicate whether the guest
+ * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly
+ * once the guest used this function in that the associated event channel
+ * will automatically get unmasked. The page registered is used as a bit
+ * array indexed by Xen's PIRQ value.
+ */
+#define PHYSDEVOP_pirq_eoi_gmfn         17
+struct physdev_pirq_eoi_gmfn {
+    /* IN */
+    xen_pfn_t gmfn;
+};
+typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t);
+
+/*
  * Query the status of an IRQ line.
  * @arg == pointer to physdev_irq_status_query structure.
  */
diff -r 6743af9fffc6 -r 17adc5c344fe mm/page_alloc.c
--- a/mm/page_alloc.c   Wed Dec 03 11:38:32 2008 +0900
+++ b/mm/page_alloc.c   Thu Dec 04 11:02:17 2008 +0900
@@ -453,7 +453,7 @@ static void __free_pages_ok(struct page 
 
 #ifdef CONFIG_XEN
        if (PageForeign(page)) {
-               PageForeignDestructor(page);
+               PageForeignDestructor(page, order);
                return;
        }
 #endif
@@ -737,7 +737,7 @@ static void fastcall free_hot_cold_page(
 
 #ifdef CONFIG_XEN
        if (PageForeign(page)) {
-               PageForeignDestructor(page);
+               PageForeignDestructor(page, 0);
                return;
        }
 #endif

_______________________________________________
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®.