Merge branch 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 2 Apr 2007 18:41:55 +0000 (11:41 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Mon, 2 Apr 2007 18:41:55 +0000 (11:41 -0700)
* 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6:
  [PATCH] x86: Don't probe for DDC on VBE1.2
  [PATCH] x86-64: Increase NMI watchdog probing timeout
  [PATCH] x86-64: Let oprofile reserve MSR on all CPUs
  [PATCH] x86-64: Disable local APIC timer use on AMD systems with C1E

20 files changed:
Documentation/cpusets.txt
arch/i386/kernel/microcode.c
arch/i386/lib/usercopy.c
arch/um/sys-i386/delay.c
arch/um/sys-x86_64/delay.c
drivers/char/vt_ioctl.c
drivers/mfd/sm501.c
drivers/pnp/system.c
drivers/rtc/rtc-cmos.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/ext3/inode.c
fs/ext4/inode.c
fs/proc/internal.h
fs/proc/root.c
include/asm-um/delay.h
include/linux/cpu.h
include/linux/device.h
kernel/cpu.c
kernel/module.c

index 842f0d1..f2c0a68 100644 (file)
@@ -557,6 +557,9 @@ Set some flags:
 Add some cpus:
 # /bin/echo 0-7 > cpus
 
+Add some mems:
+# /bin/echo 0-7 > mems
+
 Now attach your shell to this cpuset:
 # /bin/echo $$ > tasks
 
index b8f1663..cbe7ec8 100644 (file)
@@ -567,6 +567,53 @@ static int cpu_request_microcode(int cpu)
        return error;
 }
 
+static int apply_microcode_on_cpu(int cpu)
+{
+       struct cpuinfo_x86 *c = cpu_data + cpu;
+       struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+       cpumask_t old;
+       unsigned int val[2];
+       int err = 0;
+
+       if (!uci->mc)
+               return -EINVAL;
+
+       old = current->cpus_allowed;
+       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+
+       /* Check if the microcode we have in memory matches the CPU */
+       if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
+           cpu_has(c, X86_FEATURE_IA64) || uci->sig != cpuid_eax(0x00000001))
+               err = -EINVAL;
+
+       if (!err && ((c->x86_model >= 5) || (c->x86 > 6))) {
+               /* get processor flags from MSR 0x17 */
+               rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
+               if (uci->pf != (1 << ((val[1] >> 18) & 7)))
+                       err = -EINVAL;
+       }
+
+       if (!err) {
+               wrmsr(MSR_IA32_UCODE_REV, 0, 0);
+               /* see notes above for revision 1.07.  Apparent chip bug */
+               sync_core();
+               /* get the current revision from MSR 0x8B */
+               rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
+               if (uci->rev != val[1])
+                       err = -EINVAL;
+       }
+
+       if (!err)
+               apply_microcode(cpu);
+       else
+               printk(KERN_ERR "microcode: Could not apply microcode to CPU%d:"
+                       " sig=0x%x, pf=0x%x, rev=0x%x\n",
+                       cpu, uci->sig, uci->pf, uci->rev);
+
+       set_cpus_allowed(current, old);
+       return err;
+}
+
 static void microcode_init_cpu(int cpu)
 {
        cpumask_t old;
@@ -577,7 +624,8 @@ static void microcode_init_cpu(int cpu)
        set_cpus_allowed(current, cpumask_of_cpu(cpu));
        mutex_lock(&microcode_mutex);
        collect_cpu_info(cpu);
-       if (uci->valid && system_state == SYSTEM_RUNNING)
+       if (uci->valid && system_state == SYSTEM_RUNNING &&
+           !suspend_cpu_hotplug)
                cpu_request_microcode(cpu);
        mutex_unlock(&microcode_mutex);
        set_cpus_allowed(current, old);
@@ -663,13 +711,24 @@ static int mc_sysdev_add(struct sys_device *sys_dev)
                return 0;
 
        pr_debug("Microcode:CPU %d added\n", cpu);
-       memset(uci, 0, sizeof(*uci));
+       /* If suspend_cpu_hotplug is set, the system is resuming and we should
+        * use the data from before the suspend.
+        */
+       if (suspend_cpu_hotplug) {
+               err = apply_microcode_on_cpu(cpu);
+               if (err)
+                       microcode_fini_cpu(cpu);
+       }
+       if (!uci->valid)
+               memset(uci, 0, sizeof(*uci));
 
        err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
        if (err)
                return err;
 
-       microcode_init_cpu(cpu);
+       if (!uci->valid)
+               microcode_init_cpu(cpu);
+
        return 0;
 }
 
