]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/commitdiff
Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 6 Dec 2012 16:27:11 +0000 (08:27 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 6 Dec 2012 16:27:11 +0000 (08:27 -0800)
Pull watchdog fix from Thomas Gleixner:
 "Trivial CPU hotplug regression fix for the watchdog code"

* 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  watchdog: Fix CPU hotplug regression

arch/sparc/boot/piggyback.c
arch/sparc/kernel/sys32.S
arch/sparc/kernel/syscalls.S
arch/sparc/kernel/systbls_64.S
drivers/mtd/ubi/wl.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c
fs/buffer.c
include/linux/kernel.h
kernel/modsign_pubkey.c
kernel/workqueue.c

index c0a798fcf030ab7903d0508d0202d1a813cb52ca..bb7c95161d7188f5defd780ddec934b0395b48b0 100644 (file)
@@ -81,18 +81,18 @@ static void usage(void)
 
 static int start_line(const char *line)
 {
-       if (strcmp(line + 8, " T _start\n") == 0)
+       if (strcmp(line + 10, " _start\n") == 0)
                return 1;
-       else if (strcmp(line + 16, " T _start\n") == 0)
+       else if (strcmp(line + 18, " _start\n") == 0)
                return 1;
        return 0;
 }
 
 static int end_line(const char *line)
 {
-       if (strcmp(line + 8, " A _end\n") == 0)
+       if (strcmp(line + 10, " _end\n") == 0)
                return 1;
-       else if (strcmp (line + 16, " A _end\n") == 0)
+       else if (strcmp (line + 18, " _end\n") == 0)
                return 1;
        return 0;
 }
@@ -100,8 +100,8 @@ static int end_line(const char *line)
 /*
  * Find address for start and end in System.map.
  * The file looks like this:
- * f0004000 T _start
- * f0379f79 A _end
+ * f0004000 ... _start
+ * f0379f79 ... _end
  * 1234567890123456
  * ^coloumn 1
  * There is support for 64 bit addresses too.
index 44025f4ba41f883d61647f180575651ee5113645..8475a474273ae1c615ce4277dd3bf74ba1ce9f0a 100644 (file)
@@ -47,7 +47,7 @@ STUB: sra     REG1, 0, REG1; \
        sra     REG4, 0, REG4
 
 SIGN1(sys32_exit, sparc_exit, %o0)
-SIGN1(sys32_exit_group, sys_exit_group, %o0)
+SIGN1(sys32_exit_group, sparc_exit_group, %o0)
 SIGN1(sys32_wait4, compat_sys_wait4, %o2)
 SIGN1(sys32_creat, sys_creat, %o1)
 SIGN1(sys32_mknod, sys_mknod, %o1)
index 7f5f65d0b3fde92235c838bd976916bc863d0315..bf2347794e3323c3220c92e4a96849d8c89d5fbf 100644 (file)
@@ -118,10 +118,20 @@ ret_from_syscall:
        ba,pt   %xcc, ret_sys_call
         ldx    [%sp + PTREGS_OFF + PT_V9_I0], %o0
 
+       .globl  sparc_exit_group
+       .type   sparc_exit_group,#function
+sparc_exit_group:
+       sethi   %hi(sys_exit_group), %g7
+       ba,pt   %xcc, 1f
+        or     %g7, %lo(sys_exit_group), %g7
+       .size   sparc_exit_group,.-sparc_exit_group
+
        .globl  sparc_exit
        .type   sparc_exit,#function
 sparc_exit:
-       rdpr    %pstate, %g2
+       sethi   %hi(sys_exit), %g7
+       or      %g7, %lo(sys_exit), %g7
+1:     rdpr    %pstate, %g2
        wrpr    %g2, PSTATE_IE, %pstate
        rdpr    %otherwin, %g1
        rdpr    %cansave, %g3
@@ -129,7 +139,7 @@ sparc_exit:
        wrpr    %g3, 0x0, %cansave
        wrpr    %g0, 0x0, %otherwin
        wrpr    %g2, 0x0, %pstate
-       ba,pt   %xcc, sys_exit
+       jmpl    %g7, %g0
         stb    %g0, [%g6 + TI_WSAVED]
        .size   sparc_exit,.-sparc_exit
 
index 1c9af9fa38e9b0b489cb38899685e4c4c76b6584..017b74a63dcb995dd9c18049bd1a1604d329fea5 100644 (file)
@@ -133,7 +133,7 @@ sys_call_table:
 /*170*/        .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
        .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
 /*180*/        .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall
-       .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname
+       .word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname
 /*190*/        .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
        .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask
 /*200*/        .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
index da7b44998b402866643ef824055d6ed3916bcf4f..2144f611196e3188bd3983ea5e084dd4bafd47ff 100644 (file)
@@ -498,7 +498,7 @@ out:
  * @ubi: UBI device description object
  *
  * This function returns a physical eraseblock in case of success and a
- * negative error code in case of failure. Might sleep.
+ * negative error code in case of failure.
  */
 static int __wl_get_peb(struct ubi_device *ubi)
 {
@@ -540,13 +540,6 @@ retry:
         * ubi_wl_get_peb() after removing e from the pool. */
        prot_queue_add(ubi, e);
 #endif
-       err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset,
-                                   ubi->peb_size - ubi->vid_hdr_aloffset);
-       if (err) {
-               ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum);
-               return err;
-       }
-
        return e->pnum;
 }
 
