Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 20 Jun 2008 19:37:13 +0000 (12:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 20 Jun 2008 19:37:13 +0000 (12:37 -0700)
* 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  softlockup: fix NMI hangs due to lock race - 2.6.26-rc regression
  rcupreempt: remove export of rcu_batches_completed_bh
  cpuset: limit the input of cpuset.sched_relax_domain_level

28 files changed:
arch/powerpc/kernel/vdso.c
arch/x86/kernel/geode_32.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/setup_32.c
arch/x86/kernel/tsc_32.c
drivers/ata/Kconfig
drivers/ata/ahci.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/libata.h
drivers/ata/sata_mv.c
drivers/serial/bfin_5xx.c
drivers/watchdog/hpwdt.c
include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
include/asm-x86/geode.h
include/asm-x86/page_32.h
kernel/cpuset.c
kernel/sched.c
kernel/sched_rt.c
kernel/sched_stats.h
mm/memory.c
mm/migrate.c

index c21a626..ce245a8 100644 (file)
@@ -142,7 +142,7 @@ static void dump_one_vdso_page(struct page *pg, struct page *upg)
        printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT),
               page_count(pg),
               pg->flags);
-       if (upg/* && pg != upg*/) {
+       if (upg && !IS_ERR(upg) /* && pg != upg*/) {
                printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg)
                                                       << PAGE_SHIFT),
                       page_count(upg),
index e8edd63..9b08e85 100644 (file)
@@ -166,6 +166,8 @@ int geode_has_vsa2(void)
        static int has_vsa2 = -1;
 
        if (has_vsa2 == -1) {
+               u16 val;
+
                /*
                 * The VSA has virtual registers that we can query for a
                 * signature.
@@ -173,7 +175,8 @@ int geode_has_vsa2(void)
                outw(VSA_VR_UNLOCK, VSA_VRC_INDEX);
                outw(VSA_VR_SIGNATURE, VSA_VRC_INDEX);
 
-               has_vsa2 = (inw(VSA_VRC_DATA) == VSA_SIG);
+               val = inw(VSA_VRC_DATA);
+               has_vsa2 = (val == AMD_VSA_SIG || val == GSW_VSA_SIG);
        }
 
        return has_vsa2;
index 6d54833..e2db9ac 100644 (file)
@@ -333,6 +333,7 @@ void flush_thread(void)
        /*
         * Forget coprocessor state..
         */
+       tsk->fpu_counter = 0;
        clear_fpu(tsk);
        clear_used_math();
 }
index ac54ff5..c6eb5c9 100644 (file)
@@ -294,6 +294,7 @@ void flush_thread(void)
        /*
         * Forget coprocessor state..
         */
+       tsk->fpu_counter = 0;
        clear_fpu(tsk);
        clear_used_math();
 }
index 2c5f8b2..5a2f8e0 100644 (file)
@@ -532,10 +532,16 @@ static void __init reserve_crashkernel(void)
                                        (unsigned long)(crash_size >> 20),
                                        (unsigned long)(crash_base >> 20),
                                        (unsigned long)(total_mem >> 20));
+
+                       if (reserve_bootmem(crash_base, crash_size,
+                                       BOOTMEM_EXCLUSIVE) < 0) {
+                               printk(KERN_INFO "crashkernel reservation "
+                                       "failed - memory is in use\n");
+                               return;
+                       }
+
                        crashk_res.start = crash_base;
                        crashk_res.end   = crash_base + crash_size - 1;
-                       reserve_bootmem(crash_base, crash_size,
-                                       BOOTMEM_DEFAULT);
                } else
                        printk(KERN_INFO "crashkernel reservation failed - "
                                        "you have to specify a base address\n");
index 068759d..65b7063 100644 (file)
 
 #include "mach_timer.h"
 
-static int tsc_disabled;
+/* native_sched_clock() is called before tsc_init(), so
+   we must start with the TSC soft disabled to prevent
+   erroneous rdtsc usage on !cpu_has_tsc processors */
+static int tsc_disabled = -1;
 
 /*
  * On some systems the TSC frequency does not
@@ -402,25 +405,20 @@ void __init tsc_init(void)
 {
        int cpu;
 
-       if (!cpu_has_tsc || tsc_disabled) {
-               /* Disable the TSC in case of !cpu_has_tsc */
-               tsc_disabled = 1;
+       if (!cpu_has_tsc || tsc_disabled > 0)
                return;
-       }
 
        cpu_khz = calculate_cpu_khz();
        tsc_khz = cpu_khz;
 
        if (!cpu_khz) {
                mark_tsc_unstable("could not calculate TSC khz");
-               /*
-                * We need to disable the TSC completely in this case
-                * to prevent sched_clock() from using it.
-                */
-               tsc_disabled = 1;
                return;
        }
 
