From: Greg Kroah-Hartman Date: Wed, 9 Jan 2013 18:18:15 +0000 (-0800) Subject: 3.7-stable patches X-Git-Tag: v3.0.58~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=59010ceabf846f4da2d2fed973f348678ef678cf;p=thirdparty%2Fkernel%2Fstable-queue.git 3.7-stable patches added patches: arm64-compat-for-clock_adjtime-2-is-miswired.patch arm-7606-1-cache-flush-to-louu-instead-of-louis-on-uniprocessor-cpus.patch arm-7607-1-realview-fix-private-peripheral-memory-base-for-eb-rev.-b-boards.patch arm-missing-mmap_sem-around-find_vma-in-swp_emulate.c.patch arm-mm-use-pteval_t-to-represent-page-protection-values.patch bluetooth-add-missing-lock-nesting-notation.patch bluetooth-add-support-for-bcm20702a0.patch bluetooth-cancel-power_on-work-when-unregistering-the-device.patch cifs-adjust-sequence-number-downward-after-signing-nt_cancel.patch cifs-move-check-for-null-socket-into-smb_send_rqst.patch fs-fix-imbalance-in-freeze-protection-in-mark_files_ro.patch pci-pm-do-not-suspend-port-if-any-subordinate-device-needs-pme-polling.patch pci-pm-keep-runtime-pm-enabled-for-unbound-pci-devices.patch pci-reduce-ricoh-0xe822-sd-card-reader-base-clock-frequency-to-50mhz.patch pci-work-around-stratus-ftserver-broken-pcie-hierarchy-fix-dmi-check.patch printk-fix-incorrect-length-from-print_time-when-seconds-99999.patch revert-bluetooth-fix-possible-deadlock-in-sco-code.patch signals-sys_ssetmask-uses-uninitialized-newmask.patch solos-pci-fix-double-free-of-tx-skb-in-dma-mode.patch xfs-fix-direct-io-nested-transaction-deadlock.patch xfs-fix-stray-dquot-unlock-when-reclaiming-dquots.patch --- diff --git a/queue-3.7/arm-7606-1-cache-flush-to-louu-instead-of-louis-on-uniprocessor-cpus.patch b/queue-3.7/arm-7606-1-cache-flush-to-louu-instead-of-louis-on-uniprocessor-cpus.patch new file mode 100644 index 00000000000..d3493123eba --- /dev/null +++ b/queue-3.7/arm-7606-1-cache-flush-to-louu-instead-of-louis-on-uniprocessor-cpus.patch @@ -0,0 +1,40 @@ +From d056a699dd3d9366dd3b4d9996e7848209199cda Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Wed, 19 Dec 2012 15:01:08 +0100 +Subject: ARM: 7606/1: cache: flush to LoUU instead of LoUIS on uniprocessor CPUs + +From: Will Deacon + +commit d056a699dd3d9366dd3b4d9996e7848209199cda upstream. + +flush_cache_louis flushes the D-side caches to the point of unification +inner-shareable. On uniprocessor CPUs, this is defined as zero and +therefore no flushing will take place. Rather than invent a new interface +for UP systems, instead use our SMP_ON_UP patching code to read the +LoUU from the CLIDR instead. + +Cc: Lorenzo Pieralisi +Tested-by: Guennadi Liakhovetski +Signed-off-by: Will Deacon +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/mm/cache-v7.S | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/arm/mm/cache-v7.S ++++ b/arch/arm/mm/cache-v7.S +@@ -44,8 +44,10 @@ ENDPROC(v7_flush_icache_all) + ENTRY(v7_flush_dcache_louis) + dmb @ ensure ordering with previous memory accesses + mrc p15, 1, r0, c0, c0, 1 @ read clidr, r0 = clidr +- ands r3, r0, #0xe00000 @ extract LoUIS from clidr +- mov r3, r3, lsr #20 @ r3 = LoUIS * 2 ++ ALT_SMP(ands r3, r0, #(7 << 21)) @ extract LoUIS from clidr ++ ALT_UP(ands r3, r0, #(7 << 27)) @ extract LoUU from clidr ++ ALT_SMP(mov r3, r3, lsr #20) @ r3 = LoUIS * 2 ++ ALT_UP(mov r3, r3, lsr #26) @ r3 = LoUU * 2 + moveq pc, lr @ return if level == 0 + mov r10, #0 @ r10 (starting level) = 0 + b flush_levels @ start flushing cache levels diff --git a/queue-3.7/arm-7607-1-realview-fix-private-peripheral-memory-base-for-eb-rev.-b-boards.patch b/queue-3.7/arm-7607-1-realview-fix-private-peripheral-memory-base-for-eb-rev.-b-boards.patch new file mode 100644 index 00000000000..91192135a45 --- /dev/null +++ b/queue-3.7/arm-7607-1-realview-fix-private-peripheral-memory-base-for-eb-rev.-b-boards.patch @@ -0,0 +1,37 @@ +From e6ee4b2b57a8e0d8e551031173de080b338d3969 Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Wed, 19 Dec 2012 15:01:50 +0100 +Subject: ARM: 7607/1: realview: fix private peripheral memory base for EB rev. B boards + +From: Will Deacon + +commit e6ee4b2b57a8e0d8e551031173de080b338d3969 upstream. + +Commit 34ae6c96a6a7 ("ARM: 7298/1: realview: fix mapping of MPCore +private memory region") accidentally broke the definition for the base +address of the private peripheral region on revision B Realview-EB +boards. + +This patch uses the correct address for REALVIEW_EB11MP_PRIV_MEM_BASE. + +Acked-by: Marc Zyngier +Tested-by: Florian Fainelli +Signed-off-by: Will Deacon +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/mach-realview/include/mach/board-eb.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/mach-realview/include/mach/board-eb.h ++++ b/arch/arm/mach-realview/include/mach/board-eb.h +@@ -47,7 +47,7 @@ + #define REALVIEW_EB_USB_BASE 0x4F000000 /* USB */ + + #ifdef CONFIG_REALVIEW_EB_ARM11MP_REVB +-#define REALVIEW_EB11MP_PRIV_MEM_BASE 0x1F000000 ++#define REALVIEW_EB11MP_PRIV_MEM_BASE 0x10100000 + #define REALVIEW_EB11MP_L220_BASE 0x10102000 /* L220 registers */ + #define REALVIEW_EB11MP_SYS_PLD_CTRL1 0xD8 /* Register offset for MPCore sysctl */ + #else diff --git a/queue-3.7/arm-missing-mmap_sem-around-find_vma-in-swp_emulate.c.patch b/queue-3.7/arm-missing-mmap_sem-around-find_vma-in-swp_emulate.c.patch new file mode 100644 index 00000000000..34815f60a86 --- /dev/null +++ b/queue-3.7/arm-missing-mmap_sem-around-find_vma-in-swp_emulate.c.patch @@ -0,0 +1,38 @@ +From 7bf9b7bef881aac820bf1f2e9951a17b09bd7e04 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 16 Dec 2012 00:25:57 +0000 +Subject: ARM: missing ->mmap_sem around find_vma() in swp_emulate.c + +From: Al Viro + +commit 7bf9b7bef881aac820bf1f2e9951a17b09bd7e04 upstream. + +find_vma() is *not* safe when somebody else is removing vmas. Not just +the return value might get bogus just as you are getting it (this instance +doesn't try to dereference the resulting vma), the search itself can get +buggered in rather spectacular ways. IOW, ->mmap_sem really, really is +not optional here. + +Signed-off-by: Al Viro +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/kernel/swp_emulate.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/arm/kernel/swp_emulate.c ++++ b/arch/arm/kernel/swp_emulate.c +@@ -109,10 +109,12 @@ static void set_segfault(struct pt_regs + { + siginfo_t info; + ++ down_read(¤t->mm->mmap_sem); + if (find_vma(current->mm, addr) == NULL) + info.si_code = SEGV_MAPERR; + else + info.si_code = SEGV_ACCERR; ++ up_read(¤t->mm->mmap_sem); + + info.si_signo = SIGSEGV; + info.si_errno = 0; diff --git a/queue-3.7/arm-mm-use-pteval_t-to-represent-page-protection-values.patch b/queue-3.7/arm-mm-use-pteval_t-to-represent-page-protection-values.patch new file mode 100644 index 00000000000..faec8292879 --- /dev/null +++ b/queue-3.7/arm-mm-use-pteval_t-to-represent-page-protection-values.patch @@ -0,0 +1,38 @@ +From 864aa04cd02979c2c755cb28b5f4fe56039171c0 Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Tue, 18 Sep 2012 19:18:35 +0100 +Subject: ARM: mm: use pteval_t to represent page protection values + +From: Will Deacon + +commit 864aa04cd02979c2c755cb28b5f4fe56039171c0 upstream. + +When updating the page protection map after calculating the user_pgprot +value, the base protection map is temporarily stored in an unsigned long +type, causing truncation of the protection bits when LPAE is enabled. +This effectively means that calls to mprotect() will corrupt the upper +page attributes, clearing the XN bit unconditionally. + +This patch uses pteval_t to store the intermediate protection values, +preserving the upper bits for 64-bit descriptors. + +Acked-by: Nicolas Pitre +Acked-by: Catalin Marinas +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/mm/mmu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/mm/mmu.c ++++ b/arch/arm/mm/mmu.c +@@ -488,7 +488,7 @@ static void __init build_mem_type_table( + #endif + + for (i = 0; i < 16; i++) { +- unsigned long v = pgprot_val(protection_map[i]); ++ pteval_t v = pgprot_val(protection_map[i]); + protection_map[i] = __pgprot(v | user_pgprot); + } + diff --git a/queue-3.7/arm64-compat-for-clock_adjtime-2-is-miswired.patch b/queue-3.7/arm64-compat-for-clock_adjtime-2-is-miswired.patch new file mode 100644 index 00000000000..9d31cb122c4 --- /dev/null +++ b/queue-3.7/arm64-compat-for-clock_adjtime-2-is-miswired.patch @@ -0,0 +1,33 @@ +From 18a80376ddb0bdc466995ff58c844d6fd0a65e61 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Wed, 5 Dec 2012 11:48:56 +0000 +Subject: arm64: compat for clock_adjtime(2) is miswired + +From: Al Viro + +commit 18a80376ddb0bdc466995ff58c844d6fd0a65e61 upstream. + +struct timex is different on arm and arm64; adjtimex(2) takes care to +convert, clock_adjtime(2) doesn't... + +Signed-off-by: Al Viro +Acked-by: Will Deacon +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + + +--- + arch/arm64/include/asm/unistd32.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/include/asm/unistd32.h ++++ b/arch/arm64/include/asm/unistd32.h +@@ -393,7 +393,7 @@ __SYSCALL(368, compat_sys_fanotify_mark_ + __SYSCALL(369, sys_prlimit64) + __SYSCALL(370, sys_name_to_handle_at) + __SYSCALL(371, compat_sys_open_by_handle_at) +-__SYSCALL(372, sys_clock_adjtime) ++__SYSCALL(372, compat_sys_clock_adjtime) + __SYSCALL(373, sys_syncfs) + + #define __NR_compat_syscalls 374 diff --git a/queue-3.7/bluetooth-add-missing-lock-nesting-notation.patch b/queue-3.7/bluetooth-add-missing-lock-nesting-notation.patch new file mode 100644 index 00000000000..598a441be39 --- /dev/null +++ b/queue-3.7/bluetooth-add-missing-lock-nesting-notation.patch @@ -0,0 +1,63 @@ +From dc2a0e20fbc85a71c63aa4330b496fda33f6bf80 Mon Sep 17 00:00:00 2001 +From: Gustavo Padovan +Date: Tue, 20 Nov 2012 23:25:54 -0200 +Subject: Bluetooth: Add missing lock nesting notation + +From: Gustavo Padovan + +commit dc2a0e20fbc85a71c63aa4330b496fda33f6bf80 upstream. + +This patch fixes the following report, it happens when accepting rfcomm +connections: + +[ 228.165378] ============================================= +[ 228.165378] [ INFO: possible recursive locking detected ] +[ 228.165378] 3.7.0-rc1-00536-gc1d5dc4 #120 Tainted: G W +[ 228.165378] --------------------------------------------- +[ 228.165378] bluetoothd/1341 is trying to acquire lock: +[ 228.165378] (sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM){+.+...}, at: +[] bt_accept_dequeue+0xa0/0x180 [bluetooth] +[ 228.165378] +[ 228.165378] but task is already holding lock: +[ 228.165378] (sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM){+.+...}, at: +[] rfcomm_sock_accept+0x58/0x2d0 [rfcomm] +[ 228.165378] +[ 228.165378] other info that might help us debug this: +[ 228.165378] Possible unsafe locking scenario: +[ 228.165378] +[ 228.165378] CPU0 +[ 228.165378] ---- +[ 228.165378] lock(sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM); +[ 228.165378] lock(sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM); +[ 228.165378] +[ 228.165378] *** DEADLOCK *** +[ 228.165378] +[ 228.165378] May be due to missing lock nesting notation + +Signed-off-by: Gustavo Padovan +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/rfcomm/sock.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/bluetooth/rfcomm/sock.c ++++ b/net/bluetooth/rfcomm/sock.c +@@ -467,7 +467,7 @@ static int rfcomm_sock_accept(struct soc + long timeo; + int err = 0; + +- lock_sock(sk); ++ lock_sock_nested(sk, SINGLE_DEPTH_NESTING); + + if (sk->sk_type != SOCK_STREAM) { + err = -EINVAL; +@@ -504,7 +504,7 @@ static int rfcomm_sock_accept(struct soc + + release_sock(sk); + timeo = schedule_timeout(timeo); +- lock_sock(sk); ++ lock_sock_nested(sk, SINGLE_DEPTH_NESTING); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(sk_sleep(sk), &wait); diff --git a/queue-3.7/bluetooth-add-support-for-bcm20702a0.patch b/queue-3.7/bluetooth-add-support-for-bcm20702a0.patch new file mode 100644 index 00000000000..98fdf4c25b3 --- /dev/null +++ b/queue-3.7/bluetooth-add-support-for-bcm20702a0.patch @@ -0,0 +1,43 @@ +From 1ee3ff6110c16acfc915a79b1e3feb5013c41e75 Mon Sep 17 00:00:00 2001 +From: Jeff Cook +Date: Fri, 9 Nov 2012 16:39:48 -0700 +Subject: Bluetooth: Add support for BCM20702A0 [0b05, 17b5] + +From: Jeff Cook + +commit 1ee3ff6110c16acfc915a79b1e3feb5013c41e75 upstream. + +Vendor-specific ID for BCM20702A0. +Support for bluetooth over Asus Wi-Fi GO!, included with Asus P8Z77-V +Deluxe. + +T: Bus=07 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 +D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0b05 ProdID=17b5 Rev=01.12 +S: Manufacturer=Broadcom Corp +S: Product=BCM20702A0 +S: SerialNumber=94DBC98AC113 +C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) +I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) +I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) +I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none) + +Signed-off-by: Jeff Cook +Signed-off-by: Gustavo Padovan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/bluetooth/btusb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -96,6 +96,7 @@ static struct usb_device_id btusb_table[ + { USB_DEVICE(0x0c10, 0x0000) }, + + /* Broadcom BCM20702A0 */ ++ { USB_DEVICE(0x0b05, 0x17b5) }, + { USB_DEVICE(0x04ca, 0x2003) }, + { USB_DEVICE(0x0489, 0xe042) }, + { USB_DEVICE(0x413c, 0x8197) }, diff --git a/queue-3.7/bluetooth-cancel-power_on-work-when-unregistering-the-device.patch b/queue-3.7/bluetooth-cancel-power_on-work-when-unregistering-the-device.patch new file mode 100644 index 00000000000..958dd5a279e --- /dev/null +++ b/queue-3.7/bluetooth-cancel-power_on-work-when-unregistering-the-device.patch @@ -0,0 +1,64 @@ +From b9b5ef188e5a2222cfc16ef62a4703080750b451 Mon Sep 17 00:00:00 2001 +From: Gustavo Padovan +Date: Wed, 21 Nov 2012 00:50:21 -0200 +Subject: Bluetooth: cancel power_on work when unregistering the device + +From: Gustavo Padovan + +commit b9b5ef188e5a2222cfc16ef62a4703080750b451 upstream. + +We need to cancel the hci_power_on work in order to avoid it run when we +try to free the hdev. + +[ 1434.201149] ------------[ cut here ]------------ +[ 1434.204998] WARNING: at lib/debugobjects.c:261 debug_print_object+0x8e/0xb0() +[ 1434.208324] ODEBUG: free active (active state 0) object type: work_struct hint: hci +_power_on+0x0/0x90 +[ 1434.210386] Pid: 8564, comm: trinity-child25 Tainted: G W 3.7.0-rc5-next- +20121112-sasha-00018-g2f4ce0e #127 +[ 1434.210760] Call Trace: +[ 1434.210760] [] ? debug_print_object+0x8e/0xb0 +[ 1434.210760] [] warn_slowpath_common+0x87/0xb0 +[ 1434.210760] [] warn_slowpath_fmt+0x41/0x50 +[ 1434.210760] [] debug_print_object+0x8e/0xb0 +[ 1434.210760] [] ? hci_dev_open+0x310/0x310 +[ 1434.210760] [] ? _raw_spin_unlock_irqrestore+0x55/0xa0 +[ 1434.210760] [] __debug_check_no_obj_freed+0xa5/0x230 +[ 1434.210760] [] ? bt_host_release+0x10/0x20 +[ 1434.210760] [] debug_check_no_obj_freed+0x15/0x20 +[ 1434.210760] [] kfree+0x227/0x330 +[ 1434.210760] [] bt_host_release+0x10/0x20 +[ 1434.210760] [] device_release+0x65/0xc0 +[ 1434.210760] [] kobject_cleanup+0x145/0x190 +[ 1434.210760] [] kobject_release+0xd/0x10 +[ 1434.210760] [] kobject_put+0x4c/0x60 +[ 1434.210760] [] put_device+0x12/0x20 +[ 1434.210760] [] hci_free_dev+0x24/0x30 +[ 1434.210760] [] vhci_release+0x31/0x60 +[ 1434.210760] [] __fput+0x122/0x250 +[ 1434.210760] [] ? rcu_user_exit+0x9d/0xd0 +[ 1434.210760] [] ____fput+0x9/0x10 +[ 1434.210760] [] task_work_run+0xb2/0xf0 +[ 1434.210760] [] do_notify_resume+0x77/0xa0 +[ 1434.210760] [] int_signal+0x12/0x17 +[ 1434.210760] ---[ end trace a6d57fefbc8a8cc7 ]--- + +Reported-by: Sasha Levin +Signed-off-by: Gustavo Padovan +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/hci_core.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -1793,6 +1793,8 @@ void hci_unregister_dev(struct hci_dev * + for (i = 0; i < NUM_REASSEMBLY; i++) + kfree_skb(hdev->reassembly[i]); + ++ cancel_work_sync(&hdev->power_on); ++ + if (!test_bit(HCI_INIT, &hdev->flags) && + !test_bit(HCI_SETUP, &hdev->dev_flags)) { + hci_dev_lock(hdev); diff --git a/queue-3.7/cifs-adjust-sequence-number-downward-after-signing-nt_cancel.patch b/queue-3.7/cifs-adjust-sequence-number-downward-after-signing-nt_cancel.patch new file mode 100644 index 00000000000..edc2a338ed5 --- /dev/null +++ b/queue-3.7/cifs-adjust-sequence-number-downward-after-signing-nt_cancel.patch @@ -0,0 +1,41 @@ +From 31efee60f489c759c341454d755a9fd13de8c03d Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Thu, 27 Dec 2012 08:05:03 -0500 +Subject: cifs: adjust sequence number downward after signing NT_CANCEL request + +From: Jeff Layton + +commit 31efee60f489c759c341454d755a9fd13de8c03d upstream. + +When a call goes out, the signing code adjusts the sequence number +upward by two to account for the request and the response. An NT_CANCEL +however doesn't get a response of its own, it just hurries the server +along to get it to respond to the original request more quickly. +Therefore, we must adjust the sequence number back down by one after +signing a NT_CANCEL request. + +Reported-by: Tim Perry +Signed-off-by: Jeff Layton +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb1ops.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/fs/cifs/smb1ops.c ++++ b/fs/cifs/smb1ops.c +@@ -53,6 +53,13 @@ send_nt_cancel(struct TCP_Server_Info *s + mutex_unlock(&server->srv_mutex); + return rc; + } ++ ++ /* ++ * The response to this call was already factored into the sequence ++ * number when the call went out, so we must adjust it back downward ++ * after signing here. ++ */ ++ --server->sequence_number; + rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length)); + mutex_unlock(&server->srv_mutex); + diff --git a/queue-3.7/cifs-move-check-for-null-socket-into-smb_send_rqst.patch b/queue-3.7/cifs-move-check-for-null-socket-into-smb_send_rqst.patch new file mode 100644 index 00000000000..a0356dfd7f9 --- /dev/null +++ b/queue-3.7/cifs-move-check-for-null-socket-into-smb_send_rqst.patch @@ -0,0 +1,109 @@ +From ea702b80e0bbb2448e201472127288beb82ca2fe Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Thu, 27 Dec 2012 07:28:55 -0500 +Subject: cifs: move check for NULL socket into smb_send_rqst + +From: Jeff Layton + +commit ea702b80e0bbb2448e201472127288beb82ca2fe upstream. + +Cai reported this oops: + +[90701.616664] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028 +[90701.625438] IP: [] kernel_setsockopt+0x2e/0x60 +[90701.632167] PGD fea319067 PUD 103fda4067 PMD 0 +[90701.637255] Oops: 0000 [#1] SMP +[90701.640878] Modules linked in: des_generic md4 nls_utf8 cifs dns_resolver binfmt_misc tun sg igb iTCO_wdt iTCO_vendor_support lpc_ich pcspkr i2c_i801 i2c_core i7core_edac edac_core ioatdma dca mfd_core coretemp kvm_intel kvm crc32c_intel microcode sr_mod cdrom ata_generic sd_mod pata_acpi crc_t10dif ata_piix libata megaraid_sas dm_mirror dm_region_hash dm_log dm_mod +[90701.677655] CPU 10 +[90701.679808] Pid: 9627, comm: ls Tainted: G W 3.7.1+ #10 QCI QSSC-S4R/QSSC-S4R +[90701.688950] RIP: 0010:[] [] kernel_setsockopt+0x2e/0x60 +[90701.698383] RSP: 0018:ffff88177b431bb8 EFLAGS: 00010206 +[90701.704309] RAX: ffff88177b431fd8 RBX: 00007ffffffff000 RCX: ffff88177b431bec +[90701.712271] RDX: 0000000000000003 RSI: 0000000000000006 RDI: 0000000000000000 +[90701.720223] RBP: ffff88177b431bc8 R08: 0000000000000004 R09: 0000000000000000 +[90701.728185] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000001 +[90701.736147] R13: ffff88184ef92000 R14: 0000000000000023 R15: ffff88177b431c88 +[90701.744109] FS: 00007fd56a1a47c0(0000) GS:ffff88105fc40000(0000) knlGS:0000000000000000 +[90701.753137] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +[90701.759550] CR2: 0000000000000028 CR3: 000000104f15f000 CR4: 00000000000007e0 +[90701.767512] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[90701.775465] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +[90701.783428] Process ls (pid: 9627, threadinfo ffff88177b430000, task ffff88185ca4cb60) +[90701.792261] Stack: +[90701.794505] 0000000000000023 ffff88177b431c50 ffff88177b431c38 ffffffffa014fcb1 +[90701.802809] ffff88184ef921bc 0000000000000000 00000001ffffffff ffff88184ef921c0 +[90701.811123] ffff88177b431c08 ffffffff815ca3d9 ffff88177b431c18 ffff880857758000 +[90701.819433] Call Trace: +[90701.822183] [] smb_send_rqst+0x71/0x1f0 [cifs] +[90701.828991] [] ? schedule+0x29/0x70 +[90701.834736] [] smb_sendv+0x3d/0x40 [cifs] +[90701.841062] [] smb_send+0x26/0x30 [cifs] +[90701.847291] [] send_nt_cancel+0x6f/0xd0 [cifs] +[90701.854102] [] SendReceive+0x18e/0x360 [cifs] +[90701.860814] [] CIFSFindFirst+0x1a8/0x3f0 [cifs] +[90701.867724] [] ? build_path_from_dentry+0xf1/0x260 [cifs] +[90701.875601] [] ? build_path_from_dentry+0xf1/0x260 [cifs] +[90701.883477] [] cifs_query_dir_first+0x26/0x30 [cifs] +[90701.890869] [] initiate_cifs_search+0xed/0x250 [cifs] +[90701.898354] [] ? fillonedir+0x100/0x100 +[90701.904486] [] cifs_readdir+0x45b/0x8f0 [cifs] +[90701.911288] [] ? fillonedir+0x100/0x100 +[90701.917410] [] ? fillonedir+0x100/0x100 +[90701.923533] [] ? fillonedir+0x100/0x100 +[90701.929657] [] vfs_readdir+0xb8/0xe0 +[90701.935490] [] sys_getdents+0x8f/0x110 +[90701.941521] [] system_call_fastpath+0x16/0x1b +[90701.948222] Code: 66 90 55 65 48 8b 04 25 f0 c6 00 00 48 89 e5 53 48 83 ec 08 83 fe 01 48 8b 98 48 e0 ff ff 48 c7 80 48 e0 ff ff ff ff ff ff 74 22 <48> 8b 47 28 ff 50 68 65 48 8b 14 25 f0 c6 00 00 48 89 9a 48 e0 +[90701.970313] RIP [] kernel_setsockopt+0x2e/0x60 +[90701.977125] RSP +[90701.981018] CR2: 0000000000000028 +[90701.984809] ---[ end trace 24bd602971110a43 ]--- + +This is likely due to a race vs. a reconnection event. + +The current code checks for a NULL socket in smb_send_kvec, but that's +too late. By the time that check is done, the socket will already have +been passed to kernel_setsockopt. Move the check into smb_send_rqst, so +that it's checked earlier. + +In truth, this is a bit of a half-assed fix. The -ENOTSOCK error +return here looks like it could bubble back up to userspace. The locking +rules around the ssocket pointer are really unclear as well. There are +cases where the ssocket pointer is changed without holding the srv_mutex, +but I'm not clear whether there's a potential race here yet or not. + +This code seems like it could benefit from some fundamental re-think of +how the socket handling should behave. Until then though, this patch +should at least fix the above oops in most cases. + +Reported-and-Tested-by: CAI Qian +Signed-off-by: Jeff Layton +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/transport.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -144,9 +144,6 @@ smb_send_kvec(struct TCP_Server_Info *se + + *sent = 0; + +- if (ssocket == NULL) +- return -ENOTSOCK; /* BB eventually add reconnect code here */ +- + smb_msg.msg_name = (struct sockaddr *) &server->dstaddr; + smb_msg.msg_namelen = sizeof(struct sockaddr); + smb_msg.msg_control = NULL; +@@ -291,6 +288,9 @@ smb_send_rqst(struct TCP_Server_Info *se + struct socket *ssocket = server->ssocket; + int val = 1; + ++ if (ssocket == NULL) ++ return -ENOTSOCK; ++ + cFYI(1, "Sending smb: smb_len=%u", smb_buf_length); + dump_smb(iov[0].iov_base, iov[0].iov_len); + diff --git a/queue-3.7/fs-fix-imbalance-in-freeze-protection-in-mark_files_ro.patch b/queue-3.7/fs-fix-imbalance-in-freeze-protection-in-mark_files_ro.patch new file mode 100644 index 00000000000..4a22cfe9adc --- /dev/null +++ b/queue-3.7/fs-fix-imbalance-in-freeze-protection-in-mark_files_ro.patch @@ -0,0 +1,42 @@ +From 72651cac884b1e285fa8e8314b10e9f1b8458802 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Wed, 5 Dec 2012 14:40:14 +0100 +Subject: fs: Fix imbalance in freeze protection in mark_files_ro() + +From: Jan Kara + +commit 72651cac884b1e285fa8e8314b10e9f1b8458802 upstream. + +File descriptors (even those for writing) do not hold freeze protection. +Thus mark_files_ro() must call __mnt_drop_write() to only drop protection +against remount read-only. Calling mnt_drop_write_file() as we do now +results in: + +[ BUG: bad unlock balance detected! ] +3.7.0-rc6-00028-g88e75b6 #101 Not tainted +------------------------------------- +kworker/1:2/79 is trying to release lock (sb_writers) at: +[] mnt_drop_write+0x24/0x30 +but there are no more locks to release! + +Reported-by: Zdenek Kabelac +Signed-off-by: Jan Kara +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/file_table.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/file_table.c ++++ b/fs/file_table.c +@@ -458,8 +458,8 @@ void mark_files_ro(struct super_block *s + spin_unlock(&f->f_lock); + if (file_check_writeable(f) != 0) + continue; ++ __mnt_drop_write(f->f_path.mnt); + file_release_write(f); +- mnt_drop_write_file(f); + } while_file_list_for_each_entry; + lg_global_unlock(&files_lglock); + } diff --git a/queue-3.7/pci-pm-do-not-suspend-port-if-any-subordinate-device-needs-pme-polling.patch b/queue-3.7/pci-pm-do-not-suspend-port-if-any-subordinate-device-needs-pme-polling.patch new file mode 100644 index 00000000000..06e1d41b937 --- /dev/null +++ b/queue-3.7/pci-pm-do-not-suspend-port-if-any-subordinate-device-needs-pme-polling.patch @@ -0,0 +1,65 @@ +From c733b77475707cc3980542c86ee0ad5c841d544c Mon Sep 17 00:00:00 2001 +From: Huang Ying +Date: Wed, 26 Dec 2012 10:39:23 -0700 +Subject: PCI/PM: Do not suspend port if any subordinate device needs PME polling + +From: Huang Ying + +commit c733b77475707cc3980542c86ee0ad5c841d544c upstream. + +Ulrich reported that his USB3 cardreader does not work reliably when +connected to the USB3 port. It turns out that USB3 controller failed to +awaken when plugging in the USB3 cardreader. Further experiments found +that the USB3 host controller can only be awakened via polling, not via PME +interrupt. But if the PCIe port to which the USB3 host controller is +connected is suspended, we cannot poll the controller because its config +space is not accessible when the PCIe port is in a low power state. + +To solve the issue, the PCIe port will not be suspended if any subordinate +device needs PME polling. + +[bhelgaas: use bool consistently rather than mixing int/bool] +Reference: http://lkml.kernel.org/r/50841CCC.9030809@uli-eckhardt.de +Reported-by: Ulrich Eckhardt +Tested-by: Sarah Sharp +Signed-off-by: Huang Ying +Signed-off-by: Bjorn Helgaas +Acked-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pcie/portdrv_pci.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +--- a/drivers/pci/pcie/portdrv_pci.c ++++ b/drivers/pci/pcie/portdrv_pci.c +@@ -134,10 +134,28 @@ static int pcie_port_runtime_resume(stru + return 0; + } + ++static int pci_dev_pme_poll(struct pci_dev *pdev, void *data) ++{ ++ bool *pme_poll = data; ++ ++ if (pdev->pme_poll) ++ *pme_poll = true; ++ return 0; ++} ++ + static int pcie_port_runtime_idle(struct device *dev) + { ++ struct pci_dev *pdev = to_pci_dev(dev); ++ bool pme_poll = false; ++ ++ /* ++ * If any subordinate device needs pme poll, we should keep ++ * the port in D0, because we need port in D0 to poll it. ++ */ ++ pci_walk_bus(pdev->subordinate, pci_dev_pme_poll, &pme_poll); + /* Delay for a short while to prevent too frequent suspend/resume */ +- pm_schedule_suspend(dev, 10); ++ if (!pme_poll) ++ pm_schedule_suspend(dev, 10); + return -EBUSY; + } + #else diff --git a/queue-3.7/pci-pm-keep-runtime-pm-enabled-for-unbound-pci-devices.patch b/queue-3.7/pci-pm-keep-runtime-pm-enabled-for-unbound-pci-devices.patch new file mode 100644 index 00000000000..b5c781e236a --- /dev/null +++ b/queue-3.7/pci-pm-keep-runtime-pm-enabled-for-unbound-pci-devices.patch @@ -0,0 +1,182 @@ +From 967577b062417b4e4b8e27b711220f4124f5153a Mon Sep 17 00:00:00 2001 +From: Huang Ying +Date: Tue, 20 Nov 2012 16:08:22 +0800 +Subject: PCI/PM: Keep runtime PM enabled for unbound PCI devices + +From: Huang Ying + +commit 967577b062417b4e4b8e27b711220f4124f5153a upstream. + +For unbound PCI devices, what we need is: + + - Always in D0 state, because some devices do not work again after + being put into D3 by the PCI bus. + + - In SUSPENDED state if allowed, so that the parent devices can still + be put into low power state. + +To satisfy these requirements, the runtime PM for the unbound PCI +devices are disabled and set to SUSPENDED state. One issue of this +solution is that the PCI devices will be put into SUSPENDED state even +if the SUSPENDED state is forbidden via the sysfs interface +(.../power/control) of the device. This is not an issue for most +devices, because most PCI devices are not used at all if unbound. +But there are exceptions. For example, unbound VGA card can be used +for display, but suspending its parents makes it stop working. + +To fix the issue, we keep the runtime PM enabled when the PCI devices +are unbound. But the runtime PM callbacks will do nothing if the PCI +devices are unbound. This way, we can put the PCI devices into +SUSPENDED state without putting the PCI devices into D3 state. + +Reference: https://bugzilla.kernel.org/show_bug.cgi?id=48201 +Signed-off-by: Huang Ying +Signed-off-by: Bjorn Helgaas +Acked-by: Alan Stern +Acked-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pci-driver.c | 69 +++++++++++++++++++++++++++-------------------- + drivers/pci/pci.c | 2 + + 2 files changed, 43 insertions(+), 28 deletions(-) + +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -256,31 +256,26 @@ struct drv_dev_and_id { + static long local_pci_probe(void *_ddi) + { + struct drv_dev_and_id *ddi = _ddi; +- struct device *dev = &ddi->dev->dev; +- struct device *parent = dev->parent; ++ struct pci_dev *pci_dev = ddi->dev; ++ struct pci_driver *pci_drv = ddi->drv; ++ struct device *dev = &pci_dev->dev; + int rc; + +- /* The parent bridge must be in active state when probing */ +- if (parent) +- pm_runtime_get_sync(parent); +- /* Unbound PCI devices are always set to disabled and suspended. +- * During probe, the device is set to enabled and active and the +- * usage count is incremented. If the driver supports runtime PM, +- * it should call pm_runtime_put_noidle() in its probe routine and +- * pm_runtime_get_noresume() in its remove routine. +- */ +- pm_runtime_get_noresume(dev); +- pm_runtime_set_active(dev); +- pm_runtime_enable(dev); +- +- rc = ddi->drv->probe(ddi->dev, ddi->id); ++ /* ++ * Unbound PCI devices are always put in D0, regardless of ++ * runtime PM status. During probe, the device is set to ++ * active and the usage count is incremented. If the driver ++ * supports runtime PM, it should call pm_runtime_put_noidle() ++ * in its probe routine and pm_runtime_get_noresume() in its ++ * remove routine. ++ */ ++ pm_runtime_get_sync(dev); ++ pci_dev->driver = pci_drv; ++ rc = pci_drv->probe(pci_dev, ddi->id); + if (rc) { +- pm_runtime_disable(dev); +- pm_runtime_set_suspended(dev); +- pm_runtime_put_noidle(dev); ++ pci_dev->driver = NULL; ++ pm_runtime_put_sync(dev); + } +- if (parent) +- pm_runtime_put(parent); + return rc; + } + +@@ -330,10 +325,8 @@ __pci_device_probe(struct pci_driver *dr + id = pci_match_device(drv, pci_dev); + if (id) + error = pci_call_probe(drv, pci_dev, id); +- if (error >= 0) { +- pci_dev->driver = drv; ++ if (error >= 0) + error = 0; +- } + } + return error; + } +@@ -369,9 +362,7 @@ static int pci_device_remove(struct devi + } + + /* Undo the runtime PM settings in local_pci_probe() */ +- pm_runtime_disable(dev); +- pm_runtime_set_suspended(dev); +- pm_runtime_put_noidle(dev); ++ pm_runtime_put_sync(dev); + + /* + * If the device is still on, set the power state as "unknown", +@@ -994,6 +985,13 @@ static int pci_pm_runtime_suspend(struct + pci_power_t prev = pci_dev->current_state; + int error; + ++ /* ++ * If pci_dev->driver is not set (unbound), the device should ++ * always remain in D0 regardless of the runtime PM status ++ */ ++ if (!pci_dev->driver) ++ return 0; ++ + if (!pm || !pm->runtime_suspend) + return -ENOSYS; + +@@ -1029,6 +1027,13 @@ static int pci_pm_runtime_resume(struct + struct pci_dev *pci_dev = to_pci_dev(dev); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + ++ /* ++ * If pci_dev->driver is not set (unbound), the device should ++ * always remain in D0 regardless of the runtime PM status ++ */ ++ if (!pci_dev->driver) ++ return 0; ++ + if (!pm || !pm->runtime_resume) + return -ENOSYS; + +@@ -1046,8 +1051,16 @@ static int pci_pm_runtime_resume(struct + + static int pci_pm_runtime_idle(struct device *dev) + { ++ struct pci_dev *pci_dev = to_pci_dev(dev); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + ++ /* ++ * If pci_dev->driver is not set (unbound), the device should ++ * always remain in D0 regardless of the runtime PM status ++ */ ++ if (!pci_dev->driver) ++ goto out; ++ + if (!pm) + return -ENOSYS; + +@@ -1057,8 +1070,8 @@ static int pci_pm_runtime_idle(struct de + return ret; + } + ++out: + pm_runtime_suspend(dev); +- + return 0; + } + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1900,6 +1900,8 @@ void pci_pm_init(struct pci_dev *dev) + u16 pmc; + + pm_runtime_forbid(&dev->dev); ++ pm_runtime_set_active(&dev->dev); ++ pm_runtime_enable(&dev->dev); + device_enable_async_suspend(&dev->dev); + dev->wakeup_prepared = false; + diff --git a/queue-3.7/pci-reduce-ricoh-0xe822-sd-card-reader-base-clock-frequency-to-50mhz.patch b/queue-3.7/pci-reduce-ricoh-0xe822-sd-card-reader-base-clock-frequency-to-50mhz.patch new file mode 100644 index 00000000000..56adce11bd1 --- /dev/null +++ b/queue-3.7/pci-reduce-ricoh-0xe822-sd-card-reader-base-clock-frequency-to-50mhz.patch @@ -0,0 +1,70 @@ +From 812089e01b9f65f90fc8fc670d8cce72a0e01fbb Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Sat, 1 Dec 2012 12:37:20 -0800 +Subject: PCI: Reduce Ricoh 0xe822 SD card reader base clock frequency to 50MHz + +From: Andy Lutomirski + +commit 812089e01b9f65f90fc8fc670d8cce72a0e01fbb upstream. + +Otherwise it fails like this on cards like the Transcend 16GB SDHC card: + + mmc0: new SDHC card at address b368 + mmcblk0: mmc0:b368 SDC 15.0 GiB + mmcblk0: error -110 sending status command, retrying + mmcblk0: error -84 transferring data, sector 0, nr 8, cmd response 0x900, card status 0xb0 + +Tested on my Lenovo x200 laptop. + +[bhelgaas: changelog] +Signed-off-by: Andy Lutomirski +Signed-off-by: Bjorn Helgaas +Acked-by: Chris Ball +CC: Manoj Iyer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/quirks.c | 7 +++++-- + include/linux/pci_ids.h | 1 + + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -2686,7 +2686,7 @@ static void ricoh_mmc_fixup_r5c832(struc + if (PCI_FUNC(dev->devfn)) + return; + /* +- * RICOH 0xe823 SD/MMC card reader fails to recognize ++ * RICOH 0xe822 and 0xe823 SD/MMC card readers fail to recognize + * certain types of SD/MMC cards. Lowering the SD base + * clock frequency from 200Mhz to 50Mhz fixes this issue. + * +@@ -2697,7 +2697,8 @@ static void ricoh_mmc_fixup_r5c832(struc + * 0xf9 - Key register for 0x150 + * 0xfc - key register for 0xe1 + */ +- if (dev->device == PCI_DEVICE_ID_RICOH_R5CE823) { ++ if (dev->device == PCI_DEVICE_ID_RICOH_R5CE822 || ++ dev->device == PCI_DEVICE_ID_RICOH_R5CE823) { + pci_write_config_byte(dev, 0xf9, 0xfc); + pci_write_config_byte(dev, 0x150, 0x10); + pci_write_config_byte(dev, 0xf9, 0x00); +@@ -2724,6 +2725,8 @@ static void ricoh_mmc_fixup_r5c832(struc + } + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); + DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE822, ricoh_mmc_fixup_r5c832); ++DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE822, ricoh_mmc_fixup_r5c832); + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); + DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); + #endif /*CONFIG_MMC_RICOH_MMC*/ +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -1568,6 +1568,7 @@ + #define PCI_DEVICE_ID_RICOH_RL5C476 0x0476 + #define PCI_DEVICE_ID_RICOH_RL5C478 0x0478 + #define PCI_DEVICE_ID_RICOH_R5C822 0x0822 ++#define PCI_DEVICE_ID_RICOH_R5CE822 0xe822 + #define PCI_DEVICE_ID_RICOH_R5CE823 0xe823 + #define PCI_DEVICE_ID_RICOH_R5C832 0x0832 + #define PCI_DEVICE_ID_RICOH_R5C843 0x0843 diff --git a/queue-3.7/pci-work-around-stratus-ftserver-broken-pcie-hierarchy-fix-dmi-check.patch b/queue-3.7/pci-work-around-stratus-ftserver-broken-pcie-hierarchy-fix-dmi-check.patch new file mode 100644 index 00000000000..fa23d120046 --- /dev/null +++ b/queue-3.7/pci-work-around-stratus-ftserver-broken-pcie-hierarchy-fix-dmi-check.patch @@ -0,0 +1,39 @@ +From 1278998f8ff6d66044ed00b581bbf14aacaba215 Mon Sep 17 00:00:00 2001 +From: Myron Stowe +Date: Wed, 26 Dec 2012 10:39:23 -0700 +Subject: PCI: Work around Stratus ftServer broken PCIe hierarchy (fix DMI check) + +From: Myron Stowe + +commit 1278998f8ff6d66044ed00b581bbf14aacaba215 upstream. + +Commit 284f5f9 was intended to disable the "only_one_child()" optimization +on Stratus ftServer systems, but its DMI check is wrong. It looks for +DMI_SYS_VENDOR that contains "ftServer", when it should look for +DMI_SYS_VENDOR containing "Stratus" and DMI_PRODUCT_NAME containing +"ftServer". + +Tested on Stratus ftServer 6400. + +Reported-by: Fadeeva Marina +Reference: https://bugzilla.kernel.org/show_bug.cgi?id=51331 +Signed-off-by: Myron Stowe +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/pci/common.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/x86/pci/common.c ++++ b/arch/x86/pci/common.c +@@ -433,7 +433,8 @@ static const struct dmi_system_id __devi + .callback = set_scan_all, + .ident = "Stratus/NEC ftServer", + .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "ftServer"), ++ DMI_MATCH(DMI_SYS_VENDOR, "Stratus"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "ftServer"), + }, + }, + {} diff --git a/queue-3.7/printk-fix-incorrect-length-from-print_time-when-seconds-99999.patch b/queue-3.7/printk-fix-incorrect-length-from-print_time-when-seconds-99999.patch new file mode 100644 index 00000000000..2efaf6a2a10 --- /dev/null +++ b/queue-3.7/printk-fix-incorrect-length-from-print_time-when-seconds-99999.patch @@ -0,0 +1,68 @@ +From 35dac27cedd14c3b6fcd4ba7bc3c31738cfd1831 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Fri, 4 Jan 2013 15:35:50 -0800 +Subject: printk: fix incorrect length from print_time() when seconds > 99999 + +From: Roland Dreier + +commit 35dac27cedd14c3b6fcd4ba7bc3c31738cfd1831 upstream. + +print_prefix() passes a NULL buf to print_time() to get the length of +the time prefix; when printk times are enabled, the current code just +returns the constant 15, which matches the format "[%5lu.%06lu] " used +to print the time value. However, this is obviously incorrect when the +whole seconds part of the time gets beyond 5 digits (100000 seconds is a +bit more than a day of uptime). + +The simple fix is to use snprintf(NULL, 0, ...) to calculate the actual +length of the time prefix. This could be micro-optimized but it seems +better to have simpler, more readable code here. + +The bug leads to the syslog system call miscomputing which messages fit +into the userspace buffer. If there are enough messages to fill +log_buf_len and some have a timestamp >= 100000, dmesg may fail with: + + # dmesg + klogctl: Bad address + +When this happens, strace shows that the failure is indeed EFAULT due to +the kernel mistakenly accessing past the end of dmesg's buffer, since +dmesg asks the kernel how big a buffer it needs, allocates a bit more, +and then gets an error when it asks the kernel to fill it: + + syslog(0xa, 0, 0) = 1048576 + mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa4d25d2000 + syslog(0x3, 0x7fa4d25d2010, 0x100008) = -1 EFAULT (Bad address) + +As far as I can see, the bug has been there as long as print_time(), +which comes from commit 084681d14e42 ("printk: flush continuation lines +immediately to console") in 3.5-rc5. + +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman +Cc: Joe Perches +Cc: Sylvain Munaut +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/printk.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/kernel/printk.c ++++ b/kernel/printk.c +@@ -847,10 +847,11 @@ static size_t print_time(u64 ts, char *b + if (!printk_time) + return 0; + ++ rem_nsec = do_div(ts, 1000000000); ++ + if (!buf) +- return 15; ++ return snprintf(NULL, 0, "[%5lu.000000] ", (unsigned long)ts); + +- rem_nsec = do_div(ts, 1000000000); + return sprintf(buf, "[%5lu.%06lu] ", + (unsigned long)ts, rem_nsec / 1000); + } diff --git a/queue-3.7/revert-bluetooth-fix-possible-deadlock-in-sco-code.patch b/queue-3.7/revert-bluetooth-fix-possible-deadlock-in-sco-code.patch new file mode 100644 index 00000000000..e12add53cbb --- /dev/null +++ b/queue-3.7/revert-bluetooth-fix-possible-deadlock-in-sco-code.patch @@ -0,0 +1,71 @@ +From 0b27a4b97cb1874503c78453c0903df53c0c86b2 Mon Sep 17 00:00:00 2001 +From: Gustavo Padovan +Date: Mon, 3 Dec 2012 15:36:51 -0200 +Subject: Revert "Bluetooth: Fix possible deadlock in SCO code" + +From: Gustavo Padovan + +commit 0b27a4b97cb1874503c78453c0903df53c0c86b2 upstream. + +This reverts commit 269c4845d5b3627b95b1934107251bacbe99bb68. + +The commit was causing dead locks and NULL dereferences in the sco code: + + [28084.104013] BUG: soft lockup - CPU#0 stuck for 22s! [kworker/u:0H:7] + [28084.104021] Modules linked in: btusb bluetooth ] _raw_spin_lock+0xd/0x10 + [28084.104021] [] sco_conn_del+0x58/0x1b0 [bluetooth] + [28084.104021] [] sco_connect_cfm+0xb9/0x2b0 [bluetooth] + [28084.104021] [] +hci_sync_conn_complete_evt.isra.94+0x1c9/0x260 [bluetooth] + [28084.104021] [] hci_event_packet+0x74d/0x2b40 [bluetooth] + [28084.104021] [] ? __kfree_skb+0x3d/0x90 + [28084.104021] [] ? kfree_skb+0x36/0x90 + [28084.104021] [] ? hci_send_to_monitor+0x10e/0x190 [bluetooth] + [28084.104021] [] ? hci_send_to_monitor+0x10e/0x190 [bluetooth] + +Reported-by: Chan-yeol Park +Signed-off-by: Gustavo Padovan +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/sco.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +--- a/net/bluetooth/sco.c ++++ b/net/bluetooth/sco.c +@@ -131,15 +131,6 @@ static int sco_conn_del(struct hci_conn + sco_sock_clear_timer(sk); + sco_chan_del(sk, err); + bh_unlock_sock(sk); +- +- sco_conn_lock(conn); +- conn->sk = NULL; +- sco_pi(sk)->conn = NULL; +- sco_conn_unlock(conn); +- +- if (conn->hcon) +- hci_conn_put(conn->hcon); +- + sco_sock_kill(sk); + } + +@@ -830,6 +821,16 @@ static void sco_chan_del(struct sock *sk + + BT_DBG("sk %p, conn %p, err %d", sk, conn, err); + ++ if (conn) { ++ sco_conn_lock(conn); ++ conn->sk = NULL; ++ sco_pi(sk)->conn = NULL; ++ sco_conn_unlock(conn); ++ ++ if (conn->hcon) ++ hci_conn_put(conn->hcon); ++ } ++ + sk->sk_state = BT_CLOSED; + sk->sk_err = err; + sk->sk_state_change(sk); diff --git a/queue-3.7/series b/queue-3.7/series index e374fb4dfb7..b20e875ee84 100644 --- a/queue-3.7/series +++ b/queue-3.7/series @@ -88,3 +88,24 @@ mac802154-fix-nohz-local_softirq_pending-08-warning.patch net-sched-integer-overflow-fix.patch sctp-jsctp_sf_eat_sack-fix-jprobes-function-signature-mismatch.patch tcp-fix-msg_sendpage_notlast-logic.patch +printk-fix-incorrect-length-from-print_time-when-seconds-99999.patch +signals-sys_ssetmask-uses-uninitialized-newmask.patch +xfs-fix-direct-io-nested-transaction-deadlock.patch +xfs-fix-stray-dquot-unlock-when-reclaiming-dquots.patch +arm64-compat-for-clock_adjtime-2-is-miswired.patch +arm-mm-use-pteval_t-to-represent-page-protection-values.patch +arm-missing-mmap_sem-around-find_vma-in-swp_emulate.c.patch +arm-7607-1-realview-fix-private-peripheral-memory-base-for-eb-rev.-b-boards.patch +arm-7606-1-cache-flush-to-louu-instead-of-louis-on-uniprocessor-cpus.patch +fs-fix-imbalance-in-freeze-protection-in-mark_files_ro.patch +cifs-move-check-for-null-socket-into-smb_send_rqst.patch +cifs-adjust-sequence-number-downward-after-signing-nt_cancel.patch +solos-pci-fix-double-free-of-tx-skb-in-dma-mode.patch +pci-pm-keep-runtime-pm-enabled-for-unbound-pci-devices.patch +pci-reduce-ricoh-0xe822-sd-card-reader-base-clock-frequency-to-50mhz.patch +pci-pm-do-not-suspend-port-if-any-subordinate-device-needs-pme-polling.patch +pci-work-around-stratus-ftserver-broken-pcie-hierarchy-fix-dmi-check.patch +bluetooth-add-support-for-bcm20702a0.patch +bluetooth-add-missing-lock-nesting-notation.patch +bluetooth-cancel-power_on-work-when-unregistering-the-device.patch +revert-bluetooth-fix-possible-deadlock-in-sco-code.patch diff --git a/queue-3.7/signals-sys_ssetmask-uses-uninitialized-newmask.patch b/queue-3.7/signals-sys_ssetmask-uses-uninitialized-newmask.patch new file mode 100644 index 00000000000..d0dc1f48d79 --- /dev/null +++ b/queue-3.7/signals-sys_ssetmask-uses-uninitialized-newmask.patch @@ -0,0 +1,36 @@ +From 5ba53ff648e785445a32ba39112ed07e4cf588d0 Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Sat, 5 Jan 2013 19:13:13 +0100 +Subject: signals: sys_ssetmask() uses uninitialized newmask + +From: Oleg Nesterov + +commit 5ba53ff648e785445a32ba39112ed07e4cf588d0 upstream. + +Commit 77097ae503b1 ("most of set_current_blocked() callers want +SIGKILL/SIGSTOP removed from set") removed the initialization of newmask +by accident, causing ltp to complain like this: + + ssetmask01 1 TFAIL : sgetmask() failed: TEST_ERRNO=???(0): Success + +Restore the proper initialization. + +Reported-and-tested-by: CAI Qian +Signed-off-by: Oleg Nesterov +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/signal.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -3221,6 +3221,7 @@ SYSCALL_DEFINE1(ssetmask, int, newmask) + int old = current->blocked.sig[0]; + sigset_t newset; + ++ siginitset(&newset, newmask); + set_current_blocked(&newset); + + return old; diff --git a/queue-3.7/solos-pci-fix-double-free-of-tx-skb-in-dma-mode.patch b/queue-3.7/solos-pci-fix-double-free-of-tx-skb-in-dma-mode.patch new file mode 100644 index 00000000000..64207eb5210 --- /dev/null +++ b/queue-3.7/solos-pci-fix-double-free-of-tx-skb-in-dma-mode.patch @@ -0,0 +1,38 @@ +From cae49ede00ec3d0cda290b03fee55b72b49efc11 Mon Sep 17 00:00:00 2001 +From: David Woodhouse +Date: Tue, 11 Dec 2012 14:57:14 +0000 +Subject: solos-pci: fix double-free of TX skb in DMA mode + +From: David Woodhouse + +commit cae49ede00ec3d0cda290b03fee55b72b49efc11 upstream. + +We weren't clearing card->tx_skb[port] when processing the TX done interrupt. +If there wasn't another skb ready to transmit immediately, this led to a +double-free because we'd free it *again* next time we did have a packet to +send. + +Signed-off-by: David Woodhouse +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/atm/solos-pci.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -967,10 +967,11 @@ static uint32_t fpga_tx(struct solos_car + for (port = 0; tx_pending; tx_pending >>= 1, port++) { + if (tx_pending & 1) { + struct sk_buff *oldskb = card->tx_skb[port]; +- if (oldskb) ++ if (oldskb) { + pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr, + oldskb->len, PCI_DMA_TODEVICE); +- ++ card->tx_skb[port] = NULL; ++ } + spin_lock(&card->tx_queue_lock); + skb = skb_dequeue(&card->tx_queue[port]); + if (!skb) diff --git a/queue-3.7/xfs-fix-direct-io-nested-transaction-deadlock.patch b/queue-3.7/xfs-fix-direct-io-nested-transaction-deadlock.patch new file mode 100644 index 00000000000..195c9937ad0 --- /dev/null +++ b/queue-3.7/xfs-fix-direct-io-nested-transaction-deadlock.patch @@ -0,0 +1,229 @@ +From 437a255aa23766666aec78af63be4c253faa8d57 Mon Sep 17 00:00:00 2001 +From: Dave Chinner +Date: Wed, 28 Nov 2012 13:01:00 +1100 +Subject: xfs: fix direct IO nested transaction deadlock. + +From: Dave Chinner + +commit 437a255aa23766666aec78af63be4c253faa8d57 upstream. + +The direct IO path can do a nested transaction reservation when +writing past the EOF. The first transaction is the append +transaction for setting the filesize at IO completion, but we can +also need a transaction for allocation of blocks. If the log is low +on space due to reservations and small log, the append transaction +can be granted after wating for space as the only active transaction +in the system. This then attempts a reservation for an allocation, +which there isn't space in the log for, and the reservation sleeps. +The result is that there is nothing left in the system to wake up +all the processes waiting for log space to come free. + +The stack trace that shows this deadlock is relatively innocuous: + + xlog_grant_head_wait + xlog_grant_head_check + xfs_log_reserve + xfs_trans_reserve + xfs_iomap_write_direct + __xfs_get_blocks + xfs_get_blocks_direct + do_blockdev_direct_IO + __blockdev_direct_IO + xfs_vm_direct_IO + generic_file_direct_write + xfs_file_dio_aio_writ + xfs_file_aio_write + do_sync_write + vfs_write + +This was discovered on a filesystem with a log of only 10MB, and a +log stripe unit of 256k whih increased the base reservations by +512k. Hence a allocation transaction requires 1.2MB of log space to +be available instead of only 260k, and so greatly increased the +chance that there wouldn't be enough log space available for the +nested transaction to succeed. The key to reproducing it is this +mkfs command: + +mkfs.xfs -f -d agcount=16,su=256k,sw=12 -l su=256k,size=2560b $SCRATCH_DEV + +The test case was a 1000 fsstress processes running with random +freeze and unfreezes every few seconds. Thanks to Eryu Guan +(eguan@redhat.com) for writing the test that found this on a system +with a somewhat unique default configuration.... + +Signed-off-by: Dave Chinner +Reviewed-by: Christoph Hellwig +Reviewed-by: Andrew Dahl +Signed-off-by: Ben Myers +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/xfs_aops.c | 81 +++++++++++++++++++----------------------------------- + fs/xfs/xfs_log.c | 3 +- + 2 files changed, 31 insertions(+), 53 deletions(-) + +--- a/fs/xfs/xfs_aops.c ++++ b/fs/xfs/xfs_aops.c +@@ -124,7 +124,7 @@ xfs_setfilesize_trans_alloc( + ioend->io_append_trans = tp; + + /* +- * We will pass freeze protection with a transaction. So tell lockdep ++ * We may pass freeze protection with a transaction. So tell lockdep + * we released it. + */ + rwsem_release(&ioend->io_inode->i_sb->s_writers.lock_map[SB_FREEZE_FS-1], +@@ -149,11 +149,13 @@ xfs_setfilesize( + xfs_fsize_t isize; + + /* +- * The transaction was allocated in the I/O submission thread, +- * thus we need to mark ourselves as beeing in a transaction +- * manually. ++ * The transaction may have been allocated in the I/O submission thread, ++ * thus we need to mark ourselves as beeing in a transaction manually. ++ * Similarly for freeze protection. + */ + current_set_flags_nested(&tp->t_pflags, PF_FSTRANS); ++ rwsem_acquire_read(&VFS_I(ip)->i_sb->s_writers.lock_map[SB_FREEZE_FS-1], ++ 0, 1, _THIS_IP_); + + xfs_ilock(ip, XFS_ILOCK_EXCL); + isize = xfs_new_eof(ip, ioend->io_offset + ioend->io_size); +@@ -187,7 +189,8 @@ xfs_finish_ioend( + + if (ioend->io_type == XFS_IO_UNWRITTEN) + queue_work(mp->m_unwritten_workqueue, &ioend->io_work); +- else if (ioend->io_append_trans) ++ else if (ioend->io_append_trans || ++ (ioend->io_isdirect && xfs_ioend_is_append(ioend))) + queue_work(mp->m_data_workqueue, &ioend->io_work); + else + xfs_destroy_ioend(ioend); +@@ -205,15 +208,6 @@ xfs_end_io( + struct xfs_inode *ip = XFS_I(ioend->io_inode); + int error = 0; + +- if (ioend->io_append_trans) { +- /* +- * We've got freeze protection passed with the transaction. +- * Tell lockdep about it. +- */ +- rwsem_acquire_read( +- &ioend->io_inode->i_sb->s_writers.lock_map[SB_FREEZE_FS-1], +- 0, 1, _THIS_IP_); +- } + if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { + ioend->io_error = -EIO; + goto done; +@@ -226,35 +220,31 @@ xfs_end_io( + * range to normal written extens after the data I/O has finished. + */ + if (ioend->io_type == XFS_IO_UNWRITTEN) { ++ error = xfs_iomap_write_unwritten(ip, ioend->io_offset, ++ ioend->io_size); ++ } else if (ioend->io_isdirect && xfs_ioend_is_append(ioend)) { + /* +- * For buffered I/O we never preallocate a transaction when +- * doing the unwritten extent conversion, but for direct I/O +- * we do not know if we are converting an unwritten extent +- * or not at the point where we preallocate the transaction. ++ * For direct I/O we do not know if we need to allocate blocks ++ * or not so we can't preallocate an append transaction as that ++ * results in nested reservations and log space deadlocks. Hence ++ * allocate the transaction here. While this is sub-optimal and ++ * can block IO completion for some time, we're stuck with doing ++ * it this way until we can pass the ioend to the direct IO ++ * allocation callbacks and avoid nesting that way. + */ +- if (ioend->io_append_trans) { +- ASSERT(ioend->io_isdirect); +- +- current_set_flags_nested( +- &ioend->io_append_trans->t_pflags, PF_FSTRANS); +- xfs_trans_cancel(ioend->io_append_trans, 0); +- } +- +- error = xfs_iomap_write_unwritten(ip, ioend->io_offset, +- ioend->io_size); +- if (error) { +- ioend->io_error = -error; ++ error = xfs_setfilesize_trans_alloc(ioend); ++ if (error) + goto done; +- } ++ error = xfs_setfilesize(ioend); + } else if (ioend->io_append_trans) { + error = xfs_setfilesize(ioend); +- if (error) +- ioend->io_error = -error; + } else { + ASSERT(!xfs_ioend_is_append(ioend)); + } + + done: ++ if (error) ++ ioend->io_error = -error; + xfs_destroy_ioend(ioend); + } + +@@ -1432,25 +1422,21 @@ xfs_vm_direct_IO( + size_t size = iov_length(iov, nr_segs); + + /* +- * We need to preallocate a transaction for a size update +- * here. In the case that this write both updates the size +- * and converts at least on unwritten extent we will cancel +- * the still clean transaction after the I/O has finished. ++ * We cannot preallocate a size update transaction here as we ++ * don't know whether allocation is necessary or not. Hence we ++ * can only tell IO completion that one is necessary if we are ++ * not doing unwritten extent conversion. + */ + iocb->private = ioend = xfs_alloc_ioend(inode, XFS_IO_DIRECT); +- if (offset + size > XFS_I(inode)->i_d.di_size) { +- ret = xfs_setfilesize_trans_alloc(ioend); +- if (ret) +- goto out_destroy_ioend; ++ if (offset + size > XFS_I(inode)->i_d.di_size) + ioend->io_isdirect = 1; +- } + + ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov, + offset, nr_segs, + xfs_get_blocks_direct, + xfs_end_io_direct_write, NULL, 0); + if (ret != -EIOCBQUEUED && iocb->private) +- goto out_trans_cancel; ++ goto out_destroy_ioend; + } else { + ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov, + offset, nr_segs, +@@ -1460,15 +1446,6 @@ xfs_vm_direct_IO( + + return ret; + +-out_trans_cancel: +- if (ioend->io_append_trans) { +- current_set_flags_nested(&ioend->io_append_trans->t_pflags, +- PF_FSTRANS); +- rwsem_acquire_read( +- &inode->i_sb->s_writers.lock_map[SB_FREEZE_FS-1], +- 0, 1, _THIS_IP_); +- xfs_trans_cancel(ioend->io_append_trans, 0); +- } + out_destroy_ioend: + xfs_destroy_ioend(ioend); + return ret; +--- a/fs/xfs/xfs_log.c ++++ b/fs/xfs/xfs_log.c +@@ -458,7 +458,8 @@ xfs_log_reserve( + tic->t_trans_type = t_type; + *ticp = tic; + +- xlog_grant_push_ail(log, tic->t_unit_res * tic->t_cnt); ++ xlog_grant_push_ail(log, tic->t_cnt ? tic->t_unit_res * tic->t_cnt ++ : tic->t_unit_res); + + trace_xfs_log_reserve(log, tic); + diff --git a/queue-3.7/xfs-fix-stray-dquot-unlock-when-reclaiming-dquots.patch b/queue-3.7/xfs-fix-stray-dquot-unlock-when-reclaiming-dquots.patch new file mode 100644 index 00000000000..76c9727e1a6 --- /dev/null +++ b/queue-3.7/xfs-fix-stray-dquot-unlock-when-reclaiming-dquots.patch @@ -0,0 +1,83 @@ +From b870553cdecb26d5291af09602352b763e323df2 Mon Sep 17 00:00:00 2001 +From: Dave Chinner +Date: Wed, 28 Nov 2012 13:01:02 +1100 +Subject: xfs: fix stray dquot unlock when reclaiming dquots + +From: Dave Chinner + +commit b870553cdecb26d5291af09602352b763e323df2 upstream. + +When we fail to get a dquot lock during reclaim, we jump to an error +handler that unlocks the dquot. This is wrong as we didn't lock the +dquot, and unlocking it means who-ever is holding the lock has had +it silently taken away, and hence it results in a lock imbalance. + +Found by inspection while modifying the code for the numa-lru +patchset. This fixes a random hang I've been seeing on xfstest 232 +for the past several months. + +Signed-off-by: Dave Chinner +Reviewed-by: Christoph Hellwig +Signed-off-by: Ben Myers +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/xfs_qm.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +--- a/fs/xfs/xfs_qm.c ++++ b/fs/xfs/xfs_qm.c +@@ -1453,7 +1453,7 @@ xfs_qm_dqreclaim_one( + int error; + + if (!xfs_dqlock_nowait(dqp)) +- goto out_busy; ++ goto out_move_tail; + + /* + * This dquot has acquired a reference in the meantime remove it from +@@ -1476,7 +1476,7 @@ xfs_qm_dqreclaim_one( + * getting flushed to disk, we don't want to reclaim it. + */ + if (!xfs_dqflock_nowait(dqp)) +- goto out_busy; ++ goto out_unlock_move_tail; + + if (XFS_DQ_IS_DIRTY(dqp)) { + struct xfs_buf *bp = NULL; +@@ -1487,7 +1487,7 @@ xfs_qm_dqreclaim_one( + if (error) { + xfs_warn(mp, "%s: dquot %p flush failed", + __func__, dqp); +- goto out_busy; ++ goto out_unlock_move_tail; + } + + xfs_buf_delwri_queue(bp, buffer_list); +@@ -1496,7 +1496,7 @@ xfs_qm_dqreclaim_one( + * Give the dquot another try on the freelist, as the + * flushing will take some time. + */ +- goto out_busy; ++ goto out_unlock_move_tail; + } + xfs_dqfunlock(dqp); + +@@ -1515,14 +1515,13 @@ xfs_qm_dqreclaim_one( + XFS_STATS_INC(xs_qm_dqreclaims); + return; + +-out_busy: +- xfs_dqunlock(dqp); +- + /* + * Move the dquot to the tail of the list so that we don't spin on it. + */ ++out_unlock_move_tail: ++ xfs_dqunlock(dqp); ++out_move_tail: + list_move_tail(&dqp->q_lru, &qi->qi_lru_list); +- + trace_xfs_dqreclaim_busy(dqp); + XFS_STATS_INC(xs_qm_dqreclaim_misses); + }