@@ -680,7 +739,11 @@ static int mc_sysdev_remove(struct sys_device *sys_dev)
        if (!cpu_online(cpu))
                return 0;
        pr_debug("Microcode:CPU %d removed\n", cpu);
-       microcode_fini_cpu(cpu);
+       /* If suspend_cpu_hotplug is set, the system is suspending and we should
+        * keep the microcode in memory for the resume.
+        */
+       if (!suspend_cpu_hotplug)
+               microcode_fini_cpu(cpu);
        sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
        return 0;
 }
index d22cfc9..086b372 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/blkdev.h>
 #include <linux/module.h>
 #include <linux/backing-dev.h>
+#include <linux/interrupt.h>
 #include <asm/uaccess.h>
 #include <asm/mmx.h>
 
@@ -719,6 +720,14 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from,
 #ifndef CONFIG_X86_WP_WORKS_OK
        if (unlikely(boot_cpu_data.wp_works_ok == 0) &&
                        ((unsigned long )to) < TASK_SIZE) {
+               /*
+                * When we are in an atomic section (see
+                * mm/filemap.c:file_read_actor), return the full
+                * length to take the slow path.
+                */
+               if (in_atomic())
+                       return n;
+
                /* 
                 * CPU does not honor the WP bit when writing
                 * from supervisory mode, and due to preemption or SMP,
index 2c11b97..d623e07 100644 (file)
@@ -27,14 +27,3 @@ void __udelay(unsigned long usecs)
 }
 
 EXPORT_SYMBOL(__udelay);
-
-void __const_udelay(unsigned long usecs)
-{
-       int i, n;
-
-       n = (loops_per_jiffy * HZ * usecs) / MILLION;
-        for(i=0;i<n;i++)
-                cpu_relax();
-}
-
-EXPORT_SYMBOL(__const_udelay);
index 137f444..dee5be6 100644 (file)
@@ -28,14 +28,3 @@ void __udelay(unsigned long usecs)
 }
 
 EXPORT_SYMBOL(__udelay);
-
-void __const_udelay(unsigned long usecs)
-{
-       unsigned long i, n;
-
-       n = (loops_per_jiffy * HZ * usecs) / MILLION;
-        for(i=0;i<n;i++)
-                cpu_relax();
-}
-
-EXPORT_SYMBOL(__const_udelay);
index 1fa2da8..c9f2dd6 100644 (file)
@@ -1039,10 +1039,22 @@ int vt_waitactive(int vt)
 
        add_wait_queue(&vt_activate_queue, &wait);
        for (;;) {
-               set_current_state(TASK_INTERRUPTIBLE);
                retval = 0;
-               if (vt == fg_console)
+
+               /*
+                * Synchronize with redraw_screen(). By acquiring the console
+                * semaphore we make sure that the console switch is completed
+                * before we return. If we didn't wait for the semaphore, we
+                * could return at a point where fg_console has already been
+                * updated, but the console switch hasn't been completed.
+                */
+               acquire_console_sem();
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (vt == fg_console) {
+                       release_console_sem();
                        break;
+               }
+               release_console_sem();
                retval = -EINTR;
                if (signal_pending(current))
                        break;
index c707c8e..b0b4458 100644 (file)
@@ -319,7 +319,7 @@ int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
 
        mode &= 3;              /* get current power mode */
 
-       if (unit > ARRAY_SIZE(sm->unit_power)) {
+       if (unit >= ARRAY_SIZE(sm->unit_power)) {
                dev_err(dev, "%s: bad unit %d\n", __FUNCTION__, unit);
                goto already;
        }
index 2065e74..a8a9554 100644 (file)
@@ -22,7 +22,7 @@ static const struct pnp_device_id pnp_dev_table[] = {
        {       "",                     0       }
 };
 
-static void reserve_range(char *pnpid, int start, int end, int port)
+static void reserve_range(const char *pnpid, resource_size_t start, resource_size_t end, int port)
 {
        struct resource *res;
        char *regionid;
@@ -32,9 +32,9 @@ static void reserve_range(char *pnpid, int start, int end, int port)
                return;
        snprintf(regionid, 16, "pnp %s", pnpid);
        if (port)
-               res = request_region(start,end-start+1,regionid);
+               res = request_region(start, end-start+1, regionid);
        else
-               res = request_mem_region(start,end-start+1,regionid);
+               res = request_mem_region(start, end-start+1, regionid);
        if (res == NULL)
                kfree(regionid);
        else
@@ -45,12 +45,13 @@ static void reserve_range(char *pnpid, int start, int end, int port)
         * have double reservations.
         */
        printk(KERN_INFO
-               "pnp: %s: %s range 0x%x-0x%x %s reserved\n",
-               pnpid, port ? "ioport" : "iomem", start, end,
+               "pnp: %s: %s range 0x%llx-0x%llx %s reserved\n",
+               pnpid, port ? "ioport" : "iomem",
+                (unsigned long long)start, (unsigned long long)end,
                NULL != res ? "has been" : "could not be");
 }
 
-static void reserve_resources_of_dev(struct pnp_dev *dev)
+static void reserve_resources_of_dev(const struct pnp_dev *dev)
 {
        int i;
 
index 85bf795..7c0d609 100644 (file)
@@ -59,6 +59,19 @@ struct cmos_rtc {
 
 static const char driver_name[] = "rtc_cmos";
 
+/* The RTC_INTR register may have e.g. RTC_PF set even if RTC_PIE is clear;
+ * always mask it against the irq enable bits in RTC_CONTROL.  Bit values
+ * are the same: PF==PIE, AF=AIE, UF=UIE; so RTC_IRQMASK works with both.
+ */
+#define        RTC_IRQMASK     (RTC_PF | RTC_AF | RTC_UF)
+
+static inline int is_intr(u8 rtc_intr)
+{
+       if (!(rtc_intr & RTC_IRQF))
+               return 0;
+       return rtc_intr & RTC_IRQMASK;
+}
+
 /*----------------------------------------------------------------*/
 
 static int cmos_read_time(struct device *dev, struct rtc_time *t)
@@ -188,7 +201,8 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
        rtc_control &= ~RTC_AIE;
        CMOS_WRITE(rtc_control, RTC_CONTROL);
        rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
-       if (rtc_intr)
+       rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
+       if (is_intr(rtc_intr))
                rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
 
        /* update alarm */
@@ -207,7 +221,8 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
                rtc_control |= RTC_AIE;
                CMOS_WRITE(rtc_control, RTC_CONTROL);
                rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
-               if (rtc_intr)
+               rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
+               if (is_intr(rtc_intr))
                        rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
        }
 
@@ -287,7 +302,8 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
        }
        CMOS_WRITE(rtc_control, RTC_CONTROL);
        rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
-       if (rtc_intr)
+       rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
+       if (is_intr(rtc_intr))
                rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
        spin_unlock_irqrestore(&rtc_lock, flags);
        return 0;
@@ -353,12 +369,10 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
 
        spin_lock(&rtc_lock);
        irqstat = CMOS_READ(RTC_INTR_FLAGS);
+       irqstat &= (CMOS_READ(RTC_CONTROL) & RTC_IRQMASK) | RTC_IRQF;
        spin_unlock(&rtc_lock);
 
-       if (irqstat) {
-               /* NOTE: irqstat may have e.g. RTC_PF set
-                * even when RTC_PIE is clear...
-                */
+       if (is_intr(irqstat)) {
                rtc_update_irq(p, 1, irqstat);
                return IRQ_HANDLED;
        } else
@@ -525,25 +539,26 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)
 {
        struct cmos_rtc *cmos = dev_get_drvdata(dev);
        int             do_wake = device_may_wakeup(dev);
-       unsigned char   tmp, irqstat;
+       unsigned char   tmp;
 
        /* only the alarm might be a wakeup event source */
        spin_lock_irq(&rtc_lock);
        cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL);
        if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) {
+               unsigned char   irqstat;
+
                if (do_wake)
                        tmp &= ~(RTC_PIE|RTC_UIE);
                else
                        tmp &= ~(RTC_PIE|RTC_AIE|RTC_UIE);
                CMOS_WRITE(tmp, RTC_CONTROL);
                irqstat = CMOS_READ(RTC_INTR_FLAGS);
-       } else
-               irqstat = 0;
+               irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF;
+               if (is_intr(irqstat))
+                       rtc_update_irq(&cmos->rtc->class_dev, 1, irqstat);
+       }
        spin_unlock_irq(&rtc_lock);
 