+       /* now allow native_sched_clock() to use rdtsc */
+       tsc_disabled = 0;
+
        printk("Detected %lu.%03lu MHz processor.\n",
                                (unsigned long)cpu_khz / 1000,
                                (unsigned long)cpu_khz % 1000);
index 9bf2986..ae84949 100644 (file)
@@ -651,9 +651,17 @@ config PATA_WINBOND_VLB
          Support for the Winbond W83759A controller on Vesa Local Bus
          systems.
 
+config HAVE_PATA_PLATFORM
+       bool
+       help
+         This is an internal configuration node for any machine that
+         uses pata-platform driver to enable the relevant driver in the
+         configuration structure without having to submit endless patches
+         to update the PATA_PLATFORM entry.
+
 config PATA_PLATFORM
        tristate "Generic platform device PATA support"
-       depends on EMBEDDED || ARCH_RPC || PPC
+       depends on EMBEDDED || ARCH_RPC || PPC || HAVE_PATA_PLATFORM
        help
          This option enables support for generic directly connected ATA
          devices commonly found on embedded systems.
index 966ab40..6a4a2a2 100644 (file)
@@ -90,6 +90,7 @@ enum {
        board_ahci_mv           = 4,
        board_ahci_sb700        = 5,
        board_ahci_mcp65        = 6,
+       board_ahci_nopmp        = 7,
 
        /* global controller registers */
        HOST_CAP                = 0x00, /* host capabilities */
@@ -401,6 +402,14 @@ static const struct ata_port_info ahci_port_info[] = {
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
+       /* board_ahci_nopmp */
+       {
+               AHCI_HFLAGS     (AHCI_HFLAG_NO_PMP),
+               .flags          = AHCI_FLAG_COMMON,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &ahci_ops,
+       },
 };
 
 static const struct pci_device_id ahci_pci_tbl[] = {
@@ -525,9 +534,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci },            /* MCP7B */
 
        /* SiS */
-       { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
-       { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
-       { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
+       { PCI_VDEVICE(SI, 0x1184), board_ahci_nopmp },          /* SiS 966 */
+       { PCI_VDEVICE(SI, 0x1185), board_ahci_nopmp },          /* SiS 968 */
+       { PCI_VDEVICE(SI, 0x0186), board_ahci_nopmp },          /* SiS 968 */
 
        /* Marvell */
        { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv },        /* 6145 */
@@ -653,6 +662,14 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
                cap &= ~HOST_CAP_PMP;
        }
 
+       if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361 &&
+           port_map != 1) {
+               dev_printk(KERN_INFO, &pdev->dev,
+                          "JMB361 has only one port, port_map 0x%x -> 0x%x\n",
+                          port_map, 1);
+               port_map = 1;
+       }
+
        /*
         * Temporary Marvell 6145 hack: PATA port presence
         * is asserted through the standard AHCI port
index 81b7ae3..a90ae03 100644 (file)
@@ -1043,6 +1043,13 @@ static int piix_broken_suspend(void)
                        },
                },
                {
+                       .ident = "TECRA M4",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M4"),
+                       },
+               },
+               {
                        .ident = "TECRA M5",
                        .matches = {
                                DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
index cc816ca..303fc0d 100644 (file)
@@ -4297,7 +4297,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
 }
 
 /**
- *     ata_check_atapi_dma - Check whether ATAPI DMA can be supported
+ *     atapi_check_dma - Check whether ATAPI DMA can be supported
  *     @qc: Metadata associated with taskfile to check
  *
  *     Allow low-level driver to filter ATA PACKET commands, returning
@@ -4310,7 +4310,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
  *     RETURNS: 0 when ATAPI DMA can be used
  *               nonzero otherwise
  */
-int ata_check_atapi_dma(struct ata_queued_cmd *qc)
+int atapi_check_dma(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
 
index 2e6e162..57a4364 100644 (file)
@@ -2343,8 +2343,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
 {
        struct scsi_cmnd *scmd = qc->scsicmd;
        struct ata_device *dev = qc->dev;
-       int using_pio = (dev->flags & ATA_DFLAG_PIO);
        int nodata = (scmd->sc_data_direction == DMA_NONE);
+       int using_pio = !nodata && (dev->flags & ATA_DFLAG_PIO);
        unsigned int nbytes;
 
        memset(qc->cdb, 0, dev->cdb_len);
@@ -2362,7 +2362,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        ata_qc_set_pc_nbytes(qc);
 
        /* check whether ATAPI DMA is safe */
-       if (!using_pio && ata_check_atapi_dma(qc))
+       if (!nodata && !using_pio && atapi_check_dma(qc))
                using_pio = 1;
 
        /* Some controller variants snoop this value for Packet
@@ -2402,13 +2402,11 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        qc->tf.lbam = (nbytes & 0xFF);
        qc->tf.lbah = (nbytes >> 8);
 
-       if (using_pio || nodata) {
-               /* no data, or PIO data xfer */
-               if (nodata)
-                       qc->tf.protocol = ATAPI_PROT_NODATA;
-               else
-                       qc->tf.protocol = ATAPI_PROT_PIO;
-       } else {
+       if (nodata)
+               qc->tf.protocol = ATAPI_PROT_NODATA;
+       else if (using_pio)
+               qc->tf.protocol = ATAPI_PROT_PIO;
+       else {
                /* DMA data xfer */
                qc->tf.protocol = ATAPI_PROT_DMA;
                qc->tf.feature |= ATAPI_PKT_DMA;
index 4514283..1cf803a 100644 (file)
@@ -106,7 +106,7 @@ extern void ata_sg_clean(struct ata_queued_cmd *qc);
 extern void ata_qc_free(struct ata_queued_cmd *qc);
 extern void ata_qc_issue(struct ata_queued_cmd *qc);
 extern void __ata_qc_complete(struct ata_queued_cmd *qc);
-extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
+extern int atapi_check_dma(struct ata_queued_cmd *qc);
 extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
 extern void ata_dev_init(struct ata_device *dev);
 extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp);
index 60391e9..28092bc 100644 (file)
@@ -1322,6 +1322,9 @@ static int mv_port_start(struct ata_port *ap)
                goto out_port_free_dma_mem;
        memset(pp->crpb, 0, MV_CRPB_Q_SZ);
 
+       /* 6041/6081 Rev. "C0" (and newer) are okay with async notify */
+       if (hpriv->hp_flags & MV_HP_ERRATA_60X1C0)
+               ap->flags |= ATA_FLAG_AN;
        /*
         * For GEN_I, there's no NCQ, so we only allocate a single sg_tbl.
         * For later hardware, we need one unique sg_tbl per NCQ tag.
@@ -1592,6 +1595,24 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
 
        if ((qc->tf.protocol != ATA_PROT_DMA) &&
            (qc->tf.protocol != ATA_PROT_NCQ)) {
+               static int limit_warnings = 10;
+               /*
+                * Errata SATA#16, SATA#24: warn if multiple DRQs expected.
+                *
+                * Someday, we might implement special polling workarounds
+                * for these, but it all seems rather unnecessary since we
+                * normally use only DMA for commands which transfer more
+                * than a single block of data.
+                *
+                * Much of the time, this could just work regardless.
+                * So for now, just log the incident, and allow the attempt.
+                */
+               if (limit_warnings && (qc->nbytes / qc->sect_size) > 1) {
+                       --limit_warnings;
+                       ata_link_printk(qc->dev->link, KERN_WARNING, DRV_NAME
+                                       ": attempting PIO w/multiple DRQ: "
+                                       "this may fail due to h/w errata\n");
+               }
                /*
                 * We're about to send a non-EDMA capable command to the
                 * port.  Turn off EDMA so there won't be problems accessing
index f20952c..fd9bb77 100644 (file)
@@ -49,6 +49,7 @@
 #define DMA_RX_YCOUNT          (PAGE_SIZE / DMA_RX_XCOUNT)
 
 #define DMA_RX_FLUSH_JIFFIES   (HZ / 50)
+#define CTS_CHECK_JIFFIES      (HZ / 50)
 
 #ifdef CONFIG_SERIAL_BFIN_DMA
 static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart);
@@ -290,11 +291,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
 {
        struct circ_buf *xmit = &uart->port.info->xmit;
 
-       if (uart->port.x_char) {
-               UART_PUT_CHAR(uart, uart->port.x_char);
-               uart->port.icount.tx++;
-               uart->port.x_char = 0;
-       }
        /*
         * Check the modem control lines before
         * transmitting anything.
@@ -306,6 +302,12 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
                return;
        }
 
+       if (uart->port.x_char) {
+               UART_PUT_CHAR(uart, uart->port.x_char);
+               uart->port.icount.tx++;
+               uart->port.x_char = 0;
+       }
+
        while ((UART_GET_LSR(uart) & THRE) && xmit->tail != xmit->head) {
                UART_PUT_CHAR(uart, xmit->buf[xmit->tail]);
                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -345,15 +347,6 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
 }
 #endif
 
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-static void bfin_serial_do_work(struct work_struct *work)
-{
-       struct bfin_serial_port *uart = container_of(work, struct bfin_serial_port, cts_workqueue);
-
-       bfin_serial_mctrl_check(uart);
-}
-#endif
-
 #ifdef CONFIG_SERIAL_BFIN_DMA
 static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
 {
@@ -361,6 +354,12 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
 
        uart->tx_done = 0;
 
+       /*
+        * Check the modem control lines before
+        * transmitting anything.
+        */
+       bfin_serial_mctrl_check(uart);
+
        if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
                uart->tx_count = 0;
                uart->tx_done = 1;
@@ -373,12 +372,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
                uart->port.x_char = 0;
        }
 
-       /*
-        * Check the modem control lines before
-        * transmitting anything.
-        */
-       bfin_serial_mctrl_check(uart);
-
        uart->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE);
        if (uart->tx_count > (UART_XMIT_SIZE - xmit->tail))
                uart->tx_count = UART_XMIT_SIZE - xmit->tail;
@@ -565,7 +558,10 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart)
        uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
        if (!(status & TIOCM_CTS)) {
                tty->hw_stopped = 1;
-               schedule_work(&uart->cts_workqueue);
+               uart->cts_timer.data = (unsigned long)(uart);
+               uart->cts_timer.function = (void *)bfin_serial_mctrl_check;
+               uart->cts_timer.expires = jiffies + CTS_CHECK_JIFFIES;
+               add_timer(&(uart->cts_timer));
        } else {
                tty->hw_stopped = 0;
        }
@@ -885,7 +881,7 @@ static void __init bfin_serial_init_ports(void)
                init_timer(&(bfin_serial_ports[i].rx_dma_timer));
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-               INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work);
+               init_timer(&(bfin_serial_ports[i].cts_timer));
                bfin_serial_ports[i].cts_pin        =
                        bfin_serial_resource[i].uart_cts_pin;
                bfin_serial_ports[i].rts_pin        =
