From: Greg Kroah-Hartman Date: Tue, 31 Dec 2013 05:20:26 +0000 (-0800) Subject: 3.12-stable patches X-Git-Tag: v3.4.76~75 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=977e63bbcf803ae1767e4479330f7f84170eb856;p=thirdparty%2Fkernel%2Fstable-queue.git 3.12-stable patches added patches: ceph-allocate-non-zero-page-to-fscache-in-readpage.patch ceph-cleanup-aborted-requests-when-re-sending-requests.patch ceph-hung-on-ceph-fscache-invalidate-in-some-cases.patch ceph-wake-up-safe-waiters-when-unregistering-request.patch n_tty-fix-apparent-order-of-echoed-output.patch powerpc-kvm-fix-rare-but-potential-deadlock-scene.patch tty-fix-hang-at-ldsem_down_read.patch tty-pmac_zilog-check-existence-of-ports-in-pmz_console_init.patch --- diff --git a/queue-3.12/ceph-allocate-non-zero-page-to-fscache-in-readpage.patch b/queue-3.12/ceph-allocate-non-zero-page-to-fscache-in-readpage.patch new file mode 100644 index 00000000000..8ff6731d39d --- /dev/null +++ b/queue-3.12/ceph-allocate-non-zero-page-to-fscache-in-readpage.patch @@ -0,0 +1,33 @@ +From ff638b7df5a9264024a6448bdfde2b2bf5d1994a Mon Sep 17 00:00:00 2001 +From: Li Wang +Date: Sat, 9 Nov 2013 10:26:06 +0800 +Subject: ceph: allocate non-zero page to fscache in readpage() + +From: Li Wang + +commit ff638b7df5a9264024a6448bdfde2b2bf5d1994a upstream. + +ceph_osdc_readpages() returns number of bytes read, currently, +the code only allocate full-zero page into fscache, this patch +fixes this. + +Signed-off-by: Li Wang +Reviewed-by: Milosz Tanski +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/addr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ceph/addr.c ++++ b/fs/ceph/addr.c +@@ -216,7 +216,7 @@ static int readpage_nounlock(struct file + } + SetPageUptodate(page); + +- if (err == 0) ++ if (err >= 0) + ceph_readpage_to_fscache(inode, page); + + out: diff --git a/queue-3.12/ceph-cleanup-aborted-requests-when-re-sending-requests.patch b/queue-3.12/ceph-cleanup-aborted-requests-when-re-sending-requests.patch new file mode 100644 index 00000000000..2ea9df4cabf --- /dev/null +++ b/queue-3.12/ceph-cleanup-aborted-requests-when-re-sending-requests.patch @@ -0,0 +1,37 @@ +From eb1b8af33c2e42a9a57fc0a7588f4a7b255d2e79 Mon Sep 17 00:00:00 2001 +From: "Yan, Zheng" +Date: Thu, 26 Sep 2013 14:25:36 +0800 +Subject: ceph: cleanup aborted requests when re-sending requests. + +From: "Yan, Zheng" + +commit eb1b8af33c2e42a9a57fc0a7588f4a7b255d2e79 upstream. + +Aborted requests usually get cleared when the reply is received. +If MDS crashes, no reply will be received. So we need to cleanup +aborted requests when re-sending requests. + +Signed-off-by: Yan, Zheng +Reviewed-by: Greg Farnum +Signed-off-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/mds_client.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -1875,8 +1875,11 @@ static int __do_request(struct ceph_mds_ + int mds = -1; + int err = -EAGAIN; + +- if (req->r_err || req->r_got_result) ++ if (req->r_err || req->r_got_result) { ++ if (req->r_aborted) ++ __unregister_request(mdsc, req); + goto out; ++ } + + if (req->r_timeout && + time_after_eq(jiffies, req->r_started + req->r_timeout)) { diff --git a/queue-3.12/ceph-hung-on-ceph-fscache-invalidate-in-some-cases.patch b/queue-3.12/ceph-hung-on-ceph-fscache-invalidate-in-some-cases.patch new file mode 100644 index 00000000000..4cfe92ddeea --- /dev/null +++ b/queue-3.12/ceph-hung-on-ceph-fscache-invalidate-in-some-cases.patch @@ -0,0 +1,53 @@ +From ffc79664d15841025d90afdd902c4112ffe168d6 Mon Sep 17 00:00:00 2001 +From: Milosz Tanski +Date: Wed, 25 Sep 2013 11:18:14 -0400 +Subject: ceph: hung on ceph fscache invalidate in some cases + +From: Milosz Tanski + +commit ffc79664d15841025d90afdd902c4112ffe168d6 upstream. + +In some cases I'm on my ceph client cluster I'm seeing hunk kernel tasks in +the invalidate page code path. This is due to the fact that we don't check if +the page is marked as cache before calling fscache_wait_on_page_write(). + +This is the log from the hang + +INFO: task XXXXXX:12034 blocked for more than 120 seconds. +"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. + ... +Call Trace: +[] schedule+0x29/0x70 +[] __fscache_wait_on_page_write+0x6d/0xb0 [fscache] +[] ? add_wait_queue+0x60/0x60 +[] ceph_invalidate_fscache_page+0x29/0x50 [ceph] +[] ceph_invalidatepage+0x70/0x190 [ceph] +[] ? delete_from_page_cache+0x5f/0x70 +[] truncate_inode_page+0x8b/0x90 +[] truncate_inode_pages_range.part.12+0x13d/0x620 +[] truncate_inode_pages_range+0x4d/0x60 +[] truncate_inode_pages+0x15/0x20 +[] evict+0x1a6/0x1b0 +[] iput+0x103/0x190 + ... + +Signed-off-by: Milosz Tanski +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/cache.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/ceph/cache.c ++++ b/fs/ceph/cache.c +@@ -324,6 +324,9 @@ void ceph_invalidate_fscache_page(struct + { + struct ceph_inode_info *ci = ceph_inode(inode); + ++ if (!PageFsCache(page)) ++ return; ++ + fscache_wait_on_page_write(ci->fscache, page); + fscache_uncache_page(ci->fscache, page); + } diff --git a/queue-3.12/ceph-wake-up-safe-waiters-when-unregistering-request.patch b/queue-3.12/ceph-wake-up-safe-waiters-when-unregistering-request.patch new file mode 100644 index 00000000000..ddeb96e1b29 --- /dev/null +++ b/queue-3.12/ceph-wake-up-safe-waiters-when-unregistering-request.patch @@ -0,0 +1,39 @@ +From fc55d2c9448b34218ca58733a6f51fbede09575b Mon Sep 17 00:00:00 2001 +From: "Yan, Zheng" +Date: Thu, 31 Oct 2013 09:10:47 +0800 +Subject: ceph: wake up 'safe' waiters when unregistering request + +From: "Yan, Zheng" + +commit fc55d2c9448b34218ca58733a6f51fbede09575b upstream. + +We also need to wake up 'safe' waiters if error occurs or request +aborted. Otherwise sync(2)/fsync(2) may hang forever. + +Signed-off-by: Yan, Zheng +Signed-off-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/mds_client.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -642,6 +642,8 @@ static void __unregister_request(struct + req->r_unsafe_dir = NULL; + } + ++ complete_all(&req->r_safe_completion); ++ + ceph_mdsc_put_request(req); + } + +@@ -2189,7 +2191,6 @@ static void handle_reply(struct ceph_mds + if (head->safe) { + req->r_got_safe = true; + __unregister_request(mdsc, req); +- complete_all(&req->r_safe_completion); + + if (req->r_got_unsafe) { + /* diff --git a/queue-3.12/n_tty-fix-apparent-order-of-echoed-output.patch b/queue-3.12/n_tty-fix-apparent-order-of-echoed-output.patch new file mode 100644 index 00000000000..0371ee6cdb6 --- /dev/null +++ b/queue-3.12/n_tty-fix-apparent-order-of-echoed-output.patch @@ -0,0 +1,76 @@ +From 1075a6e2dc7e2a96efc417b98dd98f57fdae985d Mon Sep 17 00:00:00 2001 +From: Peter Hurley +Date: Mon, 9 Dec 2013 18:06:07 -0500 +Subject: n_tty: Fix apparent order of echoed output + +From: Peter Hurley + +commit 1075a6e2dc7e2a96efc417b98dd98f57fdae985d upstream. + +With block processing of echoed output, observed output order is still +required. Push completed echoes and echo commands prior to output. + +Introduce echo_mark echo buffer index, which tracks completed echo +commands; ie., those submitted via commit_echoes but which may not +have been committed. Ensure that completed echoes are output prior +to subsequent terminal writes in process_echoes(). + +Fixes newline/prompt output order in cooked mode shell. + +Reported-by: Karl Dahlke +Reported-by: Mikulas Patocka +Signed-off-by: Peter Hurley +Tested-by: Karl Dahlke +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/n_tty.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/tty/n_tty.c ++++ b/drivers/tty/n_tty.c +@@ -93,6 +93,7 @@ struct n_tty_data { + size_t canon_head; + size_t echo_head; + size_t echo_commit; ++ size_t echo_mark; + DECLARE_BITMAP(char_map, 256); + + /* private to n_tty_receive_overrun (single-threaded) */ +@@ -336,6 +337,7 @@ static void reset_buffer_flags(struct n_ + { + ldata->read_head = ldata->canon_head = ldata->read_tail = 0; + ldata->echo_head = ldata->echo_tail = ldata->echo_commit = 0; ++ ldata->echo_mark = 0; + ldata->line_start = 0; + + ldata->erasing = 0; +@@ -787,6 +789,7 @@ static void commit_echoes(struct tty_str + size_t head; + + head = ldata->echo_head; ++ ldata->echo_mark = head; + old = ldata->echo_commit - ldata->echo_tail; + + /* Process committed echoes if the accumulated # of bytes +@@ -811,10 +814,11 @@ static void process_echoes(struct tty_st + size_t echoed; + + if ((!L_ECHO(tty) && !L_ECHONL(tty)) || +- ldata->echo_commit == ldata->echo_tail) ++ ldata->echo_mark == ldata->echo_tail) + return; + + mutex_lock(&ldata->output_lock); ++ ldata->echo_commit = ldata->echo_mark; + echoed = __process_echoes(tty); + mutex_unlock(&ldata->output_lock); + +@@ -822,6 +826,7 @@ static void process_echoes(struct tty_st + tty->ops->flush_chars(tty); + } + ++/* NB: echo_mark and echo_head should be equivalent here */ + static void flush_echoes(struct tty_struct *tty) + { + struct n_tty_data *ldata = tty->disc_data; diff --git a/queue-3.12/powerpc-kvm-fix-rare-but-potential-deadlock-scene.patch b/queue-3.12/powerpc-kvm-fix-rare-but-potential-deadlock-scene.patch new file mode 100644 index 00000000000..a11d33e6f9c --- /dev/null +++ b/queue-3.12/powerpc-kvm-fix-rare-but-potential-deadlock-scene.patch @@ -0,0 +1,77 @@ +From 91648ec09c1ef69c4d840ab6dab391bfb452d554 Mon Sep 17 00:00:00 2001 +From: pingfan liu +Date: Fri, 15 Nov 2013 16:35:00 +0800 +Subject: powerpc: kvm: fix rare but potential deadlock scene + +From: pingfan liu + +commit 91648ec09c1ef69c4d840ab6dab391bfb452d554 upstream. + +Since kvmppc_hv_find_lock_hpte() is called from both virtmode and +realmode, so it can trigger the deadlock. + +Suppose the following scene: + +Two physical cpuM, cpuN, two VM instances A, B, each VM has a group of +vcpus. + +If on cpuM, vcpu_A_1 holds bitlock X (HPTE_V_HVLOCK), then is switched +out, and on cpuN, vcpu_A_2 try to lock X in realmode, then cpuN will be +caught in realmode for a long time. + +What makes things even worse if the following happens, + On cpuM, bitlockX is hold, on cpuN, Y is hold. + vcpu_B_2 try to lock Y on cpuM in realmode + vcpu_A_2 try to lock X on cpuN in realmode + +Oops! deadlock happens + +Signed-off-by: Liu Ping Fan +Reviewed-by: Paul Mackerras +Signed-off-by: Alexander Graf +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kvm/book3s_64_mmu_hv.c | 6 +++++- + arch/powerpc/kvm/book3s_hv_rm_mmu.c | 4 ++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c ++++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c +@@ -473,11 +473,14 @@ static int kvmppc_mmu_book3s_64_hv_xlate + slb_v = vcpu->kvm->arch.vrma_slb_v; + } + ++ preempt_disable(); + /* Find the HPTE in the hash table */ + index = kvmppc_hv_find_lock_hpte(kvm, eaddr, slb_v, + HPTE_V_VALID | HPTE_V_ABSENT); +- if (index < 0) ++ if (index < 0) { ++ preempt_enable(); + return -ENOENT; ++ } + hptep = (unsigned long *)(kvm->arch.hpt_virt + (index << 4)); + v = hptep[0] & ~HPTE_V_HVLOCK; + gr = kvm->arch.revmap[index].guest_rpte; +@@ -485,6 +488,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate + /* Unlock the HPTE */ + asm volatile("lwsync" : : : "memory"); + hptep[0] = v; ++ preempt_enable(); + + gpte->eaddr = eaddr; + gpte->vpage = ((v & HPTE_V_AVPN) << 4) | ((eaddr >> 12) & 0xfff); +--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c ++++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c +@@ -749,6 +749,10 @@ static int slb_base_page_shift[4] = { + 20, /* 1M, unsupported */ + }; + ++/* When called from virtmode, this func should be protected by ++ * preempt_disable(), otherwise, the holding of HPTE_V_HVLOCK ++ * can trigger deadlock issue. ++ */ + long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, + unsigned long valid) + { diff --git a/queue-3.12/series b/queue-3.12/series index f351a020bbc..edf6c2253c3 100644 --- a/queue-3.12/series +++ b/queue-3.12/series @@ -1 +1,9 @@ usb-serial-fix-race-in-generic-write.patch +ceph-hung-on-ceph-fscache-invalidate-in-some-cases.patch +ceph-cleanup-aborted-requests-when-re-sending-requests.patch +ceph-wake-up-safe-waiters-when-unregistering-request.patch +ceph-allocate-non-zero-page-to-fscache-in-readpage.patch +powerpc-kvm-fix-rare-but-potential-deadlock-scene.patch +tty-fix-hang-at-ldsem_down_read.patch +n_tty-fix-apparent-order-of-echoed-output.patch +tty-pmac_zilog-check-existence-of-ports-in-pmz_console_init.patch diff --git a/queue-3.12/tty-fix-hang-at-ldsem_down_read.patch b/queue-3.12/tty-fix-hang-at-ldsem_down_read.patch new file mode 100644 index 00000000000..84c31deffbc --- /dev/null +++ b/queue-3.12/tty-fix-hang-at-ldsem_down_read.patch @@ -0,0 +1,120 @@ +From cf872776fc84128bb779ce2b83a37c884c3203ae Mon Sep 17 00:00:00 2001 +From: Peter Hurley +Date: Wed, 11 Dec 2013 21:11:58 -0500 +Subject: tty: Fix hang at ldsem_down_read() + +From: Peter Hurley + +commit cf872776fc84128bb779ce2b83a37c884c3203ae upstream. + +When a controlling tty is being hung up and the hang up is +waiting for a just-signalled tty reader or writer to exit, and a new tty +reader/writer tries to acquire an ldisc reference concurrently with the +ldisc reference release from the signalled reader/writer, the hangup +can hang. The new reader/writer is sleeping in ldsem_down_read() and the +hangup is sleeping in ldsem_down_write() [1]. + +The new reader/writer fails to wakeup the waiting hangup because the +wrong lock count value is checked (the old lock count rather than the new +lock count) to see if the lock is unowned. + +Change helper function to return the new lock count if the cmpxchg was +successful; document this behavior. + +[1] edited dmesg log from reporter + +SysRq : Show Blocked State + task PC stack pid father +systemd D ffff88040c4f0000 0 1 0 0x00000000 + ffff88040c49fbe0 0000000000000046 ffff88040c4a0000 ffff88040c49ffd8 + 00000000001d3980 00000000001d3980 ffff88040c4a0000 ffff88040593d840 + ffff88040c49fb40 ffffffff810a4cc0 0000000000000006 0000000000000023 +Call Trace: + [] ? sched_clock_cpu+0x9f/0xe4 + [] ? sched_clock_cpu+0x9f/0xe4 + [] ? sched_clock_cpu+0x9f/0xe4 + [] ? sched_clock_cpu+0x9f/0xe4 + [] schedule+0x24/0x5e + [] schedule_timeout+0x15b/0x1ec + [] ? sched_clock_cpu+0x9f/0xe4 + [] ? _raw_spin_unlock_irq+0x24/0x26 + [] down_read_failed+0xe3/0x1b9 + [] ldsem_down_read+0x8b/0xa5 + [] ? tty_ldisc_ref_wait+0x1b/0x44 + [] tty_ldisc_ref_wait+0x1b/0x44 + [] tty_write+0x7d/0x28a + [] redirected_tty_write+0x8d/0x98 + [] ? tty_write+0x28a/0x28a + [] do_loop_readv_writev+0x56/0x79 + [] do_readv_writev+0x1b0/0x1ff + [] ? do_vfs_ioctl+0x32a/0x489 + [] ? final_putname+0x1d/0x3a + [] vfs_writev+0x2e/0x49 + [] SyS_writev+0x47/0xaa + [] system_call_fastpath+0x16/0x1b +bash D ffffffff81c104c0 0 5469 5302 0x00000082 + ffff8800cf817ac0 0000000000000046 ffff8804086b22a0 ffff8800cf817fd8 + 00000000001d3980 00000000001d3980 ffff8804086b22a0 ffff8800cf817a48 + 000000000000b9a0 ffff8800cf817a78 ffffffff81004675 ffff8800cf817a44 +Call Trace: + [] ? dump_trace+0x165/0x29c + [] ? sched_clock_cpu+0x9f/0xe4 + [] ? save_stack_trace+0x26/0x41 + [] schedule+0x24/0x5e + [] schedule_timeout+0x15b/0x1ec + [] ? sched_clock_cpu+0x9f/0xe4 + [] ? down_write_failed+0xa3/0x1c9 + [] ? _raw_spin_unlock_irq+0x24/0x26 + [] down_write_failed+0xab/0x1c9 + [] ldsem_down_write+0x79/0xb1 + [] ? tty_ldisc_lock_pair_timeout+0xa5/0xd9 + [] tty_ldisc_lock_pair_timeout+0xa5/0xd9 + [] tty_ldisc_hangup+0xc4/0x218 + [] __tty_hangup+0x2e2/0x3ed + [] disassociate_ctty+0x63/0x226 + [] do_exit+0x79f/0xa11 + [] ? get_signal_to_deliver+0x206/0x62f + [] ? lock_release_holdtime.part.8+0xf/0x16e + [] do_group_exit+0x47/0xb5 + [] get_signal_to_deliver+0x241/0x62f + [] do_signal+0x43/0x59d + [] ? __audit_syscall_exit+0x21a/0x2a8 + [] ? lock_release_holdtime.part.8+0xf/0x16e + [] do_notify_resume+0x54/0x6c + [] int_signal+0x12/0x17 + +Reported-by: Sami Farin +Signed-off-by: Peter Hurley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/tty_ldsem.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +--- a/drivers/tty/tty_ldsem.c ++++ b/drivers/tty/tty_ldsem.c +@@ -86,11 +86,21 @@ static inline long ldsem_atomic_update(l + return atomic_long_add_return(delta, (atomic_long_t *)&sem->count); + } + ++/* ++ * ldsem_cmpxchg() updates @*old with the last-known sem->count value. ++ * Returns 1 if count was successfully changed; @*old will have @new value. ++ * Returns 0 if count was not changed; @*old will have most recent sem->count ++ */ + static inline int ldsem_cmpxchg(long *old, long new, struct ld_semaphore *sem) + { +- long tmp = *old; +- *old = atomic_long_cmpxchg(&sem->count, *old, new); +- return *old == tmp; ++ long tmp = atomic_long_cmpxchg(&sem->count, *old, new); ++ if (tmp == *old) { ++ *old = new; ++ return 1; ++ } else { ++ *old = tmp; ++ return 0; ++ } + } + + /* diff --git a/queue-3.12/tty-pmac_zilog-check-existence-of-ports-in-pmz_console_init.patch b/queue-3.12/tty-pmac_zilog-check-existence-of-ports-in-pmz_console_init.patch new file mode 100644 index 00000000000..f2bcc48c339 --- /dev/null +++ b/queue-3.12/tty-pmac_zilog-check-existence-of-ports-in-pmz_console_init.patch @@ -0,0 +1,47 @@ +From dc1dc2f8a5dd863bf2e79f338fc3ae29e99c683a Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Fri, 22 Nov 2013 16:47:26 +0100 +Subject: TTY: pmac_zilog, check existence of ports in pmz_console_init() + +From: Geert Uytterhoeven + +commit dc1dc2f8a5dd863bf2e79f338fc3ae29e99c683a upstream. + +When booting a multi-platform m68k kernel on a non-Mac with "console=ttyS0" +on the kernel command line, it crashes with: + +Unable to handle kernel NULL pointer dereference at virtual address (null) +Oops: 00000000 +PC: [<0013ad28>] __pmz_startup+0x32/0x2a0 +... +Call Trace: [<002c5d3e>] pmz_console_setup+0x64/0xe4 + +The normal tty driver doesn't crash, because init_pmz() checks +pmz_ports_count again after calling pmz_probe(). + +In the serial console initialization path, pmz_console_init() doesn't do +this, causing the driver to crash later. + +Add a check for pmz_ports_count to fix this. + +Signed-off-by: Geert Uytterhoeven +Cc: Finn Thain +Cc: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/pmac_zilog.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/tty/serial/pmac_zilog.c ++++ b/drivers/tty/serial/pmac_zilog.c +@@ -2050,6 +2050,9 @@ static int __init pmz_console_init(void) + /* Probe ports */ + pmz_probe(); + ++ if (pmz_ports_count == 0) ++ return -ENODEV; ++ + /* TODO: Autoprobe console based on OF */ + /* pmz_console.index = i; */ + register_console(&pmz_console);