-       if (irqstat)
-               rtc_update_irq(&cmos->rtc->class_dev, 1, irqstat);
-
        /* ACPI HOOK:  enable ACPI_EVENT_RTC when (tmp & RTC_AIE)
         * ... it'd be best if we could do that under rtc_lock.
         */
@@ -573,9 +588,10 @@ static int cmos_resume(struct device *dev)
                spin_lock_irq(&rtc_lock);
                CMOS_WRITE(tmp, RTC_CONTROL);
                tmp = CMOS_READ(RTC_INTR_FLAGS);
-               spin_unlock_irq(&rtc_lock);
-               if (tmp)
+               tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF;
+               if (is_intr(tmp))
                        rtc_update_irq(&cmos->rtc->class_dev, 1, tmp);
+               spin_unlock_irq(&rtc_lock);
        }
 
        pr_debug("%s: resume, ctrl %02x\n",
@@ -594,7 +610,7 @@ static int cmos_resume(struct device *dev)
 /*----------------------------------------------------------------*/
 
 /* The "CMOS" RTC normally lives on the platform_bus.  On ACPI systems,
- * the device node may alternatively be created as a PNP device.
+ * the device node will always be created as a PNPACPI device.
  */
 
 #ifdef CONFIG_PNPACPI
@@ -673,7 +689,7 @@ module_exit(cmos_exit);
 /*----------------------------------------------------------------*/
 
 /* Platform setup should have set up an RTC device, when PNPACPI is
- * unavailable ... this is the normal case, common even on PCs.
+ * unavailable ... this could happen even on (older) PCs.
  */
 
 static int __init cmos_platform_probe(struct platform_device *pdev)
index a2fceba..9cc4f0a 100644 (file)
@@ -1704,7 +1704,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
                                DUMP_SEEK(PAGE_SIZE);
                        } else {
                                if (page == ZERO_PAGE(addr)) {
-                                       DUMP_SEEK(PAGE_SIZE);
+                                       if (!dump_seek(file, PAGE_SIZE)) {
+                                               page_cache_release(page);
+                                               goto end_coredump;
+                                       }
                                } else {
                                        void *kaddr;
                                        flush_cache_page(vma, addr,
index 47d6d49..f3ddca4 100644 (file)
@@ -1480,8 +1480,8 @@ static int elf_fdpic_dump_segments(struct file *file, struct mm_struct *mm,
                                DUMP_SEEK(file->f_pos + PAGE_SIZE);
                        }
                        else if (page == ZERO_PAGE(addr)) {
-                               DUMP_SEEK(file->f_pos + PAGE_SIZE);
                                page_cache_release(page);
+                               DUMP_SEEK(file->f_pos + PAGE_SIZE);
                        }
                        else {
                                void *kaddr;
index 8a824f4..a5b150f 100644 (file)
@@ -1148,102 +1148,37 @@ static int do_journal_get_write_access(handle_t *handle,
        return ext3_journal_get_write_access(handle, bh);
 }
 
-/*
- * The idea of this helper function is following:
- * if prepare_write has allocated some blocks, but not all of them, the
- * transaction must include the content of the newly allocated blocks.
- * This content is expected to be set to zeroes by block_prepare_write().
- * 2006/10/14  SAW
- */
-static int ext3_prepare_failure(struct file *file, struct page *page,
-                               unsigned from, unsigned to)
-{
-       struct address_space *mapping;
-       struct buffer_head *bh, *head, *next;
-       unsigned block_start, block_end;
-       unsigned blocksize;
-       int ret;
-       handle_t *handle = ext3_journal_current_handle();
-
-       mapping = page->mapping;
-       if (ext3_should_writeback_data(mapping->host)) {
-               /* optimization: no constraints about data */
-skip:
-               return ext3_journal_stop(handle);
-       }
-
-       head = page_buffers(page);
-       blocksize = head->b_size;
-       for (   bh = head, block_start = 0;
-               bh != head || !block_start;
-               block_start = block_end, bh = next)
-       {
-               next = bh->b_this_page;
-               block_end = block_start + blocksize;
-               if (block_end <= from)
-                       continue;
-               if (block_start >= to) {
-                       block_start = to;
-                       break;
-               }
-               if (!buffer_mapped(bh))
-               /* prepare_write failed on this bh */
-                       break;
-               if (ext3_should_journal_data(mapping->host)) {
-                       ret = do_journal_get_write_access(handle, bh);
-                       if (ret) {
-                               ext3_journal_stop(handle);
-                               return ret;
-                       }
-               }
-       /*
-        * block_start here becomes the first block where the current iteration
-        * of prepare_write failed.
-        */
-       }
-       if (block_start <= from)
-               goto skip;
-
-       /* commit allocated and zeroed buffers */
-       return mapping->a_ops->commit_write(file, page, from, block_start);
-}
-
 static int ext3_prepare_write(struct file *file, struct page *page,
                              unsigned from, unsigned to)
 {
        struct inode *inode = page->mapping->host;
-       int ret, ret2;
-       int needed_blocks = ext3_writepage_trans_blocks(inode);
+       int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
        handle_t *handle;
        int retries = 0;
 
 retry:
        handle = ext3_journal_start(inode, needed_blocks);
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+               goto out;
+       }
        if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode))
                ret = nobh_prepare_write(page, from, to, ext3_get_block);
        else
                ret = block_prepare_write(page, from, to, ext3_get_block);
        if (ret)
-               goto failure;
+               goto prepare_write_failed;
 
        if (ext3_should_journal_data(inode)) {
                ret = walk_page_buffers(handle, page_buffers(page),
                                from, to, NULL, do_journal_get_write_access);
-               if (ret)
-                       /* fatal error, just put the handle and return */
-                       journal_stop(handle);
        }
-       return ret;
-
-failure:
-       ret2 = ext3_prepare_failure(file, page, from, to);
-       if (ret2 < 0)
-               return ret2;
+prepare_write_failed:
+       if (ret)
+               ext3_journal_stop(handle);
        if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
                goto retry;
-       /* retry number exceeded, or other error like -EDQUOT */
+out:
        return ret;
 }
 
index fbff4b9..810b6d6 100644 (file)
@@ -1147,102 +1147,37 @@ static int do_journal_get_write_access(handle_t *handle,
        return ext4_journal_get_write_access(handle, bh);
 }
 
-/*
- * The idea of this helper function is following:
- * if prepare_write has allocated some blocks, but not all of them, the
- * transaction must include the content of the newly allocated blocks.
- * This content is expected to be set to zeroes by block_prepare_write().
- * 2006/10/14  SAW
- */
-static int ext4_prepare_failure(struct file *file, struct page *page,
-                               unsigned from, unsigned to)
-{
-       struct address_space *mapping;
-       struct buffer_head *bh, *head, *next;
-       unsigned block_start, block_end;
-       unsigned blocksize;
-       int ret;
-       handle_t *handle = ext4_journal_current_handle();
-
-       mapping = page->mapping;
-       if (ext4_should_writeback_data(mapping->host)) {
-               /* optimization: no constraints about data */
-skip:
-               return ext4_journal_stop(handle);
-       }
-
-       head = page_buffers(page);
-       blocksize = head->b_size;
-       for (   bh = head, block_start = 0;
-               bh != head || !block_start;
-               block_start = block_end, bh = next)
-       {
-               next = bh->b_this_page;
-               block_end = block_start + blocksize;
-               if (block_end <= from)
-                       continue;
-               if (block_start >= to) {
-                       block_start = to;
-                       break;
-               }
-               if (!buffer_mapped(bh))
-               /* prepare_write failed on this bh */
-                       break;
-               if (ext4_should_journal_data(mapping->host)) {
-                       ret = do_journal_get_write_access(handle, bh);
-                       if (ret) {
-                               ext4_journal_stop(handle);
-                               return ret;
-                       }
-               }
-       /*
-        * block_start here becomes the first block where the current iteration
-        * of prepare_write failed.
-        */
-       }
-       if (block_start <= from)
-               goto skip;
-
-       /* commit allocated and zeroed buffers */
-       return mapping->a_ops->commit_write(file, page, from, block_start);
-}
-
 static int ext4_prepare_write(struct file *file, struct page *page,
                              unsigned from, unsigned to)
 {
        struct inode *inode = page->mapping->host;
-       int ret, ret2;
-       int needed_blocks = ext4_writepage_trans_blocks(inode);
+       int ret, needed_blocks = ext4_writepage_trans_blocks(inode);
        handle_t *handle;
        int retries = 0;
 
 retry:
        handle = ext4_journal_start(inode, needed_blocks);
-       if (IS_ERR(handle))
-               return PTR_ERR(handle);
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+               goto out;
+       }
        if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
                ret = nobh_prepare_write(page, from, to, ext4_get_block);
        else
                ret = block_prepare_write(page, from, to, ext4_get_block);
        if (ret)
-               goto failure;
+               goto prepare_write_failed;
 
        if (ext4_should_journal_data(inode)) {
                ret = walk_page_buffers(handle, page_buffers(page),
                                from, to, NULL, do_journal_get_write_access);
-               if (ret)
-                       /* fatal error, just put the handle and return */
-                       ext4_journal_stop(handle);
        }
-       return ret;
-
-failure:
-       ret2 = ext4_prepare_failure(file, page, from, to);
-       if (ret2 < 0)
-               return ret2;
+prepare_write_failed:
+       if (ret)
+               ext4_journal_stop(handle);
        if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
                goto retry;
-       /* retry number exceeded, or other error like -EDQUOT */
+out:
        return ret;
 }
 