index 2686f3e..eaa3f2a 100644 (file)
@@ -140,49 +140,53 @@ static struct pci_device_id hpwdt_devices[] = {
 };
 MODULE_DEVICE_TABLE(pci, hpwdt_devices);
 
+extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs, unsigned long *pRomEntry);
+
 #ifndef CONFIG_X86_64
 /* --32 Bit Bios------------------------------------------------------------ */
 
 #define HPWDT_ARCH     32
 
-asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
-                              unsigned long *pRomEntry)
-{
-       asm("pushl       %ebp               \n\t"
-           "movl        %esp, %ebp         \n\t"
-           "pusha                          \n\t"
-           "pushf                          \n\t"
-           "push        %es                \n\t"
-           "push        %ds                \n\t"
-           "pop         %es                \n\t"
-           "movl        8(%ebp),%eax       \n\t"
-           "movl        4(%eax),%ebx       \n\t"
-           "movl        8(%eax),%ecx       \n\t"
-           "movl        12(%eax),%edx      \n\t"
-           "movl        16(%eax),%esi      \n\t"
-           "movl        20(%eax),%edi      \n\t"
-           "movl        (%eax),%eax        \n\t"
-           "push        %cs                \n\t"
-           "call        *12(%ebp)          \n\t"
-           "pushf                          \n\t"
-           "pushl       %eax               \n\t"
-           "movl        8(%ebp),%eax       \n\t"
-           "movl        %ebx,4(%eax)       \n\t"
-           "movl        %ecx,8(%eax)       \n\t"
-           "movl        %edx,12(%eax)      \n\t"
-           "movl        %esi,16(%eax)      \n\t"
-           "movl        %edi,20(%eax)      \n\t"
-           "movw        %ds,24(%eax)       \n\t"
-           "movw        %es,26(%eax)       \n\t"
-           "popl        %ebx               \n\t"
-           "movl        %ebx,(%eax)        \n\t"
-           "popl        %ebx               \n\t"
-           "movl        %ebx,28(%eax)      \n\t"
-           "pop         %es                \n\t"
-           "popf                           \n\t"
-           "popa                           \n\t"
-           "leave                          \n\t" "ret");
-}
+asm(".text                          \n\t"
+    ".align 4                       \n"
+    "asminline_call:                \n\t"
+    "pushl       %ebp               \n\t"
+    "movl        %esp, %ebp         \n\t"
+    "pusha                          \n\t"
+    "pushf                          \n\t"
+    "push        %es                \n\t"
+    "push        %ds                \n\t"
+    "pop         %es                \n\t"
+    "movl        8(%ebp),%eax       \n\t"
+    "movl        4(%eax),%ebx       \n\t"
+    "movl        8(%eax),%ecx       \n\t"
+    "movl        12(%eax),%edx      \n\t"
+    "movl        16(%eax),%esi      \n\t"
+    "movl        20(%eax),%edi      \n\t"
+    "movl        (%eax),%eax        \n\t"
+    "push        %cs                \n\t"
+    "call        *12(%ebp)          \n\t"
+    "pushf                          \n\t"
+    "pushl       %eax               \n\t"
+    "movl        8(%ebp),%eax       \n\t"
+    "movl        %ebx,4(%eax)       \n\t"
+    "movl        %ecx,8(%eax)       \n\t"
+    "movl        %edx,12(%eax)      \n\t"
+    "movl        %esi,16(%eax)      \n\t"
+    "movl        %edi,20(%eax)      \n\t"
+    "movw        %ds,24(%eax)       \n\t"
+    "movw        %es,26(%eax)       \n\t"
+    "popl        %ebx               \n\t"
+    "movl        %ebx,(%eax)        \n\t"
+    "popl        %ebx               \n\t"
+    "movl        %ebx,28(%eax)      \n\t"
+    "pop         %es                \n\t"
+    "popf                           \n\t"
+    "popa                           \n\t"
+    "leave                          \n\t"
+    "ret                            \n\t"
+    ".previous");
+
 
 /*
  *     cru_detect
@@ -333,43 +337,44 @@ static int __devinit detect_cru_service(void)
 
 #define HPWDT_ARCH     64
 
-asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
-                              unsigned long *pRomEntry)
-{
-       asm("pushq      %rbp            \n\t"
-           "movq       %rsp, %rbp      \n\t"
-           "pushq      %rax            \n\t"
-           "pushq      %rbx            \n\t"
-           "pushq      %rdx            \n\t"
-           "pushq      %r12            \n\t"
-           "pushq      %r9             \n\t"
-           "movq       %rsi, %r12      \n\t"
-           "movq       %rdi, %r9       \n\t"
-           "movl       4(%r9),%ebx     \n\t"
-           "movl       8(%r9),%ecx     \n\t"
-           "movl       12(%r9),%edx    \n\t"
-           "movl       16(%r9),%esi    \n\t"
-           "movl       20(%r9),%edi    \n\t"
-           "movl       (%r9),%eax      \n\t"
-           "call       *%r12           \n\t"
-           "pushfq                     \n\t"
-           "popq        %r12           \n\t"
-           "popfq                      \n\t"
-           "movl       %eax, (%r9)     \n\t"
-           "movl       %ebx, 4(%r9)    \n\t"
-           "movl       %ecx, 8(%r9)    \n\t"
-           "movl       %edx, 12(%r9)   \n\t"
-           "movl       %esi, 16(%r9)   \n\t"
-           "movl       %edi, 20(%r9)   \n\t"
-           "movq       %r12, %rax      \n\t"
-           "movl       %eax, 28(%r9)   \n\t"
-           "popq       %r9             \n\t"
-           "popq       %r12            \n\t"
-           "popq       %rdx            \n\t"
-           "popq       %rbx            \n\t"
-           "popq       %rax            \n\t"
-           "leave                      \n\t" "ret");
-}
+asm(".text                      \n\t"
+    ".align 4                   \n"
+    "asminline_call:            \n\t"
+    "pushq      %rbp            \n\t"
+    "movq       %rsp, %rbp      \n\t"
+    "pushq      %rax            \n\t"
+    "pushq      %rbx            \n\t"
+    "pushq      %rdx            \n\t"
+    "pushq      %r12            \n\t"
+    "pushq      %r9             \n\t"
+    "movq       %rsi, %r12      \n\t"
+    "movq       %rdi, %r9       \n\t"
+    "movl       4(%r9),%ebx     \n\t"
+    "movl       8(%r9),%ecx     \n\t"
+    "movl       12(%r9),%edx    \n\t"
+    "movl       16(%r9),%esi    \n\t"
+    "movl       20(%r9),%edi    \n\t"
+    "movl       (%r9),%eax      \n\t"
+    "call       *%r12           \n\t"
+    "pushfq                     \n\t"
+    "popq        %r12           \n\t"
+    "popfq                      \n\t"
+    "movl       %eax, (%r9)     \n\t"
+    "movl       %ebx, 4(%r9)    \n\t"
+    "movl       %ecx, 8(%r9)    \n\t"
+    "movl       %edx, 12(%r9)   \n\t"
+    "movl       %esi, 16(%r9)   \n\t"
+    "movl       %edi, 20(%r9)   \n\t"
+    "movq       %r12, %rax      \n\t"
+    "movl       %eax, 28(%r9)   \n\t"
+    "popq       %r9             \n\t"
+    "popq       %r12            \n\t"
+    "popq       %rdx            \n\t"
+    "popq       %rbx            \n\t"
+    "popq       %rax            \n\t"
+    "leave                      \n\t"
+    "ret                        \n\t"
+    ".previous");
 
 /*
  *     dmi_find_cru
index 96bd09e..2526b6e 100644 (file)
@@ -96,7 +96,7 @@ struct bfin_serial_port {
        struct work_struct tx_dma_workqueue;
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-       struct work_struct cts_workqueue;
+       struct timer_list cts_timer;
        int cts_pin;
        int rts_pin;
 #endif
index e924569..ebf592b 100644 (file)
@@ -88,7 +88,7 @@ struct bfin_serial_port {
 # endif
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-       struct work_struct      cts_workqueue;
+       struct timer_list       cts_timer;
        int                     cts_pin;
        int                     rts_pin;
 #endif
index 41d7b64..1bf56ff 100644 (file)
@@ -96,7 +96,7 @@ struct bfin_serial_port {
        struct work_struct      tx_dma_workqueue;
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-       struct work_struct      cts_workqueue;
+       struct timer_list       cts_timer;
        int             cts_pin;
        int             rts_pin;
 #endif
index 59b4ad4..5e29446 100644 (file)
@@ -99,7 +99,7 @@ struct bfin_serial_port {
        struct work_struct      tx_dma_workqueue;
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-       struct work_struct      cts_workqueue;
+       struct timer_list       cts_timer;
        int             cts_pin;
        int             rts_pin;
 #endif
@@ -187,7 +187,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
 
 #ifdef CONFIG_BFIN_UART1_CTSRTS
        peripheral_request(P_UART1_RTS, DRIVER_NAME);
-       peripheral_request(P_UART1_CTS DRIVER_NAME);
+       peripheral_request(P_UART1_CTS, DRIVER_NAME);
 #endif
 #endif
 
@@ -202,7 +202,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
 
 #ifdef CONFIG_BFIN_UART3_CTSRTS
        peripheral_request(P_UART3_RTS, DRIVER_NAME);
-       peripheral_request(P_UART3_CTS DRIVER_NAME);
+       peripheral_request(P_UART3_CTS, DRIVER_NAME);
 #endif
 #endif
        SSYNC();
index 30d90b5..8aa0278 100644 (file)
@@ -88,7 +88,7 @@ struct bfin_serial_port {
 # endif
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-       struct work_struct      cts_workqueue;
+       struct timer_list       cts_timer;
        int                     cts_pin;
        int                     rts_pin;
 #endif
index 6e64588..bb06027 100644 (file)
@@ -112,8 +112,8 @@ extern int geode_get_dev_base(unsigned int dev);
 #define VSA_VR_UNLOCK          0xFC53  /* unlock virtual register */
 #define VSA_VR_SIGNATURE       0x0003
 #define VSA_VR_MEM_SIZE                0x0200
