From: Greg Kroah-Hartman Date: Tue, 26 Mar 2013 18:28:59 +0000 (-0700) Subject: 3.8-stable patches X-Git-Tag: v3.0.71~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=40f905731d7f89f72b79af4ee47e7558bf6236e5;p=thirdparty%2Fkernel%2Fstable-queue.git 3.8-stable patches added patches: acpi-rework-acpi_get_child-to-be-more-efficient.patch clockevents-don-t-allow-dummy-broadcast-timers.patch efivars-add-module-parameter-to-disable-use-as-a-pstore-backend.patch efivars-allow-disabling-use-as-a-pstore-backend.patch efivars-fix-check-for-config_efi_vars_pstore_default_disable.patch ext4-fix-data-journal-fast-mount-umount-hang.patch ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch ext4-use-s_extent_max_zeroout_kb-value-as-number-of-kb.patch ipoib-fix-send-lockup-due-to-missed-tx-completion.patch md-raid5-avoid-accessing-gendisk-or-queue-structs-when-not-available.patch md-raid5-ensure-sync-and-discard-don-t-happen-at-the-same-time.patch md-raid5-schedule_construction-should-abort-if-nothing-to-do.patch nfsd-fix-bad-offset-use.patch usb-cdc-acm-fix-device-unregistration.patch usb-ehci-fix-regression-during-bus-resume.patch usb-ehci-fix-regression-in-qh-unlinking.patch usb-gadget-ffs-fix-enable-multiple-instances.patch usb-serial-fix-interface-refcounting.patch usb-storage-add-unusual_devs-entry-for-samsung-yp-z3-mp3-player.patch usb-xhci-correctly-enable-interrupts.patch usb-xhci-fix-bit-definitions-for-iman-register.patch watchdog-sp5100_tco-remove-code-that-may-cause-a-boot-failure.patch watchdog-sp5100_tco-set-the-acpimmiosel-bitmask-value-to-1-instead-of-2.patch x86-64-fix-the-failure-case-in-copy_user_handle_tail.patch --- diff --git a/queue-3.8/acpi-rework-acpi_get_child-to-be-more-efficient.patch b/queue-3.8/acpi-rework-acpi_get_child-to-be-more-efficient.patch new file mode 100644 index 00000000000..e9bde1c004a --- /dev/null +++ b/queue-3.8/acpi-rework-acpi_get_child-to-be-more-efficient.patch @@ -0,0 +1,85 @@ +From 33f767d767e9a684e9cd60704d4c049a2014c8d5 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Thu, 10 Jan 2013 13:13:49 +0100 +Subject: ACPI: Rework acpi_get_child() to be more efficient + +From: "Rafael J. Wysocki" + +commit 33f767d767e9a684e9cd60704d4c049a2014c8d5 upstream. + +Observe that acpi_get_child() doesn't need to use the helper +struct acpi_find_child structure and change it to work without it. +Also, using acpi_get_object_info() to get the output of _ADR for the +given device is overkill, because that function does much more than +just evaluating _ADR (let alone the additional memory allocation +done by it). + +Moreover, acpi_get_child() doesn't need to loop any more once it has +found a matching handle, so make it stop in that case. To prevent +the results from changing, make it use do_acpi_find_child() as +a post-order callback. + +Signed-off-by: Rafael J. Wysocki +Cc: Josh Boyer +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/acpi/glue.c | 33 ++++++++++++--------------------- + 1 file changed, 12 insertions(+), 21 deletions(-) + +--- a/drivers/acpi/glue.c ++++ b/drivers/acpi/glue.c +@@ -95,40 +95,31 @@ static int acpi_find_bridge_device(struc + return ret; + } + +-/* Get device's handler per its address under its parent */ +-struct acpi_find_child { +- acpi_handle handle; +- u64 address; +-}; +- +-static acpi_status +-do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) ++static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used, ++ void *addr_p, void **ret_p) + { ++ unsigned long long addr; + acpi_status status; +- struct acpi_device_info *info; +- struct acpi_find_child *find = context; + +- status = acpi_get_object_info(handle, &info); +- if (ACPI_SUCCESS(status)) { +- if ((info->address == find->address) +- && (info->valid & ACPI_VALID_ADR)) +- find->handle = handle; +- kfree(info); ++ status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr); ++ if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) { ++ *ret_p = handle; ++ return AE_CTRL_TERMINATE; + } + return AE_OK; + } + + acpi_handle acpi_get_child(acpi_handle parent, u64 address) + { +- struct acpi_find_child find = { NULL, address }; ++ void *ret = NULL; + + if (!parent) + return NULL; +- acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, +- 1, do_acpi_find_child, NULL, &find, NULL); +- return find.handle; +-} + ++ acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, NULL, ++ do_acpi_find_child, &address, &ret); ++ return (acpi_handle)ret; ++} + EXPORT_SYMBOL(acpi_get_child); + + static int acpi_bind_one(struct device *dev, acpi_handle handle) diff --git a/queue-3.8/clockevents-don-t-allow-dummy-broadcast-timers.patch b/queue-3.8/clockevents-don-t-allow-dummy-broadcast-timers.patch new file mode 100644 index 00000000000..7a6e990bd4e --- /dev/null +++ b/queue-3.8/clockevents-don-t-allow-dummy-broadcast-timers.patch @@ -0,0 +1,41 @@ +From a7dc19b8652c862d5b7c4d2339bd3c428bd29c4a Mon Sep 17 00:00:00 2001 +From: Mark Rutland +Date: Thu, 7 Mar 2013 15:09:24 +0000 +Subject: clockevents: Don't allow dummy broadcast timers + +From: Mark Rutland + +commit a7dc19b8652c862d5b7c4d2339bd3c428bd29c4a upstream. + +Currently tick_check_broadcast_device doesn't reject clock_event_devices +with CLOCK_EVT_FEAT_DUMMY, and may select them in preference to real +hardware if they have a higher rating value. In this situation, the +dummy timer is responsible for broadcasting to itself, and the core +clockevents code may attempt to call non-existent callbacks for +programming the dummy, eventually leading to a panic. + +This patch makes tick_check_broadcast_device always reject dummy timers, +preventing this problem. + +Signed-off-by: Mark Rutland +Cc: linux-arm-kernel@lists.infradead.org +Cc: Jon Medhurst (Tixy) +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/tick-broadcast.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/time/tick-broadcast.c ++++ b/kernel/time/tick-broadcast.c +@@ -66,7 +66,8 @@ static void tick_broadcast_start_periodi + */ + int tick_check_broadcast_device(struct clock_event_device *dev) + { +- if ((tick_broadcast_device.evtdev && ++ if ((dev->features & CLOCK_EVT_FEAT_DUMMY) || ++ (tick_broadcast_device.evtdev && + tick_broadcast_device.evtdev->rating >= dev->rating) || + (dev->features & CLOCK_EVT_FEAT_C3STOP)) + return 0; diff --git a/queue-3.8/efivars-add-module-parameter-to-disable-use-as-a-pstore-backend.patch b/queue-3.8/efivars-add-module-parameter-to-disable-use-as-a-pstore-backend.patch new file mode 100644 index 00000000000..e01deff6ed4 --- /dev/null +++ b/queue-3.8/efivars-add-module-parameter-to-disable-use-as-a-pstore-backend.patch @@ -0,0 +1,76 @@ +From ec0971ba5372a4dfa753f232449d23a8fd98490e Mon Sep 17 00:00:00 2001 +From: Seth Forshee +Date: Mon, 11 Mar 2013 16:17:50 -0500 +Subject: efivars: Add module parameter to disable use as a pstore backend + +From: Seth Forshee + +commit ec0971ba5372a4dfa753f232449d23a8fd98490e upstream. + +We know that with some firmware implementations writing too much data to +UEFI variables can lead to bricking machines. Recent changes attempt to +address this issue, but for some it may still be prudent to avoid +writing large amounts of data until the solution has been proven on a +wide variety of hardware. + +Crash dumps or other data from pstore can potentially be a large data +source. Add a pstore_module parameter to efivars to allow disabling its +use as a backend for pstore. Also add a config option, +CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE, to allow setting the default +value of this paramter to true (i.e. disabled by default). + +Signed-off-by: Seth Forshee +Cc: Josh Boyer +Cc: Matthew Garrett +Cc: Seiji Aguchi +Cc: Tony Luck +Signed-off-by: Matt Fleming +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firmware/Kconfig | 9 +++++++++ + drivers/firmware/efivars.c | 8 +++++++- + 2 files changed, 16 insertions(+), 1 deletion(-) + +--- a/drivers/firmware/Kconfig ++++ b/drivers/firmware/Kconfig +@@ -62,6 +62,15 @@ config EFI_VARS_PSTORE + will allow writing console messages, crash dumps, or anything + else supported by pstore to EFI variables. + ++config EFI_VARS_PSTORE_DEFAULT_DISABLE ++ bool "Disable using efivars as a pstore backend by default" ++ depends on EFI_VARS_PSTORE ++ default n ++ help ++ Saying Y here will disable the use of efivars as a storage ++ backend for pstore by default. This setting can be overridden ++ using the efivars module's pstore_disable parameter. ++ + config EFI_PCDP + bool "Console device selection via EFI PCDP or HCDP table" + depends on ACPI && EFI && IA64 +--- a/drivers/firmware/efivars.c ++++ b/drivers/firmware/efivars.c +@@ -103,6 +103,11 @@ MODULE_VERSION(EFIVARS_VERSION); + */ + #define GUID_LEN 36 + ++static bool efivars_pstore_disable = ++ IS_ENABLED(EFI_VARS_PSTORE_DEFAULT_DISABLE); ++ ++module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644); ++ + /* + * The maximum size of VariableName + Data = 1024 + * Therefore, it's reasonable to save that much +@@ -1926,7 +1931,8 @@ int register_efivars(struct efivars *efi + if (error) + unregister_efivars(efivars); + +- efivar_pstore_register(efivars); ++ if (!efivars_pstore_disable) ++ efivar_pstore_register(efivars); + + register_filesystem(&efivarfs_type); + diff --git a/queue-3.8/efivars-allow-disabling-use-as-a-pstore-backend.patch b/queue-3.8/efivars-allow-disabling-use-as-a-pstore-backend.patch new file mode 100644 index 00000000000..c11c1bb8bff --- /dev/null +++ b/queue-3.8/efivars-allow-disabling-use-as-a-pstore-backend.patch @@ -0,0 +1,141 @@ +From ed9dc8ce7a1c8115dba9483a9b51df8b63a2e0ef Mon Sep 17 00:00:00 2001 +From: Seth Forshee +Date: Thu, 7 Mar 2013 11:40:17 -0600 +Subject: efivars: Allow disabling use as a pstore backend + +From: Seth Forshee + +commit ed9dc8ce7a1c8115dba9483a9b51df8b63a2e0ef upstream. + +Add a new option, CONFIG_EFI_VARS_PSTORE, which can be set to N to +avoid using efivars as a backend to pstore, as some users may want to +compile out the code completely. + +Set the default to Y to maintain backwards compatability, since this +feature has always been enabled until now. + +Signed-off-by: Seth Forshee +Cc: Josh Boyer +Cc: Matthew Garrett +Cc: Seiji Aguchi +Cc: Tony Luck +Signed-off-by: Matt Fleming +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firmware/Kconfig | 9 ++++++ + drivers/firmware/efivars.c | 64 ++++++++++++++------------------------------- + 2 files changed, 29 insertions(+), 44 deletions(-) + +--- a/drivers/firmware/Kconfig ++++ b/drivers/firmware/Kconfig +@@ -53,6 +53,15 @@ config EFI_VARS + Subsequent efibootmgr releases may be found at: + + ++config EFI_VARS_PSTORE ++ bool "Register efivars backend for pstore" ++ depends on EFI_VARS && PSTORE ++ default y ++ help ++ Say Y here to enable use efivars as a backend to pstore. This ++ will allow writing console messages, crash dumps, or anything ++ else supported by pstore to EFI variables. ++ + config EFI_PCDP + bool "Console device selection via EFI PCDP or HCDP table" + depends on ACPI && EFI && IA64 +--- a/drivers/firmware/efivars.c ++++ b/drivers/firmware/efivars.c +@@ -1301,9 +1301,7 @@ static const struct inode_operations efi + .create = efivarfs_create, + }; + +-static struct pstore_info efi_pstore_info; +- +-#ifdef CONFIG_PSTORE ++#ifdef CONFIG_EFI_VARS_PSTORE + + static int efi_pstore_open(struct pstore_info *psi) + { +@@ -1500,38 +1498,6 @@ static int efi_pstore_erase(enum pstore_ + + return 0; + } +-#else +-static int efi_pstore_open(struct pstore_info *psi) +-{ +- return 0; +-} +- +-static int efi_pstore_close(struct pstore_info *psi) +-{ +- return 0; +-} +- +-static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, int *count, +- struct timespec *timespec, +- char **buf, struct pstore_info *psi) +-{ +- return -1; +-} +- +-static int efi_pstore_write(enum pstore_type_id type, +- enum kmsg_dump_reason reason, u64 *id, +- unsigned int part, int count, size_t size, +- struct pstore_info *psi) +-{ +- return 0; +-} +- +-static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, +- struct timespec time, struct pstore_info *psi) +-{ +- return 0; +-} +-#endif + + static struct pstore_info efi_pstore_info = { + .owner = THIS_MODULE, +@@ -1543,6 +1509,24 @@ static struct pstore_info efi_pstore_inf + .erase = efi_pstore_erase, + }; + ++static void efivar_pstore_register(struct efivars *efivars) ++{ ++ efivars->efi_pstore_info = efi_pstore_info; ++ efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL); ++ if (efivars->efi_pstore_info.buf) { ++ efivars->efi_pstore_info.bufsize = 1024; ++ efivars->efi_pstore_info.data = efivars; ++ spin_lock_init(&efivars->efi_pstore_info.buf_lock); ++ pstore_register(&efivars->efi_pstore_info); ++ } ++} ++#else ++static void efivar_pstore_register(struct efivars *efivars) ++{ ++ return; ++} ++#endif ++ + static ssize_t efivar_create(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t pos, size_t count) +@@ -1942,15 +1926,7 @@ int register_efivars(struct efivars *efi + if (error) + unregister_efivars(efivars); + +- efivars->efi_pstore_info = efi_pstore_info; +- +- efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL); +- if (efivars->efi_pstore_info.buf) { +- efivars->efi_pstore_info.bufsize = 1024; +- efivars->efi_pstore_info.data = efivars; +- spin_lock_init(&efivars->efi_pstore_info.buf_lock); +- pstore_register(&efivars->efi_pstore_info); +- } ++ efivar_pstore_register(efivars); + + register_filesystem(&efivarfs_type); + diff --git a/queue-3.8/efivars-fix-check-for-config_efi_vars_pstore_default_disable.patch b/queue-3.8/efivars-fix-check-for-config_efi_vars_pstore_default_disable.patch new file mode 100644 index 00000000000..a81af2e9d4c --- /dev/null +++ b/queue-3.8/efivars-fix-check-for-config_efi_vars_pstore_default_disable.patch @@ -0,0 +1,31 @@ +From ca0ba26fbbd2d81c43085df49ce0abfe34535a90 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Fri, 22 Mar 2013 19:56:51 +0000 +Subject: efivars: Fix check for CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE + +From: Ben Hutchings + +commit ca0ba26fbbd2d81c43085df49ce0abfe34535a90 upstream. + +The 'CONFIG_' prefix is not implicit in IS_ENABLED(). + +Signed-off-by: Ben Hutchings +Cc: Seth Forshee +Signed-off-by: Matt Fleming +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firmware/efivars.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/firmware/efivars.c ++++ b/drivers/firmware/efivars.c +@@ -104,7 +104,7 @@ MODULE_VERSION(EFIVARS_VERSION); + #define GUID_LEN 36 + + static bool efivars_pstore_disable = +- IS_ENABLED(EFI_VARS_PSTORE_DEFAULT_DISABLE); ++ IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE); + + module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644); + diff --git a/queue-3.8/ext4-fix-data-journal-fast-mount-umount-hang.patch b/queue-3.8/ext4-fix-data-journal-fast-mount-umount-hang.patch new file mode 100644 index 00000000000..c696bdb9379 --- /dev/null +++ b/queue-3.8/ext4-fix-data-journal-fast-mount-umount-hang.patch @@ -0,0 +1,75 @@ +From 2b405bfa84063bfa35621d2d6879f52693c614b0 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Wed, 20 Mar 2013 09:42:11 -0400 +Subject: ext4: fix data=journal fast mount/umount hang + +From: Theodore Ts'o + +commit 2b405bfa84063bfa35621d2d6879f52693c614b0 upstream. + +In data=journal mode, if we unmount the file system before a +transaction has a chance to complete, when the journal inode is being +evicted, we can end up calling into jbd2_log_wait_commit() for the +last transaction, after the journalling machinery has been shut down. + +Arguably we should adjust ext4_should_journal_data() to return FALSE +for the journal inode, but the only place it matters is +ext4_evict_inode(), and so to save a bit of CPU time, and to make the +patch much more obviously correct by inspection(tm), we'll fix it by +explicitly not trying to waiting for a journal commit when we are +evicting the journal inode, since it's guaranteed to never succeed in +this case. + +This can be easily replicated via: + + mount -t ext4 -o data=journal /dev/vdb /vdb ; umount /vdb + +------------[ cut here ]------------ +WARNING: at /usr/projects/linux/ext4/fs/jbd2/journal.c:542 __jbd2_log_start_commit+0xba/0xcd() +Hardware name: Bochs +JBD2: bad log_start_commit: 3005630206 3005630206 0 0 +Modules linked in: +Pid: 2909, comm: umount Not tainted 3.8.0-rc3 #1020 +Call Trace: + [] warn_slowpath_common+0x68/0x7d + [] ? __jbd2_log_start_commit+0xba/0xcd + [] warn_slowpath_fmt+0x2b/0x2f + [] __jbd2_log_start_commit+0xba/0xcd + [] jbd2_log_start_commit+0x24/0x34 + [] ext4_evict_inode+0x71/0x2e3 + [] evict+0x94/0x135 + [] iput+0x10a/0x110 + [] jbd2_journal_destroy+0x190/0x1ce + [] ? bit_waitqueue+0x50/0x50 + [] ext4_put_super+0x52/0x294 + [] generic_shutdown_super+0x48/0xb4 + [] kill_block_super+0x22/0x60 + [] deactivate_locked_super+0x22/0x49 + [] deactivate_super+0x30/0x33 + [] mntput_no_expire+0x107/0x10c + [] sys_umount+0x2cf/0x2e0 + [] sys_oldumount+0x12/0x14 + [] syscall_call+0x7/0xb +---[ end trace 6a954cc790501c1f ]--- +jbd2_log_wait_commit: error: j_commit_request=-1289337090, tid=0 + +Signed-off-by: "Theodore Ts'o" +Reviewed-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -211,7 +211,8 @@ void ext4_evict_inode(struct inode *inod + * don't use page cache. + */ + if (ext4_should_journal_data(inode) && +- (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) { ++ (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) && ++ inode->i_ino != EXT4_JOURNAL_INO) { + journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; + tid_t commit_tid = EXT4_I(inode)->i_datasync_tid; + diff --git a/queue-3.8/ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch b/queue-3.8/ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch new file mode 100644 index 00000000000..af05f41b30a --- /dev/null +++ b/queue-3.8/ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch @@ -0,0 +1,130 @@ +From 90ba983f6889e65a3b506b30dc606aa9d1d46cd2 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Mon, 11 Mar 2013 23:39:59 -0400 +Subject: ext4: use atomic64_t for the per-flexbg free_clusters count + +From: Theodore Ts'o + +commit 90ba983f6889e65a3b506b30dc606aa9d1d46cd2 upstream. + +A user who was using a 8TB+ file system and with a very large flexbg +size (> 65536) could cause the atomic_t used in the struct flex_groups +to overflow. This was detected by PaX security patchset: + +http://forums.grsecurity.net/viewtopic.php?f=3&t=3289&p=12551#p12551 + +This bug was introduced in commit 9f24e4208f7e, so it's been around +since 2.6.30. :-( + +Fix this by using an atomic64_t for struct orlav_stats's +free_clusters. + +Signed-off-by: "Theodore Ts'o" +Reviewed-by: Lukas Czerner +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ext4.h | 6 +++--- + fs/ext4/ialloc.c | 4 ++-- + fs/ext4/mballoc.c | 12 ++++++------ + fs/ext4/resize.c | 4 ++-- + fs/ext4/super.c | 4 ++-- + 5 files changed, 15 insertions(+), 15 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -338,9 +338,9 @@ struct ext4_group_desc + */ + + struct flex_groups { +- atomic_t free_inodes; +- atomic_t free_clusters; +- atomic_t used_dirs; ++ atomic64_t free_clusters; ++ atomic_t free_inodes; ++ atomic_t used_dirs; + }; + + #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -324,8 +324,8 @@ error_return: + } + + struct orlov_stats { ++ __u64 free_clusters; + __u32 free_inodes; +- __u32 free_clusters; + __u32 used_dirs; + }; + +@@ -342,7 +342,7 @@ static void get_orlov_stats(struct super + + if (flex_size > 1) { + stats->free_inodes = atomic_read(&flex_group[g].free_inodes); +- stats->free_clusters = atomic_read(&flex_group[g].free_clusters); ++ stats->free_clusters = atomic64_read(&flex_group[g].free_clusters); + stats->used_dirs = atomic_read(&flex_group[g].used_dirs); + return; + } +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -2829,8 +2829,8 @@ ext4_mb_mark_diskspace_used(struct ext4_ + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, + ac->ac_b_ex.fe_group); +- atomic_sub(ac->ac_b_ex.fe_len, +- &sbi->s_flex_groups[flex_group].free_clusters); ++ atomic64_sub(ac->ac_b_ex.fe_len, ++ &sbi->s_flex_groups[flex_group].free_clusters); + } + + err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); +@@ -4691,8 +4691,8 @@ do_more: + + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, block_group); +- atomic_add(count_clusters, +- &sbi->s_flex_groups[flex_group].free_clusters); ++ atomic64_add(count_clusters, ++ &sbi->s_flex_groups[flex_group].free_clusters); + } + + ext4_mb_unload_buddy(&e4b); +@@ -4836,8 +4836,8 @@ int ext4_group_add_blocks(handle_t *hand + + if (sbi->s_log_groups_per_flex) { + ext4_group_t flex_group = ext4_flex_group(sbi, block_group); +- atomic_add(EXT4_NUM_B2C(sbi, blocks_freed), +- &sbi->s_flex_groups[flex_group].free_clusters); ++ atomic64_add(EXT4_NUM_B2C(sbi, blocks_freed), ++ &sbi->s_flex_groups[flex_group].free_clusters); + } + + ext4_mb_unload_buddy(&e4b); +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -1360,8 +1360,8 @@ static void ext4_update_super(struct sup + sbi->s_log_groups_per_flex) { + ext4_group_t flex_group; + flex_group = ext4_flex_group(sbi, group_data[0].group); +- atomic_add(EXT4_NUM_B2C(sbi, free_blocks), +- &sbi->s_flex_groups[flex_group].free_clusters); ++ atomic64_add(EXT4_NUM_B2C(sbi, free_blocks), ++ &sbi->s_flex_groups[flex_group].free_clusters); + atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count, + &sbi->s_flex_groups[flex_group].free_inodes); + } +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1979,8 +1979,8 @@ static int ext4_fill_flex_info(struct su + flex_group = ext4_flex_group(sbi, i); + atomic_add(ext4_free_inodes_count(sb, gdp), + &sbi->s_flex_groups[flex_group].free_inodes); +- atomic_add(ext4_free_group_clusters(sb, gdp), +- &sbi->s_flex_groups[flex_group].free_clusters); ++ atomic64_add(ext4_free_group_clusters(sb, gdp), ++ &sbi->s_flex_groups[flex_group].free_clusters); + atomic_add(ext4_used_dirs_count(sb, gdp), + &sbi->s_flex_groups[flex_group].used_dirs); + } diff --git a/queue-3.8/ext4-use-s_extent_max_zeroout_kb-value-as-number-of-kb.patch b/queue-3.8/ext4-use-s_extent_max_zeroout_kb-value-as-number-of-kb.patch new file mode 100644 index 00000000000..bd031600f6c --- /dev/null +++ b/queue-3.8/ext4-use-s_extent_max_zeroout_kb-value-as-number-of-kb.patch @@ -0,0 +1,42 @@ +From 4f42f80a8f08d4c3f52c4267361241885d5dee3a Mon Sep 17 00:00:00 2001 +From: Lukas Czerner +Date: Tue, 12 Mar 2013 12:40:04 -0400 +Subject: ext4: use s_extent_max_zeroout_kb value as number of kb + +From: Lukas Czerner + +commit 4f42f80a8f08d4c3f52c4267361241885d5dee3a upstream. + +Currently when converting extent to initialized, we have to decide +whether to zeroout part/all of the uninitialized extent in order to +avoid extent tree growing rapidly. + +The decision is made by comparing the size of the extent with the +configurable value s_extent_max_zeroout_kb which is in kibibytes units. + +However when converting it to number of blocks we currently use it as it +was in bytes. This is obviously bug and it will result in ext4 _never_ +zeroout extents, but rather always split and convert parts to +initialized while leaving the rest uninitialized in default setting. + +Fix this by using s_extent_max_zeroout_kb as kibibytes. + +Signed-off-by: Lukas Czerner +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/extents.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -3278,7 +3278,7 @@ static int ext4_ext_convert_to_initializ + + if (EXT4_EXT_MAY_ZEROOUT & split_flag) + max_zeroout = sbi->s_extent_max_zeroout_kb >> +- inode->i_sb->s_blocksize_bits; ++ (inode->i_sb->s_blocksize_bits - 10); + + /* If extent is less than s_max_zeroout_kb, zeroout directly */ + if (max_zeroout && (ee_len <= max_zeroout)) { diff --git a/queue-3.8/ipoib-fix-send-lockup-due-to-missed-tx-completion.patch b/queue-3.8/ipoib-fix-send-lockup-due-to-missed-tx-completion.patch new file mode 100644 index 00000000000..5db4eac9b54 --- /dev/null +++ b/queue-3.8/ipoib-fix-send-lockup-due-to-missed-tx-completion.patch @@ -0,0 +1,51 @@ +From 1ee9e2aa7b31427303466776f455d43e5e3c9275 Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Tue, 26 Feb 2013 15:46:27 +0000 +Subject: IPoIB: Fix send lockup due to missed TX completion + +From: Mike Marciniszyn + +commit 1ee9e2aa7b31427303466776f455d43e5e3c9275 upstream. + +Commit f0dc117abdfa ("IPoIB: Fix TX queue lockup with mixed UD/CM +traffic") attempts to solve an issue where unprocessed UD send +completions can deadlock the netdev. + +The patch doesn't fully resolve the issue because if more than half +the tx_outstanding's were UD and all of the destinations are RC +reachable, arming the CQ doesn't solve the issue. + +This patch uses the IB_CQ_REPORT_MISSED_EVENTS on the +ib_req_notify_cq(). If the rc is above 0, the UD send cq completion +callback is called directly to re-arm the send completion timer. + +This issue is seen in very large parallel filesystem deployments +and the patch has been shown to correct the issue. + +Reviewed-by: Dean Luick +Signed-off-by: Mike Marciniszyn +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/ipoib/ipoib_cm.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c ++++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c +@@ -758,9 +758,13 @@ void ipoib_cm_send(struct net_device *de + if (++priv->tx_outstanding == ipoib_sendq_size) { + ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", + tx->qp->qp_num); +- if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP)) +- ipoib_warn(priv, "request notify on send CQ failed\n"); + netif_stop_queue(dev); ++ rc = ib_req_notify_cq(priv->send_cq, ++ IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS); ++ if (rc < 0) ++ ipoib_warn(priv, "request notify on send CQ failed\n"); ++ else if (rc) ++ ipoib_send_comp_handler(priv->send_cq, dev); + } + } + } diff --git a/queue-3.8/md-raid5-avoid-accessing-gendisk-or-queue-structs-when-not-available.patch b/queue-3.8/md-raid5-avoid-accessing-gendisk-or-queue-structs-when-not-available.patch new file mode 100644 index 00000000000..110681b1edc --- /dev/null +++ b/queue-3.8/md-raid5-avoid-accessing-gendisk-or-queue-structs-when-not-available.patch @@ -0,0 +1,105 @@ +From e3620a3ad52609f64a2402e4b59300afb4b83b77 Mon Sep 17 00:00:00 2001 +From: Jonathan Brassow +Date: Thu, 7 Mar 2013 16:22:01 -0600 +Subject: MD RAID5: Avoid accessing gendisk or queue structs when not available + +From: Jonathan Brassow + +commit e3620a3ad52609f64a2402e4b59300afb4b83b77 upstream. + +MD RAID5: Fix kernel oops when RAID4/5/6 is used via device-mapper + +Commit a9add5d (v3.8-rc1) added blktrace calls to the RAID4/5/6 driver. +However, when device-mapper is used to create RAID4/5/6 arrays, the +mddev->gendisk and mddev->queue fields are not setup. Therefore, calling +things like trace_block_bio_remap will cause a kernel oops. This patch +conditionalizes those calls on whether the proper fields exist to make +the calls. (Device-mapper will call trace_block_bio_remap on its own.) + +This patch is suitable for the 3.8.y stable kernel. + +Signed-off-by: Jonathan Brassow +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid5.c | 33 ++++++++++++++++++++------------- + 1 file changed, 20 insertions(+), 13 deletions(-) + +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -674,9 +674,11 @@ static void ops_run_io(struct stripe_hea + bi->bi_next = NULL; + if (rrdev) + set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); +- trace_block_bio_remap(bdev_get_queue(bi->bi_bdev), +- bi, disk_devt(conf->mddev->gendisk), +- sh->dev[i].sector); ++ ++ if (conf->mddev->gendisk) ++ trace_block_bio_remap(bdev_get_queue(bi->bi_bdev), ++ bi, disk_devt(conf->mddev->gendisk), ++ sh->dev[i].sector); + generic_make_request(bi); + } + if (rrdev) { +@@ -704,9 +706,10 @@ static void ops_run_io(struct stripe_hea + rbi->bi_io_vec[0].bv_offset = 0; + rbi->bi_size = STRIPE_SIZE; + rbi->bi_next = NULL; +- trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), +- rbi, disk_devt(conf->mddev->gendisk), +- sh->dev[i].sector); ++ if (conf->mddev->gendisk) ++ trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), ++ rbi, disk_devt(conf->mddev->gendisk), ++ sh->dev[i].sector); + generic_make_request(rbi); + } + if (!rdev && !rrdev) { +@@ -2871,8 +2874,10 @@ static void handle_stripe_dirtying(struc + set_bit(STRIPE_HANDLE, &sh->state); + if (rmw < rcw && rmw > 0) { + /* prefer read-modify-write, but need to get some data */ +- blk_add_trace_msg(conf->mddev->queue, "raid5 rmw %llu %d", +- (unsigned long long)sh->sector, rmw); ++ if (conf->mddev->queue) ++ blk_add_trace_msg(conf->mddev->queue, ++ "raid5 rmw %llu %d", ++ (unsigned long long)sh->sector, rmw); + for (i = disks; i--; ) { + struct r5dev *dev = &sh->dev[i]; + if ((dev->towrite || i == sh->pd_idx) && +@@ -2922,7 +2927,7 @@ static void handle_stripe_dirtying(struc + } + } + } +- if (rcw) ++ if (rcw && conf->mddev->queue) + blk_add_trace_msg(conf->mddev->queue, "raid5 rcw %llu %d %d %d", + (unsigned long long)sh->sector, + rcw, qread, test_bit(STRIPE_DELAYED, &sh->state)); +@@ -4029,9 +4034,10 @@ static int chunk_aligned_read(struct mdd + atomic_inc(&conf->active_aligned_reads); + spin_unlock_irq(&conf->device_lock); + +- trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev), +- align_bi, disk_devt(mddev->gendisk), +- raid_bio->bi_sector); ++ if (mddev->gendisk) ++ trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev), ++ align_bi, disk_devt(mddev->gendisk), ++ raid_bio->bi_sector); + generic_make_request(align_bi); + return 1; + } else { +@@ -4125,7 +4131,8 @@ static void raid5_unplug(struct blk_plug + } + spin_unlock_irq(&conf->device_lock); + } +- trace_block_unplug(mddev->queue, cnt, !from_schedule); ++ if (mddev->queue) ++ trace_block_unplug(mddev->queue, cnt, !from_schedule); + kfree(cb); + } + diff --git a/queue-3.8/md-raid5-ensure-sync-and-discard-don-t-happen-at-the-same-time.patch b/queue-3.8/md-raid5-ensure-sync-and-discard-don-t-happen-at-the-same-time.patch new file mode 100644 index 00000000000..679c88064b4 --- /dev/null +++ b/queue-3.8/md-raid5-ensure-sync-and-discard-don-t-happen-at-the-same-time.patch @@ -0,0 +1,157 @@ +From f8dfcffd0472a0f353f34a567ad3f53568914d04 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Tue, 12 Mar 2013 12:18:06 +1100 +Subject: md/raid5: ensure sync and DISCARD don't happen at the same time. + +From: NeilBrown + +commit f8dfcffd0472a0f353f34a567ad3f53568914d04 upstream. + +A number of problems can occur due to races between +resync/recovery and discard. + +- if sync_request calls handle_stripe() while a discard is + happening on the stripe, it might call handle_stripe_clean_event + before all of the individual discard requests have completed + (so some devices are still locked, but not all). + Since commit ca64cae96037de16e4af92678814f5d4bf0c1c65 + md/raid5: Make sure we clear R5_Discard when discard is finished. + this will cause R5_Discard to be cleared for the parity device, + so handle_stripe_clean_event() will not be called when the other + devices do become unlocked, so their ->written will not be cleared. + This ultimately leads to a WARN_ON in init_stripe and a lock-up. + +- If handle_stripe_clean_event() does clear R5_UPTODATE at an awkward + time for resync, it can lead to s->uptodate being less than disks + in handle_parity_checks5(), which triggers a BUG (because it is + one). + +So: + - keep R5_Discard on the parity device until all other devices have + completed their discard request + - make sure we don't try to have a 'discard' and a 'sync' action at + the same time. + This involves a new stripe flag to we know when a 'discard' is + happening, and the use of R5_Overlap on the parity disk so when a + discard is wanted while a sync is active, so we know to wake up + the discard at the appropriate time. + +Discard support for RAID5 was added in 3.7, so this is suitable for +any -stable kernel since 3.7. + +Reported-by: Jes Sorensen +Tested-by: Jes Sorensen +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid5.c | 45 +++++++++++++++++++++++++++++++++++++++------ + drivers/md/raid5.h | 1 + + 2 files changed, 40 insertions(+), 6 deletions(-) + +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -2612,6 +2612,8 @@ handle_failed_sync(struct r5conf *conf, + int i; + + clear_bit(STRIPE_SYNCING, &sh->state); ++ if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags)) ++ wake_up(&conf->wait_for_overlap); + s->syncing = 0; + s->replacing = 0; + /* There is nothing more to do for sync/check/repair. +@@ -2785,6 +2787,7 @@ static void handle_stripe_clean_event(st + { + int i; + struct r5dev *dev; ++ int discard_pending = 0; + + for (i = disks; i--; ) + if (sh->dev[i].written) { +@@ -2813,9 +2816,23 @@ static void handle_stripe_clean_event(st + STRIPE_SECTORS, + !test_bit(STRIPE_DEGRADED, &sh->state), + 0); +- } +- } else if (test_bit(R5_Discard, &sh->dev[i].flags)) +- clear_bit(R5_Discard, &sh->dev[i].flags); ++ } else if (test_bit(R5_Discard, &dev->flags)) ++ discard_pending = 1; ++ } ++ if (!discard_pending && ++ test_bit(R5_Discard, &sh->dev[sh->pd_idx].flags)) { ++ clear_bit(R5_Discard, &sh->dev[sh->pd_idx].flags); ++ clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags); ++ if (sh->qd_idx >= 0) { ++ clear_bit(R5_Discard, &sh->dev[sh->qd_idx].flags); ++ clear_bit(R5_UPTODATE, &sh->dev[sh->qd_idx].flags); ++ } ++ /* now that discard is done we can proceed with any sync */ ++ clear_bit(STRIPE_DISCARD, &sh->state); ++ if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) ++ set_bit(STRIPE_HANDLE, &sh->state); ++ ++ } + + if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) + if (atomic_dec_and_test(&conf->pending_full_writes)) +@@ -3467,9 +3484,15 @@ static void handle_stripe(struct stripe_ + return; + } + +- if (test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { +- set_bit(STRIPE_SYNCING, &sh->state); +- clear_bit(STRIPE_INSYNC, &sh->state); ++ if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { ++ spin_lock(&sh->stripe_lock); ++ /* Cannot process 'sync' concurrently with 'discard' */ ++ if (!test_bit(STRIPE_DISCARD, &sh->state) && ++ test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { ++ set_bit(STRIPE_SYNCING, &sh->state); ++ clear_bit(STRIPE_INSYNC, &sh->state); ++ } ++ spin_unlock(&sh->stripe_lock); + } + clear_bit(STRIPE_DELAYED, &sh->state); + +@@ -3629,6 +3652,8 @@ static void handle_stripe(struct stripe_ + test_bit(STRIPE_INSYNC, &sh->state)) { + md_done_sync(conf->mddev, STRIPE_SECTORS, 1); + clear_bit(STRIPE_SYNCING, &sh->state); ++ if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags)) ++ wake_up(&conf->wait_for_overlap); + } + + /* If the failed drives are just a ReadError, then we might need +@@ -4195,6 +4220,13 @@ static void make_discard_request(struct + sh = get_active_stripe(conf, logical_sector, 0, 0, 0); + prepare_to_wait(&conf->wait_for_overlap, &w, + TASK_UNINTERRUPTIBLE); ++ set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags); ++ if (test_bit(STRIPE_SYNCING, &sh->state)) { ++ release_stripe(sh); ++ schedule(); ++ goto again; ++ } ++ clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags); + spin_lock_irq(&sh->stripe_lock); + for (d = 0; d < conf->raid_disks; d++) { + if (d == sh->pd_idx || d == sh->qd_idx) +@@ -4207,6 +4239,7 @@ static void make_discard_request(struct + goto again; + } + } ++ set_bit(STRIPE_DISCARD, &sh->state); + finish_wait(&conf->wait_for_overlap, &w); + for (d = 0; d < conf->raid_disks; d++) { + if (d == sh->pd_idx || d == sh->qd_idx) +--- a/drivers/md/raid5.h ++++ b/drivers/md/raid5.h +@@ -323,6 +323,7 @@ enum { + STRIPE_COMPUTE_RUN, + STRIPE_OPS_REQ_PENDING, + STRIPE_ON_UNPLUG_LIST, ++ STRIPE_DISCARD, + }; + + /* diff --git a/queue-3.8/md-raid5-schedule_construction-should-abort-if-nothing-to-do.patch b/queue-3.8/md-raid5-schedule_construction-should-abort-if-nothing-to-do.patch new file mode 100644 index 00000000000..1a04c02f959 --- /dev/null +++ b/queue-3.8/md-raid5-schedule_construction-should-abort-if-nothing-to-do.patch @@ -0,0 +1,100 @@ +From ce7d363aaf1e28be8406a2976220944ca487e8ca Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 4 Mar 2013 12:37:14 +1100 +Subject: md/raid5: schedule_construction should abort if nothing to do. + +From: NeilBrown + +commit ce7d363aaf1e28be8406a2976220944ca487e8ca upstream. + +Since commit 1ed850f356a0a422013846b5291acff08815008b + md/raid5: make sure to_read and to_write never go negative. + +It has been possible for handle_stripe_dirtying to be called +when there isn't actually any work to do. +It then calls schedule_reconstruction() which will set R5_LOCKED +on the parity block(s) even when nothing else is happening. +This then causes problems in do_release_stripe(). + +So add checks to schedule_reconstruction() so that if it doesn't +find anything to do, it just aborts. + +This bug was introduced in v3.7, so the patch is suitable +for -stable kernels since then. + +Reported-by: majianpeng +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid5.c | 38 ++++++++++++++++++++++---------------- + 1 file changed, 22 insertions(+), 16 deletions(-) + +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -2319,17 +2319,6 @@ schedule_reconstruction(struct stripe_he + int level = conf->level; + + if (rcw) { +- /* if we are not expanding this is a proper write request, and +- * there will be bios with new data to be drained into the +- * stripe cache +- */ +- if (!expand) { +- sh->reconstruct_state = reconstruct_state_drain_run; +- set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); +- } else +- sh->reconstruct_state = reconstruct_state_run; +- +- set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); + + for (i = disks; i--; ) { + struct r5dev *dev = &sh->dev[i]; +@@ -2342,6 +2331,21 @@ schedule_reconstruction(struct stripe_he + s->locked++; + } + } ++ /* if we are not expanding this is a proper write request, and ++ * there will be bios with new data to be drained into the ++ * stripe cache ++ */ ++ if (!expand) { ++ if (!s->locked) ++ /* False alarm, nothing to do */ ++ return; ++ sh->reconstruct_state = reconstruct_state_drain_run; ++ set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); ++ } else ++ sh->reconstruct_state = reconstruct_state_run; ++ ++ set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); ++ + if (s->locked + conf->max_degraded == disks) + if (!test_and_set_bit(STRIPE_FULL_WRITE, &sh->state)) + atomic_inc(&conf->pending_full_writes); +@@ -2350,11 +2354,6 @@ schedule_reconstruction(struct stripe_he + BUG_ON(!(test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags) || + test_bit(R5_Wantcompute, &sh->dev[pd_idx].flags))); + +- sh->reconstruct_state = reconstruct_state_prexor_drain_run; +- set_bit(STRIPE_OP_PREXOR, &s->ops_request); +- set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); +- set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); +- + for (i = disks; i--; ) { + struct r5dev *dev = &sh->dev[i]; + if (i == pd_idx) +@@ -2369,6 +2368,13 @@ schedule_reconstruction(struct stripe_he + s->locked++; + } + } ++ if (!s->locked) ++ /* False alarm - nothing to do */ ++ return; ++ sh->reconstruct_state = reconstruct_state_prexor_drain_run; ++ set_bit(STRIPE_OP_PREXOR, &s->ops_request); ++ set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); ++ set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); + } + + /* keep the parity disk(s) locked while asynchronous operations diff --git a/queue-3.8/nfsd-fix-bad-offset-use.patch b/queue-3.8/nfsd-fix-bad-offset-use.patch new file mode 100644 index 00000000000..26c8138377b --- /dev/null +++ b/queue-3.8/nfsd-fix-bad-offset-use.patch @@ -0,0 +1,46 @@ +From e49dbbf3e770aa590a8a464ac4978a09027060b9 Mon Sep 17 00:00:00 2001 +From: Kent Overstreet +Date: Fri, 22 Mar 2013 11:18:24 -0700 +Subject: nfsd: fix bad offset use + +From: Kent Overstreet + +commit e49dbbf3e770aa590a8a464ac4978a09027060b9 upstream. + +vfs_writev() updates the offset argument - but the code then passes the +offset to vfs_fsync_range(). Since offset now points to the offset after +what was just written, this is probably not what was intended + +Introduced by face15025ffdf664de95e86ae831544154d26c9c "nfsd: use +vfs_fsync_range(), not O_SYNC, for stable writes". + +Signed-off-by: Kent Overstreet +Cc: Al Viro +Cc: "Eric W. Biederman" +Reviewed-by: Zach Brown +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/vfs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -1013,6 +1013,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s + int host_err; + int stable = *stablep; + int use_wgather; ++ loff_t pos = offset; + + dentry = file->f_path.dentry; + inode = dentry->d_inode; +@@ -1025,7 +1026,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s + + /* Write the data. */ + oldfs = get_fs(); set_fs(KERNEL_DS); +- host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset); ++ host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &pos); + set_fs(oldfs); + if (host_err < 0) + goto out_nfserr; diff --git a/queue-3.8/series b/queue-3.8/series index 4a703cceeb8..6b10af9f99a 100644 --- a/queue-3.8/series +++ b/queue-3.8/series @@ -66,3 +66,27 @@ cifs-delay-super-block-destruction-until-all-cifsfileinfo-objects-are-gone.patch cifs-ignore-everything-in-spnego-blob-after-mechtypes.patch jbd2-fix-use-after-free-in-jbd2_journal_dirty_metadata.patch ext4-fix-the-wrong-number-of-the-allocated-blocks-in-ext4_split_extent.patch +usb-storage-add-unusual_devs-entry-for-samsung-yp-z3-mp3-player.patch +ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch +ext4-use-s_extent_max_zeroout_kb-value-as-number-of-kb.patch +ext4-fix-data-journal-fast-mount-umount-hang.patch +ipoib-fix-send-lockup-due-to-missed-tx-completion.patch +watchdog-sp5100_tco-set-the-acpimmiosel-bitmask-value-to-1-instead-of-2.patch +watchdog-sp5100_tco-remove-code-that-may-cause-a-boot-failure.patch +md-raid5-schedule_construction-should-abort-if-nothing-to-do.patch +md-raid5-avoid-accessing-gendisk-or-queue-structs-when-not-available.patch +md-raid5-ensure-sync-and-discard-don-t-happen-at-the-same-time.patch +nfsd-fix-bad-offset-use.patch +clockevents-don-t-allow-dummy-broadcast-timers.patch +x86-64-fix-the-failure-case-in-copy_user_handle_tail.patch +usb-xhci-fix-bit-definitions-for-iman-register.patch +usb-xhci-correctly-enable-interrupts.patch +usb-cdc-acm-fix-device-unregistration.patch +usb-ehci-fix-regression-during-bus-resume.patch +usb-ehci-fix-regression-in-qh-unlinking.patch +usb-gadget-ffs-fix-enable-multiple-instances.patch +usb-serial-fix-interface-refcounting.patch +efivars-allow-disabling-use-as-a-pstore-backend.patch +efivars-add-module-parameter-to-disable-use-as-a-pstore-backend.patch +efivars-fix-check-for-config_efi_vars_pstore_default_disable.patch +acpi-rework-acpi_get_child-to-be-more-efficient.patch diff --git a/queue-3.8/usb-cdc-acm-fix-device-unregistration.patch b/queue-3.8/usb-cdc-acm-fix-device-unregistration.patch new file mode 100644 index 00000000000..c2a9f13a35e --- /dev/null +++ b/queue-3.8/usb-cdc-acm-fix-device-unregistration.patch @@ -0,0 +1,52 @@ +From cb25505fc604292c70fc02143fc102f54c8595f0 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:06 +0100 +Subject: USB: cdc-acm: fix device unregistration + +From: Johan Hovold + +commit cb25505fc604292c70fc02143fc102f54c8595f0 upstream. + +Unregister tty device in disconnect as is required by the USB stack. + +By deferring unregistration to when the last tty reference is dropped, +the parent interface device can get unregistered before the child +resulting in broken hotplug events being generated when the tty is +finally closed: + +KERNEL[2290.798128] remove /devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:3.1 (usb) +KERNEL[2290.804589] remove /devices/pci0000:00/0000:00:1d.7/usb2/2-1 (usb) +KERNEL[2294.554799] remove /2-1:3.1/tty/ttyACM0 (tty) + +The driver must deal with tty callbacks after disconnect by checking the +disconnected flag. Specifically, further opens must be prevented and +this is already implemented. + +Acked-by: Oliver Neukum +Cc: Oliver Neukum +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-acm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -600,7 +600,6 @@ static void acm_port_destruct(struct tty + + dev_dbg(&acm->control->dev, "%s\n", __func__); + +- tty_unregister_device(acm_tty_driver, acm->minor); + acm_release_minor(acm); + usb_put_intf(acm->control); + kfree(acm->country_codes); +@@ -1418,6 +1417,8 @@ static void acm_disconnect(struct usb_in + + stop_data_traffic(acm); + ++ tty_unregister_device(acm_tty_driver, acm->minor); ++ + usb_free_urb(acm->ctrlurb); + for (i = 0; i < ACM_NW; i++) + usb_free_urb(acm->wb[i].urb); diff --git a/queue-3.8/usb-ehci-fix-regression-during-bus-resume.patch b/queue-3.8/usb-ehci-fix-regression-during-bus-resume.patch new file mode 100644 index 00000000000..307b818b0c6 --- /dev/null +++ b/queue-3.8/usb-ehci-fix-regression-during-bus-resume.patch @@ -0,0 +1,85 @@ +From 2a40f324541ee61c22146214349c2ce9f5c30bcf Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 15 Mar 2013 14:40:26 -0400 +Subject: USB: EHCI: fix regression during bus resume + +From: Alan Stern + +commit 2a40f324541ee61c22146214349c2ce9f5c30bcf upstream. + +This patch (as1663) fixes a regression caused by commit +6e0c3339a6f19d748f16091d0a05adeb1e1f822b (USB: EHCI: unlink one async +QH at a time). In order to avoid keeping multiple QHs in an unusable +intermediate state, that commit changed unlink_empty_async() so that +it unlinks only one empty QH at a time. + +However, when the EHCI root hub is suspended, _all_ async QHs need to +be unlinked. ehci_bus_suspend() used to do this by calling +unlink_empty_async(), but now this only unlinks one of the QHs, not +all of them. + +The symptom is that when the root hub is resumed, USB communications +don't work for some period of time. This is because ehci-hcd doesn't +realize it needs to restart the async schedule; it assumes that +because some QHs are already on the schedule, the schedule must be +running. + +The easiest way to fix the problem is add a new function that unlinks +all the async QHs when the root hub is suspended. + +This patch should be applied to all kernels that have the 6e0c3339a6f1 +commit. + +Signed-off-by: Alan Stern +Reported-and-tested-by: Adrian Bassett +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-hcd.c | 1 + + drivers/usb/host/ehci-hub.c | 2 +- + drivers/usb/host/ehci-q.c | 13 +++++++++++++ + 3 files changed, 15 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -302,6 +302,7 @@ static void ehci_quiesce (struct ehci_hc + + static void end_unlink_async(struct ehci_hcd *ehci); + static void unlink_empty_async(struct ehci_hcd *ehci); ++static void unlink_empty_async_suspended(struct ehci_hcd *ehci); + static void ehci_work(struct ehci_hcd *ehci); + static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); + static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); +--- a/drivers/usb/host/ehci-hub.c ++++ b/drivers/usb/host/ehci-hub.c +@@ -328,7 +328,7 @@ static int ehci_bus_suspend (struct usb_ + ehci->rh_state = EHCI_RH_SUSPENDED; + + end_unlink_async(ehci); +- unlink_empty_async(ehci); ++ unlink_empty_async_suspended(ehci); + ehci_handle_intr_unlinks(ehci); + end_free_itds(ehci); + +--- a/drivers/usb/host/ehci-q.c ++++ b/drivers/usb/host/ehci-q.c +@@ -1316,6 +1316,19 @@ static void unlink_empty_async(struct eh + } + } + ++/* The root hub is suspended; unlink all the async QHs */ ++static void unlink_empty_async_suspended(struct ehci_hcd *ehci) ++{ ++ struct ehci_qh *qh; ++ ++ while (ehci->async->qh_next.qh) { ++ qh = ehci->async->qh_next.qh; ++ WARN_ON(!list_empty(&qh->qtd_list)); ++ single_unlink_async(ehci, qh); ++ } ++ start_iaa_cycle(ehci, false); ++} ++ + /* makes sure the async qh will become idle */ + /* caller must own ehci->lock */ + diff --git a/queue-3.8/usb-ehci-fix-regression-in-qh-unlinking.patch b/queue-3.8/usb-ehci-fix-regression-in-qh-unlinking.patch new file mode 100644 index 00000000000..77e9e993701 --- /dev/null +++ b/queue-3.8/usb-ehci-fix-regression-in-qh-unlinking.patch @@ -0,0 +1,49 @@ +From d714aaf649460cbfd5e82e75520baa856b4fa0a0 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 20 Mar 2013 15:07:26 -0400 +Subject: USB: EHCI: fix regression in QH unlinking + +From: Alan Stern + +commit d714aaf649460cbfd5e82e75520baa856b4fa0a0 upstream. + +This patch (as1670) fixes a regression caused by commit +6402c796d3b4205d3d7296157956c5100a05d7d6 (USB: EHCI: work around +silicon bug in Intel's EHCI controllers). The workaround goes through +two IAA cycles for each QH being unlinked. During the first cycle, +the QH is not added to the async_iaa list (because it isn't fully gone +from the hardware yet), which means that list will be empty. + +Unfortunately, I forgot to update the IAA watchdog timer routine. It +thinks that an empty async_iaa list means the timer expiration was an +error, which isn't true any more. This problem didn't show up during +initial testing because the controllers being tested all had working +IAA interrupts. But not all controllers do, and when the watchdog +timer expires, the empty-list check prevents the second IAA cycle from +starting. As a result, URB unlinks never complete. The check needs +to be removed. + +Among the symptoms of the regression are processes stuck in D wait +states and hangs during system shutdown. + +Signed-off-by: Alan Stern +Reported-and-tested-by: Stephen Warren +Reported-and-tested-by: Sven Joachim +Reported-by: Andreas Bombe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ehci-timer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/ehci-timer.c ++++ b/drivers/usb/host/ehci-timer.c +@@ -304,7 +304,7 @@ static void ehci_iaa_watchdog(struct ehc + * (a) SMP races against real IAA firing and retriggering, and + * (b) clean HC shutdown, when IAA watchdog was pending. + */ +- if (ehci->async_iaa) { ++ if (1) { + u32 cmd, status; + + /* If we get here, IAA is *REALLY* late. It's barely diff --git a/queue-3.8/usb-gadget-ffs-fix-enable-multiple-instances.patch b/queue-3.8/usb-gadget-ffs-fix-enable-multiple-instances.patch new file mode 100644 index 00000000000..7cc10c64d7d --- /dev/null +++ b/queue-3.8/usb-gadget-ffs-fix-enable-multiple-instances.patch @@ -0,0 +1,47 @@ +From 3416905ba058e43112ad7b1b4859797f027f5a07 Mon Sep 17 00:00:00 2001 +From: Andrzej Pietrasiewicz +Date: Mon, 11 Mar 2013 16:32:14 +0100 +Subject: usb: gadget: ffs: fix enable multiple instances + +From: Andrzej Pietrasiewicz + +commit 3416905ba058e43112ad7b1b4859797f027f5a07 upstream. + +This patch fixes an "off-by-one" bug found in +581791f (FunctionFS: enable multiple functions). + +During gfs_bind/gfs_unbind the functionfs_bind/functionfs_unbind should be +called for every functionfs instance. With the "i" pre-decremented they +were not called for the zeroth instance. + +Acked-by: Michal Nazarewicz +Signed-off-by: Andrzej Pietrasiewicz +Signed-off-by: Kyungmin Park +[ balbi@ti.com : added offending commit's subject ] +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/g_ffs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/g_ffs.c ++++ b/drivers/usb/gadget/g_ffs.c +@@ -357,7 +357,7 @@ static int gfs_bind(struct usb_composite + goto error; + gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id; + +- for (i = func_num; --i; ) { ++ for (i = func_num; i--; ) { + ret = functionfs_bind(ffs_tab[i].ffs_data, cdev); + if (unlikely(ret < 0)) { + while (++i < func_num) +@@ -413,7 +413,7 @@ static int gfs_unbind(struct usb_composi + gether_cleanup(); + gfs_ether_setup = false; + +- for (i = func_num; --i; ) ++ for (i = func_num; i--; ) + if (ffs_tab[i].ffs_data) + functionfs_unbind(ffs_tab[i].ffs_data); + diff --git a/queue-3.8/usb-serial-fix-interface-refcounting.patch b/queue-3.8/usb-serial-fix-interface-refcounting.patch new file mode 100644 index 00000000000..2b58247894d --- /dev/null +++ b/queue-3.8/usb-serial-fix-interface-refcounting.patch @@ -0,0 +1,41 @@ +From d7971051e4df825e0bc11b995e87bfe86355b8e5 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:09 +0100 +Subject: USB: serial: fix interface refcounting + +From: Johan Hovold + +commit d7971051e4df825e0bc11b995e87bfe86355b8e5 upstream. + +Make sure the interface is not released before our serial device. + +Note that drivers are still not allowed to access the interface in +any way that may interfere with another driver that may have gotten +bound to the same interface after disconnect returns. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/usb-serial.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/usb-serial.c ++++ b/drivers/usb/serial/usb-serial.c +@@ -151,6 +151,7 @@ static void destroy_serial(struct kref * + } + } + ++ usb_put_intf(serial->interface); + usb_put_dev(serial->dev); + kfree(serial); + } +@@ -614,7 +615,7 @@ static struct usb_serial *create_serial( + } + serial->dev = usb_get_dev(dev); + serial->type = driver; +- serial->interface = interface; ++ serial->interface = usb_get_intf(interface); + kref_init(&serial->kref); + mutex_init(&serial->disc_mutex); + serial->minor = SERIAL_TTY_NO_MINOR; diff --git a/queue-3.8/usb-storage-add-unusual_devs-entry-for-samsung-yp-z3-mp3-player.patch b/queue-3.8/usb-storage-add-unusual_devs-entry-for-samsung-yp-z3-mp3-player.patch new file mode 100644 index 00000000000..6df05ee197a --- /dev/null +++ b/queue-3.8/usb-storage-add-unusual_devs-entry-for-samsung-yp-z3-mp3-player.patch @@ -0,0 +1,37 @@ +From 29f86e66428ee083aec106cca1748dc63d98ce23 Mon Sep 17 00:00:00 2001 +From: Dmitry Artamonow +Date: Sat, 9 Mar 2013 20:30:58 +0400 +Subject: usb-storage: add unusual_devs entry for Samsung YP-Z3 mp3 player + +From: Dmitry Artamonow + +commit 29f86e66428ee083aec106cca1748dc63d98ce23 upstream. + +Device stucks on filesystem writes, unless following quirk is passed: + echo 04e8:5136:m > /sys/module/usb_storage/parameters/quirks + +Add corresponding entry to unusual_devs.h + +Signed-off-by: Dmitry Artamonow +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/unusual_devs.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -488,6 +488,13 @@ UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG), + ++/* Added by Dmitry Artamonow */ ++UNUSUAL_DEV( 0x04e8, 0x5136, 0x0000, 0x9999, ++ "Samsung", ++ "YP-Z3", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_MAX_SECTORS_64), ++ + /* Entry and supporting patch by Theodore Kilgore . + * Device uses standards-violating 32-byte Bulk Command Block Wrappers and + * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. diff --git a/queue-3.8/usb-xhci-correctly-enable-interrupts.patch b/queue-3.8/usb-xhci-correctly-enable-interrupts.patch new file mode 100644 index 00000000000..2890f603476 --- /dev/null +++ b/queue-3.8/usb-xhci-correctly-enable-interrupts.patch @@ -0,0 +1,99 @@ +From 00eed9c814cb8f281be6f0f5d8f45025dc0a97eb Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +Date: Mon, 4 Mar 2013 17:14:43 +0100 +Subject: USB: xhci: correctly enable interrupts + +From: Hannes Reinecke + +commit 00eed9c814cb8f281be6f0f5d8f45025dc0a97eb upstream. + +xhci has its own interrupt enabling routine, which will try to +use MSI-X/MSI if present. So the usb core shouldn't try to enable +legacy interrupts; on some machines the xhci legacy IRQ setting +is invalid. + +v3: Be careful to not break XHCI_BROKEN_MSI workaround (by trenn) + +Cc: Bjorn Helgaas +Cc: Oliver Neukum +Cc: Thomas Renninger +Cc: Yinghai Lu +Cc: Frederik Himpe +Cc: David Haerdeman +Cc: Alan Stern +Acked-by: Sarah Sharp +Reviewed-by: Thomas Renninger +Signed-off-by: Hannes Reinecke +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hcd-pci.c | 23 ++++++++++++++--------- + drivers/usb/host/xhci.c | 3 ++- + 2 files changed, 16 insertions(+), 10 deletions(-) + +--- a/drivers/usb/core/hcd-pci.c ++++ b/drivers/usb/core/hcd-pci.c +@@ -173,6 +173,7 @@ int usb_hcd_pci_probe(struct pci_dev *de + struct hc_driver *driver; + struct usb_hcd *hcd; + int retval; ++ int hcd_irq = 0; + + if (usb_disabled()) + return -ENODEV; +@@ -187,15 +188,19 @@ int usb_hcd_pci_probe(struct pci_dev *de + return -ENODEV; + dev->current_state = PCI_D0; + +- /* The xHCI driver supports MSI and MSI-X, +- * so don't fail if the BIOS doesn't provide a legacy IRQ. ++ /* ++ * The xHCI driver has its own irq management ++ * make sure irq setup is not touched for xhci in generic hcd code + */ +- if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) { +- dev_err(&dev->dev, +- "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", +- pci_name(dev)); +- retval = -ENODEV; +- goto disable_pci; ++ if ((driver->flags & HCD_MASK) != HCD_USB3) { ++ if (!dev->irq) { ++ dev_err(&dev->dev, ++ "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", ++ pci_name(dev)); ++ retval = -ENODEV; ++ goto disable_pci; ++ } ++ hcd_irq = dev->irq; + } + + hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev)); +@@ -245,7 +250,7 @@ int usb_hcd_pci_probe(struct pci_dev *de + + pci_set_master(dev); + +- retval = usb_add_hcd(hcd, dev->irq, IRQF_SHARED); ++ retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED); + if (retval != 0) + goto unmap_registers; + set_hs_companion(dev, hcd); +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -350,7 +350,7 @@ static int xhci_try_enable_msi(struct us + * generate interrupts. Don't even try to enable MSI. + */ + if (xhci->quirks & XHCI_BROKEN_MSI) +- return 0; ++ goto legacy_irq; + + /* unregister the legacy interrupt */ + if (hcd->irq) +@@ -371,6 +371,7 @@ static int xhci_try_enable_msi(struct us + return -EINVAL; + } + ++ legacy_irq: + /* fall back to legacy interrupt*/ + ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, + hcd->irq_descr, hcd); diff --git a/queue-3.8/usb-xhci-fix-bit-definitions-for-iman-register.patch b/queue-3.8/usb-xhci-fix-bit-definitions-for-iman-register.patch new file mode 100644 index 00000000000..1257725e830 --- /dev/null +++ b/queue-3.8/usb-xhci-fix-bit-definitions-for-iman-register.patch @@ -0,0 +1,42 @@ +From f8264340e694604863255cc0276491d17c402390 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Mon, 25 Feb 2013 10:56:01 -0800 +Subject: USB: xhci - fix bit definitions for IMAN register + +From: Dmitry Torokhov + +commit f8264340e694604863255cc0276491d17c402390 upstream. + +According to XHCI specification (5.5.2.1) the IP is bit 0 and IE is bit 1 +of IMAN register. Previously their definitions were reversed. + +Even though there are no ill effects being observed from the swapped +definitions (because IMAN_IP is RW1C and in legacy PCI case we come in +with it already set to 1 so it was clearing itself even though we were +setting IMAN_IE instead of IMAN_IP), we should still correct the values. + +This patch should be backported to kernels as old as 2.6.36, that +contain the commit 4e833c0b87a30798e67f06120cecebef6ee9644c "xhci: don't +re-enable IE constantly". + +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -206,8 +206,8 @@ struct xhci_op_regs { + /* bits 12:31 are reserved (and should be preserved on writes). */ + + /* IMAN - Interrupt Management Register */ +-#define IMAN_IP (1 << 1) +-#define IMAN_IE (1 << 0) ++#define IMAN_IE (1 << 1) ++#define IMAN_IP (1 << 0) + + /* USBSTS - USB status - status bitmasks */ + /* HC not running - set to 1 when run/stop bit is cleared. */ diff --git a/queue-3.8/watchdog-sp5100_tco-remove-code-that-may-cause-a-boot-failure.patch b/queue-3.8/watchdog-sp5100_tco-remove-code-that-may-cause-a-boot-failure.patch new file mode 100644 index 00000000000..9f4186d5169 --- /dev/null +++ b/queue-3.8/watchdog-sp5100_tco-remove-code-that-may-cause-a-boot-failure.patch @@ -0,0 +1,248 @@ +From 18e4321276fcf083b85b788fee7cf15be29ed72a Mon Sep 17 00:00:00 2001 +From: Takahisa Tanaka +Date: Sun, 3 Mar 2013 14:52:07 +0900 +Subject: watchdog: sp5100_tco: Remove code that may cause a boot failure + +From: Takahisa Tanaka + +commit 18e4321276fcf083b85b788fee7cf15be29ed72a upstream. + +A problem was found on PC's with the SB700 chipset: The PC fails to +load BIOS after running the 3.8.x kernel until the power is completely +cut off. It occurs in all 3.8.x versions and the mainline version as of +2/4. The issue does not occur with the 3.7.x builds. + +There are two methods for accessing the watchdog registers. + + 1. Re-programming a resource address obtained by allocate_resource() +to chipset. + 2. Use the direct memory-mapped IO access. + +The method 1 can be used by all the chipsets (SP5100, SB7x0, SB8x0 or +later). However, experience shows that only PC with the SB8x0 (or +later) chipsets can use the method 2. + +This patch removes the method 1, because the critical problem was found. +That's why the watchdog timer was able to be used on SP5100 and SB7x0 +chipsets until now. + +Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1116835 +Link: https://lkml.org/lkml/2013/2/14/271 + +Signed-off-by: Takahisa Tanaka +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/watchdog/sp5100_tco.c | 126 ++---------------------------------------- + 1 file changed, 6 insertions(+), 120 deletions(-) + +--- a/drivers/watchdog/sp5100_tco.c ++++ b/drivers/watchdog/sp5100_tco.c +@@ -40,13 +40,12 @@ + #include "sp5100_tco.h" + + /* Module and version information */ +-#define TCO_VERSION "0.03" ++#define TCO_VERSION "0.05" + #define TCO_MODULE_NAME "SP5100 TCO timer" + #define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION + + /* internal variables */ + static u32 tcobase_phys; +-static u32 resbase_phys; + static u32 tco_wdt_fired; + static void __iomem *tcobase; + static unsigned int pm_iobase; +@@ -54,10 +53,6 @@ static DEFINE_SPINLOCK(tco_lock); /* Gua + static unsigned long timer_alive; + static char tco_expect_close; + static struct pci_dev *sp5100_tco_pci; +-static struct resource wdt_res = { +- .name = "Watchdog Timer", +- .flags = IORESOURCE_MEM, +-}; + + /* the watchdog platform device */ + static struct platform_device *sp5100_tco_platform_device; +@@ -75,12 +70,6 @@ module_param(nowayout, bool, 0); + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started." + " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +-static unsigned int force_addr; +-module_param(force_addr, uint, 0); +-MODULE_PARM_DESC(force_addr, "Force the use of specified MMIO address." +- " ONLY USE THIS PARAMETER IF YOU REALLY KNOW" +- " WHAT YOU ARE DOING (default=none)"); +- + /* + * Some TCO specific functions + */ +@@ -176,39 +165,6 @@ static void tco_timer_enable(void) + } + } + +-static void tco_timer_disable(void) +-{ +- int val; +- +- if (sp5100_tco_pci->revision >= 0x40) { +- /* For SB800 or later */ +- /* Enable watchdog decode bit and Disable watchdog timer */ +- outb(SB800_PM_WATCHDOG_CONTROL, SB800_IO_PM_INDEX_REG); +- val = inb(SB800_IO_PM_DATA_REG); +- val |= SB800_PCI_WATCHDOG_DECODE_EN; +- val |= SB800_PM_WATCHDOG_DISABLE; +- outb(val, SB800_IO_PM_DATA_REG); +- } else { +- /* For SP5100 or SB7x0 */ +- /* Enable watchdog decode bit */ +- pci_read_config_dword(sp5100_tco_pci, +- SP5100_PCI_WATCHDOG_MISC_REG, +- &val); +- +- val |= SP5100_PCI_WATCHDOG_DECODE_EN; +- +- pci_write_config_dword(sp5100_tco_pci, +- SP5100_PCI_WATCHDOG_MISC_REG, +- val); +- +- /* Disable Watchdog timer */ +- outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG); +- val = inb(SP5100_IO_PM_DATA_REG); +- val |= SP5100_PM_WATCHDOG_DISABLE; +- outb(val, SP5100_IO_PM_DATA_REG); +- } +-} +- + /* + * /dev/watchdog handling + */ +@@ -361,7 +317,7 @@ static unsigned char sp5100_tco_setupdev + { + struct pci_dev *dev = NULL; + const char *dev_name = NULL; +- u32 val, tmp_val; ++ u32 val; + u32 index_reg, data_reg, base_addr; + + /* Match the PCI device */ +@@ -459,63 +415,8 @@ static unsigned char sp5100_tco_setupdev + } else + pr_debug("SBResource_MMIO is disabled(0x%04x)\n", val); + +- /* +- * Lastly re-programming the watchdog timer MMIO address, +- * This method is a last resort... +- * +- * Before re-programming, to ensure that the watchdog timer +- * is disabled, disable the watchdog timer. +- */ +- tco_timer_disable(); +- +- if (force_addr) { +- /* +- * Force the use of watchdog timer MMIO address, and aligned to +- * 8byte boundary. +- */ +- force_addr &= ~0x7; +- val = force_addr; +- +- pr_info("Force the use of 0x%04x as MMIO address\n", val); +- } else { +- /* +- * Get empty slot into the resource tree for watchdog timer. +- */ +- if (allocate_resource(&iomem_resource, +- &wdt_res, +- SP5100_WDT_MEM_MAP_SIZE, +- 0xf0000000, +- 0xfffffff8, +- 0x8, +- NULL, +- NULL)) { +- pr_err("MMIO allocation failed\n"); +- goto unreg_region; +- } +- +- val = resbase_phys = wdt_res.start; +- pr_debug("Got 0x%04x from resource tree\n", val); +- } +- +- /* Restore to the low three bits */ +- outb(base_addr+0, index_reg); +- tmp_val = val | (inb(data_reg) & 0x7); +- +- /* Re-programming the watchdog timer base address */ +- outb(base_addr+0, index_reg); +- outb((tmp_val >> 0) & 0xff, data_reg); +- outb(base_addr+1, index_reg); +- outb((tmp_val >> 8) & 0xff, data_reg); +- outb(base_addr+2, index_reg); +- outb((tmp_val >> 16) & 0xff, data_reg); +- outb(base_addr+3, index_reg); +- outb((tmp_val >> 24) & 0xff, data_reg); +- +- if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE, +- dev_name)) { +- pr_err("MMIO address 0x%04x already in use\n", val); +- goto unreg_resource; +- } ++ pr_notice("failed to find MMIO address, giving up.\n"); ++ goto unreg_region; + + setup_wdt: + tcobase_phys = val; +@@ -555,9 +456,6 @@ setup_wdt: + + unreg_mem_region: + release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); +-unreg_resource: +- if (resbase_phys) +- release_resource(&wdt_res); + unreg_region: + release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); + exit: +@@ -567,7 +465,6 @@ exit: + static int sp5100_tco_init(struct platform_device *dev) + { + int ret; +- char addr_str[16]; + + /* + * Check whether or not the hardware watchdog is there. If found, then +@@ -599,23 +496,14 @@ static int sp5100_tco_init(struct platfo + clear_bit(0, &timer_alive); + + /* Show module parameters */ +- if (force_addr == tcobase_phys) +- /* The force_addr is vaild */ +- sprintf(addr_str, "0x%04x", force_addr); +- else +- strcpy(addr_str, "none"); +- +- pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d, " +- "force_addr=%s)\n", +- tcobase, heartbeat, nowayout, addr_str); ++ pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", ++ tcobase, heartbeat, nowayout); + + return 0; + + exit: + iounmap(tcobase); + release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); +- if (resbase_phys) +- release_resource(&wdt_res); + release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); + return ret; + } +@@ -630,8 +518,6 @@ static void sp5100_tco_cleanup(void) + misc_deregister(&sp5100_tco_miscdev); + iounmap(tcobase); + release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); +- if (resbase_phys) +- release_resource(&wdt_res); + release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); + } + diff --git a/queue-3.8/watchdog-sp5100_tco-set-the-acpimmiosel-bitmask-value-to-1-instead-of-2.patch b/queue-3.8/watchdog-sp5100_tco-set-the-acpimmiosel-bitmask-value-to-1-instead-of-2.patch new file mode 100644 index 00000000000..00cb487d481 --- /dev/null +++ b/queue-3.8/watchdog-sp5100_tco-set-the-acpimmiosel-bitmask-value-to-1-instead-of-2.patch @@ -0,0 +1,51 @@ +From 81fc933f176cd95f757bfc8a98109ef422598b79 Mon Sep 17 00:00:00 2001 +From: Takahisa Tanaka +Date: Sun, 3 Mar 2013 14:48:00 +0900 +Subject: watchdog: sp5100_tco: Set the AcpiMmioSel bitmask value to 1 instead of 2 + +From: Takahisa Tanaka + +commit 81fc933f176cd95f757bfc8a98109ef422598b79 upstream. + +The AcpiMmioSel bit is bit 1 in the AcpiMmioEn register, but the current +sp5100_tco driver is using bit 2. + +See 2.3.3 Power Management (PM) Registers page 150 of the +AMD SB800-Series Southbridges Register Reference Guide [1]. + + AcpiMmioEn - RW – 8/16/32 bits - [PM_Reg: 24h] + Field Name Bits Default Description + AcpiMMioDecodeEn 0 0b Set to 1 to enable AcpiMMio space. + AcpiMMIoSel 1 0b Set AcpiMMio registers to be memory-mapped or IO-mapped space. + 0: Memory-mapped space + 1: I/O-mapped space + +The sp5100_tco driver expects zero as a value of AcpiMmioSel (bit 1). + +Fortunately, no problems were caused by this typo, because the default +value of the undocumented misused bit 2 seems to be zero. + +However, the sp5100_tco driver should use the correct bitmask value. + +[1] http://support.amd.com/us/Embedded_TechDocs/45482.pdf + +Signed-off-by: Takahisa Tanaka +Signed-off-by: Paul Menzel +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/watchdog/sp5100_tco.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/watchdog/sp5100_tco.h ++++ b/drivers/watchdog/sp5100_tco.h +@@ -57,7 +57,7 @@ + #define SB800_PM_WATCHDOG_DISABLE (1 << 2) + #define SB800_PM_WATCHDOG_SECOND_RES (3 << 0) + #define SB800_ACPI_MMIO_DECODE_EN (1 << 0) +-#define SB800_ACPI_MMIO_SEL (1 << 2) ++#define SB800_ACPI_MMIO_SEL (1 << 1) + + + #define SB800_PM_WDT_MMIO_OFFSET 0xB00 diff --git a/queue-3.8/x86-64-fix-the-failure-case-in-copy_user_handle_tail.patch b/queue-3.8/x86-64-fix-the-failure-case-in-copy_user_handle_tail.patch new file mode 100644 index 00000000000..4d1add31c74 --- /dev/null +++ b/queue-3.8/x86-64-fix-the-failure-case-in-copy_user_handle_tail.patch @@ -0,0 +1,40 @@ +From 66db3feb486c01349f767b98ebb10b0c3d2d021b Mon Sep 17 00:00:00 2001 +From: CQ Tang +Date: Mon, 18 Mar 2013 11:02:21 -0400 +Subject: x86-64: Fix the failure case in copy_user_handle_tail() + +From: CQ Tang + +commit 66db3feb486c01349f767b98ebb10b0c3d2d021b upstream. + +The increment of "to" in copy_user_handle_tail() will have incremented +before a failure has been noted. This causes us to skip a byte in the +failure case. + +Only do the increment when assured there is no failure. + +Signed-off-by: CQ Tang +Link: http://lkml.kernel.org/r/20130318150221.8439.993.stgit@phlsvslse11.ph.intel.com +Signed-off-by: Mike Marciniszyn +Signed-off-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/lib/usercopy_64.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/lib/usercopy_64.c ++++ b/arch/x86/lib/usercopy_64.c +@@ -74,10 +74,10 @@ copy_user_handle_tail(char *to, char *fr + char c; + unsigned zero_len; + +- for (; len; --len) { ++ for (; len; --len, to++) { + if (__get_user_nocheck(c, from++, sizeof(char))) + break; +- if (__put_user_nocheck(c, to++, sizeof(char))) ++ if (__put_user_nocheck(c, to, sizeof(char))) + break; + } +