index c932aa6..f771889 100644 (file)
 
 #include <linux/proc_fs.h>
 
+#ifdef CONFIG_PROC_SYSCTL
 extern int proc_sys_init(void);
+#else
+static inline void proc_sys_init(void) { }
+#endif
 
 struct vmalloc_info {
        unsigned long   used;
index 5834a74..41f1703 100644 (file)
@@ -79,9 +79,7 @@ void __init proc_root_init(void)
        proc_device_tree_init();
 #endif
        proc_bus = proc_mkdir("bus", NULL);
-#ifdef CONFIG_SYSCTL
        proc_sys_init();
-#endif
 }
 
 static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
index 0985bda..c71e32b 100644 (file)
@@ -1,9 +1,20 @@
 #ifndef __UM_DELAY_H
 #define __UM_DELAY_H
 
-#include "asm/arch/delay.h"
-#include "asm/archparam.h"
-
 #define MILLION 1000000
 
+/* Undefined on purpose */
+extern void __bad_udelay(void);
+
+extern void __udelay(unsigned long usecs);
+extern void __delay(unsigned long loops);
+
+#define udelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \
+       __bad_udelay() : __udelay(n))
+
+/* It appears that ndelay is not used at all for UML, and has never been
+ * implemented. */
+extern void __unimplemented_ndelay(void);
+#define ndelay(n) __unimplemented_ndelay()
+
 #endif