-#define VSA_SIG                        0x4132  /* signature is ascii 'VSA2' */
-
+#define AMD_VSA_SIG            0x4132  /* signature is ascii 'VSA2' */
+#define GSW_VSA_SIG            0x534d  /* General Software signature */
 /* GPIO */
 
 #define GPIO_OUTPUT_VAL                0x00
index 424e82f..ccf0ba3 100644 (file)
@@ -14,7 +14,8 @@
 #define __PAGE_OFFSET          _AC(CONFIG_PAGE_OFFSET, UL)
 
 #ifdef CONFIG_X86_PAE
-#define __PHYSICAL_MASK_SHIFT  36
+/* 44=32+12, the limit we can fit into an unsigned long pfn */
+#define __PHYSICAL_MASK_SHIFT  44
 #define __VIRTUAL_MASK_SHIFT   32
 #define PAGETABLE_LEVELS       3
 
index 66103a1..9fceb97 100644 (file)
@@ -1890,6 +1890,12 @@ static void common_cpu_mem_hotplug_unplug(void)
        top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
        scan_for_empty_cpusets(&top_cpuset);
 
+       /*
+        * Scheduler destroys domains on hotplug events.
+        * Rebuild them based on the current settings.
+        */
+       rebuild_sched_domains();
+
        cgroup_unlock();
 }
 