@@ -679,17 +672,30 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
 #else
 static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
 {
-       return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+       struct ubi_wl_entry *e;
+
+       e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+       self_check_in_wl_tree(ubi, e, &ubi->free);
+       rb_erase(&e->u.rb, &ubi->free);
+
+       return e;
 }
 
 int ubi_wl_get_peb(struct ubi_device *ubi)
 {
-       int peb;
+       int peb, err;
 
        spin_lock(&ubi->wl_lock);
        peb = __wl_get_peb(ubi);
        spin_unlock(&ubi->wl_lock);
 
+       err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset,
+                                   ubi->peb_size - ubi->vid_hdr_aloffset);
+       if (err) {
+               ubi_err("new PEB %d does not contain all 0xFF bytes", peb);
+               return err;
+       }
+
        return peb;
 }
 #endif
index 16b7a72a70c4aae344cefb39f64d4b9ca5155eb8..3b2365c8eab23a38fda34d71b27a7497294dd5fb 100644 (file)
@@ -1276,7 +1276,7 @@ struct megasas_evt_detail {
 } __attribute__ ((packed));
 
 struct megasas_aen_event {
-       struct work_struct hotplug_work;
+       struct delayed_work hotplug_work;
        struct megasas_instance *instance;
 };
 
index d2c5366aff7fba67ffa0bdef6007d69ff8e37de2..e4f2baacf1e1783ec9054bae3f7013afb5af0a5f 100644 (file)
@@ -2060,9 +2060,9 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
                } else {
                        ev->instance = instance;
                        instance->ev = ev;
-                       INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
-                       schedule_delayed_work(
-                               (struct delayed_work *)&ev->hotplug_work, 0);
+                       INIT_DELAYED_WORK(&ev->hotplug_work,
+                                         megasas_aen_polling);
+                       schedule_delayed_work(&ev->hotplug_work, 0);
                }
        }
 }
@@ -4352,8 +4352,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
        /* cancel the delayed work if this work still in queue */
        if (instance->ev != NULL) {
                struct megasas_aen_event *ev = instance->ev;
-               cancel_delayed_work_sync(
-                       (struct delayed_work *)&ev->hotplug_work);
+               cancel_delayed_work_sync(&ev->hotplug_work);
                instance->ev = NULL;
        }
 
@@ -4545,8 +4544,7 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
        /* cancel the delayed work if this work still in queue*/
        if (instance->ev != NULL) {
                struct megasas_aen_event *ev = instance->ev;
-               cancel_delayed_work_sync(
-                       (struct delayed_work *)&ev->hotplug_work);
+               cancel_delayed_work_sync(&ev->hotplug_work);
                instance->ev = NULL;
        }
 
@@ -5190,7 +5188,7 @@ static void
 megasas_aen_polling(struct work_struct *work)
 {
        struct megasas_aen_event *ev =
-               container_of(work, struct megasas_aen_event, hotplug_work);
+               container_of(work, struct megasas_aen_event, hotplug_work.work);
        struct megasas_instance *instance = ev->instance;
        union megasas_evt_class_locale class_locale;
        struct  Scsi_Host *host;
index 3586fb05c8ce03a4b0167b19f07c007c2095bf14..ec0aca8ba6bfdc79022563007207c5a70d23bd37 100644 (file)
@@ -2893,6 +2893,55 @@ static void end_bio_bh_io_sync(struct bio *bio, int err)
        bio_put(bio);
 }
 