index 769ddc6..c22b0df 100644 (file)
@@ -127,9 +127,13 @@ static inline int cpu_is_offline(int cpu) { return 0; }
 #endif         /* CONFIG_HOTPLUG_CPU */
 
 #ifdef CONFIG_SUSPEND_SMP
+extern int suspend_cpu_hotplug;
+
 extern int disable_nonboot_cpus(void);
 extern void enable_nonboot_cpus(void);
 #else
+#define suspend_cpu_hotplug    0
+
 static inline int disable_nonboot_cpus(void) { return 0; }
 static inline void enable_nonboot_cpus(void) {}
 #endif
index caad9bb..5cf30e9 100644 (file)
@@ -128,6 +128,7 @@ struct device_driver {
 
        struct module           * owner;
        const char              * mod_name;     /* used for built-in modules */
+       struct module_kobject   * mkobj;
 
        int     (*probe)        (struct device * dev);
        int     (*remove)       (struct device * dev);
index 3d4206a..36e7084 100644 (file)
@@ -254,6 +254,12 @@ int __cpuinit cpu_up(unsigned int cpu)
 }
 
 #ifdef CONFIG_SUSPEND_SMP
+/* Needed to prevent the microcode driver from requesting firmware in its CPU
+ * hotplug notifier during the suspend/resume.
+ */
+int suspend_cpu_hotplug;
+EXPORT_SYMBOL(suspend_cpu_hotplug);
+
 static cpumask_t frozen_cpus;
 
 int disable_nonboot_cpus(void)