index bb2c699..b048ad8 100644 (file)
@@ -1127,6 +1127,7 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer)
        return HRTIMER_NORESTART;
 }
 
+#ifdef CONFIG_SMP
 static void hotplug_hrtick_disable(int cpu)
 {
        struct rq *rq = cpu_rq(cpu);
@@ -1182,6 +1183,7 @@ static void init_hrtick(void)
 {
        hotcpu_notifier(hotplug_hrtick, 0);
 }
+#endif /* CONFIG_SMP */
 
 static void init_rq_hrtick(struct rq *rq)
 {
@@ -7241,6 +7243,18 @@ void __attribute__((weak)) arch_update_cpu_topology(void)
 }
 
 /*
+ * Free current domain masks.
+ * Called after all cpus are attached to NULL domain.
+ */
+static void free_sched_domains(void)
+{
+       ndoms_cur = 0;
+       if (doms_cur != &fallback_doms)
+               kfree(doms_cur);
+       doms_cur = &fallback_doms;
+}
+
+/*
  * Set up scheduler domains and groups. Callers must hold the hotplug lock.
  * For now this just excludes isolated cpus, but could be used to
  * exclude other special cases in the future.
@@ -7387,6 +7401,7 @@ int arch_reinit_sched_domains(void)
        get_online_cpus();
        mutex_lock(&sched_domains_mutex);
        detach_destroy_domains(&cpu_online_map);
+       free_sched_domains();
        err = arch_init_sched_domains(&cpu_online_map);
        mutex_unlock(&sched_domains_mutex);
        put_online_cpus();
@@ -7472,6 +7487,7 @@ static int update_sched_domains(struct notifier_block *nfb,
        case CPU_DOWN_PREPARE:
        case CPU_DOWN_PREPARE_FROZEN:
                detach_destroy_domains(&cpu_online_map);
+               free_sched_domains();
                return NOTIFY_OK;
 
        case CPU_UP_CANCELED:
@@ -7490,8 +7506,16 @@ static int update_sched_domains(struct notifier_block *nfb,
                return NOTIFY_DONE;
        }
 
+#ifndef CONFIG_CPUSETS
+       /*
+        * Create default domain partitioning if cpusets are disabled.
+        * Otherwise we let cpusets rebuild the domains based on the
+        * current setup.
+        */
+
        /* The hotplug lock is already held by cpu_up/cpu_down */
        arch_init_sched_domains(&cpu_online_map);
+#endif
 
        return NOTIFY_OK;
 }