+/*
+ * This allows us to do IO even on the odd last sectors
+ * of a device, even if the bh block size is some multiple
+ * of the physical sector size.
+ *
+ * We'll just truncate the bio to the size of the device,
+ * and clear the end of the buffer head manually.
+ *
+ * Truly out-of-range accesses will turn into actual IO
+ * errors, this only handles the "we need to be able to
+ * do IO at the final sector" case.
+ */
+static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh)
+{
+       sector_t maxsector;
+       unsigned bytes;
+
+       maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9;
+       if (!maxsector)
+               return;
+
+       /*
+        * If the *whole* IO is past the end of the device,
+        * let it through, and the IO layer will turn it into
+        * an EIO.
+        */
+       if (unlikely(bio->bi_sector >= maxsector))
+               return;
+
+       maxsector -= bio->bi_sector;
+       bytes = bio->bi_size;
+       if (likely((bytes >> 9) <= maxsector))
+               return;
+
+       /* Uhhuh. We've got a bh that straddles the device size! */
+       bytes = maxsector << 9;
+
+       /* Truncate the bio.. */
+       bio->bi_size = bytes;
+       bio->bi_io_vec[0].bv_len = bytes;
+
+       /* ..and clear the end of the buffer for reads */
+       if ((rw & RW_MASK) == READ) {
+               void *kaddr = kmap_atomic(bh->b_page);
+               memset(kaddr + bh_offset(bh) + bytes, 0, bh->b_size - bytes);
+               kunmap_atomic(kaddr);
+       }
+}
+
 int submit_bh(int rw, struct buffer_head * bh)
 {
        struct bio *bio;
@@ -2929,6 +2978,9 @@ int submit_bh(int rw, struct buffer_head * bh)
        bio->bi_end_io = end_bio_bh_io_sync;
        bio->bi_private = bh;
 
+       /* Take care of bh's that straddle the end of the device */
+       guard_bh_eod(rw, bio, bh);
+
        bio_get(bio);
        submit_bio(rw, bio);
 
index a123b13b70fd80cb12def4c100ee198606b7c6b6..7d8dfc7392f11f020f1a4de28ff66f416c19c964 100644 (file)
@@ -701,6 +701,13 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
 #define COMPACTION_BUILD 0
 #endif
 
+/* This helps us to avoid #ifdef CONFIG_SYMBOL_PREFIX */
+#ifdef CONFIG_SYMBOL_PREFIX
+#define SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
+#else
+#define SYMBOL_PREFIX ""
+#endif
+
 /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
 # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
index 4646eb2c382011de7c051577d0fe8b590b4dddca..767e559dfb10e697d207cdc1dedca0b00d5b5bdf 100644 (file)
@@ -21,10 +21,10 @@ struct key *modsign_keyring;
 extern __initdata const u8 modsign_certificate_list[];
 extern __initdata const u8 modsign_certificate_list_end[];
 asm(".section .init.data,\"aw\"\n"
-    "modsign_certificate_list:\n"
+    SYMBOL_PREFIX "modsign_certificate_list:\n"
     ".incbin \"signing_key.x509\"\n"
     ".incbin \"extra_certificates\"\n"
-    "modsign_certificate_list_end:"
+    SYMBOL_PREFIX "modsign_certificate_list_end:"
     );
 
 /*
index 084aa47bac820498f932ae6ff54158414e48e889..1dae900df798d1c4e1be722567fd2906041f08f5 100644 (file)
@@ -1361,8 +1361,8 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq,
 
        WARN_ON_ONCE(timer->function != delayed_work_timer_fn ||
                     timer->data != (unsigned long)dwork);
-       BUG_ON(timer_pending(timer));
-       BUG_ON(!list_empty(&work->entry));
+       WARN_ON_ONCE(timer_pending(timer));
+       WARN_ON_ONCE(!list_empty(&work->entry));
 
        /*
         * If @delay is 0, queue @dwork->work immediately.  This is for