@@ -261,16 +267,8 @@ int disable_nonboot_cpus(void)
        int cpu, first_cpu, error = 0;
 
        mutex_lock(&cpu_add_remove_lock);
-       first_cpu = first_cpu(cpu_present_map);
-       if (!cpu_online(first_cpu)) {
-               error = _cpu_up(first_cpu);
-               if (error) {
-                       printk(KERN_ERR "Could not bring CPU%d up.\n",
-                               first_cpu);
-                       goto out;
-               }
-       }
-
+       suspend_cpu_hotplug = 1;
+       first_cpu = first_cpu(cpu_online_map);
        /* We take down all of the non-boot CPUs in one shot to avoid races
         * with the userspace trying to use the CPU hotplug at the same time
         */
@@ -296,7 +294,7 @@ int disable_nonboot_cpus(void)
        } else {
                printk(KERN_ERR "Non-boot CPUs are not disabled\n");
        }
-out:
+       suspend_cpu_hotplug = 0;
        mutex_unlock(&cpu_add_remove_lock);
        return error;
 }
@@ -308,20 +306,22 @@ void enable_nonboot_cpus(void)
        /* Allow everyone to use the CPU hotplug again */
        mutex_lock(&cpu_add_remove_lock);
        cpu_hotplug_disabled = 0;