@@ -7631,7 +7655,6 @@ static void init_tg_rt_entry(struct task_group *tg, struct rt_rq *rt_rq,
        else
                rt_se->rt_rq = parent->my_q;
 
-       rt_se->rt_rq = &rq->rt;
        rt_se->my_q = rt_rq;
        rt_se->parent = parent;
        INIT_LIST_HEAD(&rt_se->run_list);
@@ -8353,7 +8376,7 @@ static unsigned long to_ratio(u64 period, u64 runtime)
 #ifdef CONFIG_CGROUP_SCHED
 static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
 {
-       struct task_group *tgi, *parent = tg->parent;
+       struct task_group *tgi, *parent = tg ? tg->parent : NULL;
        unsigned long total = 0;
 
        if (!parent) {
index 3432d57..1dad5bb 100644 (file)
@@ -449,13 +449,19 @@ void dec_rt_tasks(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 #endif
 }
 
-static void enqueue_rt_entity(struct sched_rt_entity *rt_se)
+static void __enqueue_rt_entity(struct sched_rt_entity *rt_se)
 {
        struct rt_rq *rt_rq = rt_rq_of_se(rt_se);
        struct rt_prio_array *array = &rt_rq->active;
        struct rt_rq *group_rq = group_rt_rq(rt_se);
 
-       if (group_rq && rt_rq_throttled(group_rq))
+       /*
+        * Don't enqueue the group if its throttled, or when empty.
+        * The latter is a consequence of the former when a child group
+        * get throttled and the current group doesn't have any other
+        * active members.
+        */
+       if (group_rq && (rt_rq_throttled(group_rq) || !group_rq->rt_nr_running))
                return;
 
        list_add_tail(&rt_se->run_list, array->queue + rt_se_prio(rt_se));
@@ -464,7 +470,7 @@ static void enqueue_rt_entity(struct sched_rt_entity *rt_se)
        inc_rt_tasks(rt_se, rt_rq);
 }
 
-static void dequeue_rt_entity(struct sched_rt_entity *rt_se)
+static void __dequeue_rt_entity(struct sched_rt_entity *rt_se)
 {
        struct rt_rq *rt_rq = rt_rq_of_se(rt_se);
        struct rt_prio_array *array = &rt_rq->active;
@@ -480,11 +486,10 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se)
  * Because the prio of an upper entry depends on the lower
  * entries, we must remove entries top - down.
  */
-static void dequeue_rt_stack(struct task_struct *p)
+static void dequeue_rt_stack(struct sched_rt_entity *rt_se)
 {
-       struct sched_rt_entity *rt_se, *back = NULL;
+       struct sched_rt_entity *back = NULL;
 
-       rt_se = &p->rt;
        for_each_sched_rt_entity(rt_se) {
                rt_se->back = back;
                back = rt_se;
@@ -492,7 +497,26 @@ static void dequeue_rt_stack(struct task_struct *p)
 
        for (rt_se = back; rt_se; rt_se = rt_se->back) {
                if (on_rt_rq(rt_se))
-                       dequeue_rt_entity(rt_se);
+                       __dequeue_rt_entity(rt_se);
+       }
+}
+
+static void enqueue_rt_entity(struct sched_rt_entity *rt_se)
+{
+       dequeue_rt_stack(rt_se);
+       for_each_sched_rt_entity(rt_se)
+               __enqueue_rt_entity(rt_se);
+}
+
+static void dequeue_rt_entity(struct sched_rt_entity *rt_se)
+{
+       dequeue_rt_stack(rt_se);
+
+       for_each_sched_rt_entity(rt_se) {
+               struct rt_rq *rt_rq = group_rt_rq(rt_se);
+
+               if (rt_rq && rt_rq->rt_nr_running)
+                       __enqueue_rt_entity(rt_se);
        }
 }
 
@@ -506,32 +530,15 @@ static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup)
        if (wakeup)
                rt_se->timeout = 0;
 
-       dequeue_rt_stack(p);
-
-       /*
-        * enqueue everybody, bottom - up.
-        */
-       for_each_sched_rt_entity(rt_se)
-               enqueue_rt_entity(rt_se);
+       enqueue_rt_entity(rt_se);
 }
 
 static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep)
 {
        struct sched_rt_entity *rt_se = &p->rt;
-       struct rt_rq *rt_rq;
 
        update_curr_rt(rq);
-
-       dequeue_rt_stack(p);
-
-       /*
-        * re-enqueue all non-empty rt_rq entities.
-        */
-       for_each_sched_rt_entity(rt_se) {
-               rt_rq = group_rt_rq(rt_se);
-               if (rt_rq && rt_rq->rt_nr_running)
-                       enqueue_rt_entity(rt_se);
-       }
+       dequeue_rt_entity(rt_se);
 }
 
 /*
@@ -542,8 +549,10 @@ static
 void requeue_rt_entity(struct rt_rq *rt_rq, struct sched_rt_entity *rt_se)
 {
        struct rt_prio_array *array = &rt_rq->active;
+       struct list_head *queue = array->queue + rt_se_prio(rt_se);
 
-       list_move_tail(&rt_se->run_list, array->queue + rt_se_prio(rt_se));
+       if (on_rt_rq(rt_se))
+               list_move_tail(&rt_se->run_list, queue);
 }
 
 static void requeue_task_rt(struct rq *rq, struct task_struct *p)
index a38878e..80179ef 100644 (file)
@@ -198,6 +198,9 @@ static inline void sched_info_queued(struct task_struct *t)
 /*
  * Called when a process ceases being the active-running process, either
  * voluntarily or involuntarily.  Now we can calculate how long we ran.
+ * Also, if the process is still in the TASK_RUNNING state, call
+ * sched_info_queued() to mark that it has now again started waiting on
+ * the runqueue.
  */
 static inline void sched_info_depart(struct task_struct *t)
 {
@@ -206,6 +209,9 @@ static inline void sched_info_depart(struct task_struct *t)
 
        t->sched_info.cpu_time += delta;
        rq_sched_info_depart(task_rq(t), delta);
+
+       if (t->state == TASK_RUNNING)
+               sched_info_queued(t);
 }
 
 /*
index 19e0ae9..9aefaae 100644 (file)
@@ -999,17 +999,15 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
                goto no_page_table;
 
        ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
-       if (!ptep)
-               goto out;
 
        pte = *ptep;
        if (!pte_present(pte))
-               goto unlock;
+               goto no_page;
        if ((flags & FOLL_WRITE) && !pte_write(pte))
                goto unlock;
        page = vm_normal_page(vma, address, pte);
        if (unlikely(!page))
-               goto unlock;
+               goto bad_page;
 
        if (flags & FOLL_GET)
                get_page(page);
@@ -1024,6 +1022,15 @@ unlock:
 out:
        return page;
 
+bad_page:
+       pte_unmap_unlock(ptep, ptl);
+       return ERR_PTR(-EFAULT);
+
+no_page:
+       pte_unmap_unlock(ptep, ptl);
+       if (!pte_none(pte))
+               return page;
+       /* Fall through to ZERO_PAGE handling */
 no_page_table:
        /*
         * When core dumping an enormous anonymous area that nobody
@@ -1159,6 +1166,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 
                                cond_resched();
                        }
+                       if (IS_ERR(page))
+                               return i ? i : PTR_ERR(page);
                        if (pages) {
                                pages[i] = page;
 
index 449d77d..112bcae 100644 (file)
@@ -865,6 +865,11 @@ static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm,
                        goto set_status;
 
                page = follow_page(vma, pp->addr, FOLL_GET);
+
+               err = PTR_ERR(page);
+               if (IS_ERR(page))
+                       goto set_status;
+
                err = -ENOENT;
                if (!page)
                        goto set_status;
@@ -928,6 +933,11 @@ static int do_pages_stat(struct mm_struct *mm, struct page_to_node *pm)
                        goto set_status;
 
                page = follow_page(vma, pm->addr, 0);
+
+               err = PTR_ERR(page);
+               if (IS_ERR(page))
+                       goto set_status;
+
                err = -ENOENT;
                /* Use PageReserved to check for zero page */
                if (!page || PageReserved(page))