-       mutex_unlock(&cpu_add_remove_lock);
        if (cpus_empty(frozen_cpus))
-               return;
+               goto out;
 
+       suspend_cpu_hotplug = 1;
        printk("Enabling non-boot CPUs ...\n");
        for_each_cpu_mask(cpu, frozen_cpus) {
-               error = cpu_up(cpu);
+               error = _cpu_up(cpu);
                if (!error) {
                        printk("CPU%d is up\n", cpu);
                        continue;
                }
-               printk(KERN_WARNING "Error taking CPU%d up: %d\n",
-                       cpu, error);
+               printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error);
        }
        cpus_clear(frozen_cpus);
+       suspend_cpu_hotplug = 0;
+out:
+       mutex_unlock(&cpu_add_remove_lock);
 }
 #endif
index fbc51de..dcdb32b 100644 (file)
@@ -2384,8 +2384,13 @@ void module_add_driver(struct module *mod, struct device_driver *drv)
 
                /* Lookup built-in module entry in /sys/modules */
                mkobj = kset_find_obj(&module_subsys.kset, drv->mod_name);
-               if (mkobj)
+               if (mkobj) {
                        mk = container_of(mkobj, struct module_kobject, kobj);
+                       /* remember our module structure */
+                       drv->mkobj = mk;
+                       /* kset_find_obj took a reference */
+                       kobject_put(mkobj);
+               }
        }
 
        if (!mk)
@@ -2405,17 +2410,22 @@ EXPORT_SYMBOL(module_add_driver);
 
 void module_remove_driver(struct device_driver *drv)
 {
+       struct module_kobject *mk = NULL;
        char *driver_name;
 
        if (!drv)
                return;
 
        sysfs_remove_link(&drv->kobj, "module");
-       if (drv->owner && drv->owner->mkobj.drivers_dir) {
+
+       if (drv->owner)
+               mk = &drv->owner->mkobj;
+       else if (drv->mkobj)
+               mk = drv->mkobj;
+       if (mk && mk->drivers_dir) {
                driver_name = make_driver_name(drv);
                if (driver_name) {
-                       sysfs_remove_link(drv->owner->mkobj.drivers_dir,
-                                         driver_name);
+                       sysfs_remove_link(mk->drivers_dir, driver_name);
                        kfree(driver_name);
                }
        }