From 909ecba21b3a070eede09cf44750604c821375e8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Jan 2012 16:33:25 -0800 Subject: [PATCH] 3.2-stable patches added patches: atmel_serial-fix-spinlock-lockup-in-rs485-code.patch cgroup-fix-to-allow-mounting-a-hierarchy-by-name.patch drivers-hv-don-t-oops-when-you-cannot-init-vmbus.patch drivers-hv-fix-a-bug-in-vmbus_driver_unregister.patch drivers-usb-class-cdc-acm.c-clear-dangling-pointer.patch ext3-don-t-warn-from-writepage-when-readonly-inode-is-spotted-after-error.patch ib-qib-fix-a-possible-data-corruption-when-receiving.patch ib-uverbs-protect-qp-multicast-list.patch iwlagn-fix-remove-use-of-page_size.patch iwlagn-fix-tid-use-bug.patch ore-fix-breakage-when-misc_filesystems-is-not-set.patch ore-fix-bug_on-too-few-sgs-when-reading.patch ore-fix-crash-in-case-of-an-io-error.patch ore-must-support-none-page-aligned-io.patch perf-fix-parsing-of-__print_flags-in-tp_printk.patch reiserfs-fix-quota-mount-option-parsing.patch reiserfs-force-inode-evictions-before-umount-to-avoid-crash.patch udf-fix-deadlock-when-converting-file-from-in-icb-one-to-normal-one.patch usbfs-fix-oops-related-to-user-namespace-conversion.patch usb-isight-fix-kernel-bug-when-loading-firmware.patch usb-update-documentation-for-usbmon.patch --- ...al-fix-spinlock-lockup-in-rs485-code.patch | 45 +++++ ...o-allow-mounting-a-hierarchy-by-name.patch | 48 +++++ ...on-t-oops-when-you-cannot-init-vmbus.patch | 68 +++++++ ...fix-a-bug-in-vmbus_driver_unregister.patch | 38 ++++ ...ass-cdc-acm.c-clear-dangling-pointer.patch | 43 +++++ ...eadonly-inode-is-spotted-after-error.patch | 70 +++++++ ...sible-data-corruption-when-receiving.patch | 72 +++++++ .../ib-uverbs-protect-qp-multicast-list.patch | 94 +++++++++ .../iwlagn-fix-remove-use-of-page_size.patch | 178 ++++++++++++++++++ queue-3.2/iwlagn-fix-tid-use-bug.patch | 48 +++++ ...age-when-misc_filesystems-is-not-set.patch | 81 ++++++++ ...-fix-bug_on-too-few-sgs-when-reading.patch | 52 +++++ ...ore-fix-crash-in-case-of-an-io-error.patch | 39 ++++ ...re-must-support-none-page-aligned-io.patch | 161 ++++++++++++++++ ...arsing-of-__print_flags-in-tp_printk.patch | 35 ++++ ...serfs-fix-quota-mount-option-parsing.patch | 32 ++++ ...ictions-before-umount-to-avoid-crash.patch | 67 +++++++ queue-3.2/series | 21 +++ ...g-file-from-in-icb-one-to-normal-one.patch | 125 ++++++++++++ ...fix-kernel-bug-when-loading-firmware.patch | 45 +++++ .../usb-update-documentation-for-usbmon.patch | 52 +++++ ...related-to-user-namespace-conversion.patch | 123 ++++++++++++ 22 files changed, 1537 insertions(+) create mode 100644 queue-3.2/atmel_serial-fix-spinlock-lockup-in-rs485-code.patch create mode 100644 queue-3.2/cgroup-fix-to-allow-mounting-a-hierarchy-by-name.patch create mode 100644 queue-3.2/drivers-hv-don-t-oops-when-you-cannot-init-vmbus.patch create mode 100644 queue-3.2/drivers-hv-fix-a-bug-in-vmbus_driver_unregister.patch create mode 100644 queue-3.2/drivers-usb-class-cdc-acm.c-clear-dangling-pointer.patch create mode 100644 queue-3.2/ext3-don-t-warn-from-writepage-when-readonly-inode-is-spotted-after-error.patch create mode 100644 queue-3.2/ib-qib-fix-a-possible-data-corruption-when-receiving.patch create mode 100644 queue-3.2/ib-uverbs-protect-qp-multicast-list.patch create mode 100644 queue-3.2/iwlagn-fix-remove-use-of-page_size.patch create mode 100644 queue-3.2/iwlagn-fix-tid-use-bug.patch create mode 100644 queue-3.2/ore-fix-breakage-when-misc_filesystems-is-not-set.patch create mode 100644 queue-3.2/ore-fix-bug_on-too-few-sgs-when-reading.patch create mode 100644 queue-3.2/ore-fix-crash-in-case-of-an-io-error.patch create mode 100644 queue-3.2/ore-must-support-none-page-aligned-io.patch create mode 100644 queue-3.2/perf-fix-parsing-of-__print_flags-in-tp_printk.patch create mode 100644 queue-3.2/reiserfs-fix-quota-mount-option-parsing.patch create mode 100644 queue-3.2/reiserfs-force-inode-evictions-before-umount-to-avoid-crash.patch create mode 100644 queue-3.2/udf-fix-deadlock-when-converting-file-from-in-icb-one-to-normal-one.patch create mode 100644 queue-3.2/usb-isight-fix-kernel-bug-when-loading-firmware.patch create mode 100644 queue-3.2/usb-update-documentation-for-usbmon.patch create mode 100644 queue-3.2/usbfs-fix-oops-related-to-user-namespace-conversion.patch diff --git a/queue-3.2/atmel_serial-fix-spinlock-lockup-in-rs485-code.patch b/queue-3.2/atmel_serial-fix-spinlock-lockup-in-rs485-code.patch new file mode 100644 index 00000000000..20661091fbf --- /dev/null +++ b/queue-3.2/atmel_serial-fix-spinlock-lockup-in-rs485-code.patch @@ -0,0 +1,45 @@ +From dbf1115d3f8c7052788aa4e6e46abd27f3b3eeba Mon Sep 17 00:00:00 2001 +From: Claudio Scordino +Date: Fri, 16 Dec 2011 15:08:49 +0100 +Subject: atmel_serial: fix spinlock lockup in RS485 code + +From: Claudio Scordino + +commit dbf1115d3f8c7052788aa4e6e46abd27f3b3eeba upstream. + +Patch to fix a spinlock lockup in the driver that sometimes happens when the +tasklet starts. + +Signed-off-by: Claudio Scordino +Signed-off-by: Dave Bender +Tested-by: Dave Bender +Acked-by: Nicolas Ferre +Acked-by: Alan Cox +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/serial/atmel_serial.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -212,8 +212,9 @@ void atmel_config_rs485(struct uart_port + { + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + unsigned int mode; ++ unsigned long flags; + +- spin_lock(&port->lock); ++ spin_lock_irqsave(&port->lock, flags); + + /* Disable interrupts */ + UART_PUT_IDR(port, atmel_port->tx_done_mask); +@@ -244,7 +245,7 @@ void atmel_config_rs485(struct uart_port + /* Enable interrupts */ + UART_PUT_IER(port, atmel_port->tx_done_mask); + +- spin_unlock(&port->lock); ++ spin_unlock_irqrestore(&port->lock, flags); + + } + diff --git a/queue-3.2/cgroup-fix-to-allow-mounting-a-hierarchy-by-name.patch b/queue-3.2/cgroup-fix-to-allow-mounting-a-hierarchy-by-name.patch new file mode 100644 index 00000000000..2dd8280ad0f --- /dev/null +++ b/queue-3.2/cgroup-fix-to-allow-mounting-a-hierarchy-by-name.patch @@ -0,0 +1,48 @@ +From 0d19ea866562e46989412a0676412fa0983c9ce7 Mon Sep 17 00:00:00 2001 +From: Li Zefan +Date: Tue, 27 Dec 2011 14:25:55 +0800 +Subject: cgroup: fix to allow mounting a hierarchy by name + +From: Li Zefan + +commit 0d19ea866562e46989412a0676412fa0983c9ce7 upstream. + +If we mount a hierarchy with a specified name, the name is unique, +and we can use it to mount the hierarchy without specifying its +set of subsystem names. This feature is documented is +Documentation/cgroups/cgroups.txt section 2.3 + +Here's an example: + + # mount -t cgroup -o cpuset,name=myhier xxx /cgroup1 + # mount -t cgroup -o name=myhier xxx /cgroup2 + +But it was broken by commit 32a8cf235e2f192eb002755076994525cdbaa35a +(cgroup: make the mount options parsing more accurate) + +This fixes the regression. + +Signed-off-by: Li Zefan +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/cgroup.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -1175,10 +1175,10 @@ static int parse_cgroupfs_options(char * + + /* + * If the 'all' option was specified select all the subsystems, +- * otherwise 'all, 'none' and a subsystem name options were not +- * specified, let's default to 'all' ++ * otherwise if 'none', 'name=' and a subsystem name options ++ * were not specified, let's default to 'all' + */ +- if (all_ss || (!all_ss && !one_ss && !opts->none)) { ++ if (all_ss || (!one_ss && !opts->none && !opts->name)) { + for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { + struct cgroup_subsys *ss = subsys[i]; + if (ss == NULL) diff --git a/queue-3.2/drivers-hv-don-t-oops-when-you-cannot-init-vmbus.patch b/queue-3.2/drivers-hv-don-t-oops-when-you-cannot-init-vmbus.patch new file mode 100644 index 00000000000..b565195cc98 --- /dev/null +++ b/queue-3.2/drivers-hv-don-t-oops-when-you-cannot-init-vmbus.patch @@ -0,0 +1,68 @@ +From cf6a2eacbcb2593b5b91d0817915c4f0464bb534 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Thu, 1 Dec 2011 09:59:34 -0800 +Subject: drivers: hv: Don't OOPS when you cannot init vmbus + +From: "K. Y. Srinivasan" + +commit cf6a2eacbcb2593b5b91d0817915c4f0464bb534 upstream. + +The hv vmbus driver was causing an OOPS since it was trying to register drivers +on top of the bus even if initialization of the bus has failed for some +reason (such as the odd chance someone would run a hv enabled kernel in a +non-hv environment). + +Signed-off-by: Sasha Levin +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hv/vmbus_drv.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -62,6 +62,14 @@ struct hv_device_info { + struct hv_dev_port_info outbound; + }; + ++static int vmbus_exists(void) ++{ ++ if (hv_acpi_dev == NULL) ++ return -ENODEV; ++ ++ return 0; ++} ++ + + static void get_channel_info(struct hv_device *device, + struct hv_device_info *info) +@@ -590,6 +598,10 @@ int __vmbus_driver_register(struct hv_dr + + pr_info("registering driver %s\n", hv_driver->name); + ++ ret = vmbus_exists(); ++ if (ret < 0) ++ return ret; ++ + hv_driver->driver.name = hv_driver->name; + hv_driver->driver.owner = owner; + hv_driver->driver.mod_name = mod_name; +@@ -614,6 +626,9 @@ void vmbus_driver_unregister(struct hv_d + { + pr_info("unregistering driver %s\n", hv_driver->name); + ++ if (!vmbus_exists()) ++ return; ++ + driver_unregister(&hv_driver->driver); + + } +@@ -776,6 +791,7 @@ static int __init hv_acpi_init(void) + + cleanup: + acpi_bus_unregister_driver(&vmbus_acpi_driver); ++ hv_acpi_dev = NULL; + return ret; + } + diff --git a/queue-3.2/drivers-hv-fix-a-bug-in-vmbus_driver_unregister.patch b/queue-3.2/drivers-hv-fix-a-bug-in-vmbus_driver_unregister.patch new file mode 100644 index 00000000000..8b80154aa28 --- /dev/null +++ b/queue-3.2/drivers-hv-fix-a-bug-in-vmbus_driver_unregister.patch @@ -0,0 +1,38 @@ +From 8f257a142fc3868d69de3f996b95d7bdbc509560 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" +Date: Tue, 27 Dec 2011 13:49:37 -0800 +Subject: Drivers:hv: Fix a bug in vmbus_driver_unregister() + +From: "K. Y. Srinivasan" + +commit 8f257a142fc3868d69de3f996b95d7bdbc509560 upstream. + +The function vmbus_exists() was introduced recently to deal with cases where +the vmbus driver failed to initialize and yet other Hyper-V drivers attempted +to register with the vmbus bus driver. This patch introduced a bug where +vmbus_driver_unregister() would fail to unregister the driver. This patch +fixes the problem. + +Signed-off-by: K. Y. Srinivasan +Signed-off-by: Fuzhou Chen +Cc: Sasha Levin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hv/vmbus_drv.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -627,10 +627,7 @@ void vmbus_driver_unregister(struct hv_d + pr_info("unregistering driver %s\n", hv_driver->name); + + if (!vmbus_exists()) +- return; +- +- driver_unregister(&hv_driver->driver); +- ++ driver_unregister(&hv_driver->driver); + } + EXPORT_SYMBOL_GPL(vmbus_driver_unregister); + diff --git a/queue-3.2/drivers-usb-class-cdc-acm.c-clear-dangling-pointer.patch b/queue-3.2/drivers-usb-class-cdc-acm.c-clear-dangling-pointer.patch new file mode 100644 index 00000000000..cf23662567f --- /dev/null +++ b/queue-3.2/drivers-usb-class-cdc-acm.c-clear-dangling-pointer.patch @@ -0,0 +1,43 @@ +From e7c8e8605d0bafc705ff27f9da98a1668427cc0f Mon Sep 17 00:00:00 2001 +From: Julia Lawall +Date: Fri, 23 Dec 2011 14:02:55 +0100 +Subject: drivers/usb/class/cdc-acm.c: clear dangling pointer + +From: Julia Lawall + +commit e7c8e8605d0bafc705ff27f9da98a1668427cc0f upstream. + +On some failures, the country_code field of an acm structure is freed +without freeing the acm structure itself. Elsewhere, operations including +memcpy and kfree are performed on the country_code field. The patch sets +the country_code field to NULL when it is freed, and likewise sets the +country_code_size field to 0. + +Signed-off-by: Julia Lawall +Acked-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-acm.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1183,6 +1183,8 @@ made_compressed_probe: + i = device_create_file(&intf->dev, &dev_attr_wCountryCodes); + if (i < 0) { + kfree(acm->country_codes); ++ acm->country_codes = NULL; ++ acm->country_code_size = 0; + goto skip_countries; + } + +@@ -1191,6 +1193,8 @@ made_compressed_probe: + if (i < 0) { + device_remove_file(&intf->dev, &dev_attr_wCountryCodes); + kfree(acm->country_codes); ++ acm->country_codes = NULL; ++ acm->country_code_size = 0; + goto skip_countries; + } + } diff --git a/queue-3.2/ext3-don-t-warn-from-writepage-when-readonly-inode-is-spotted-after-error.patch b/queue-3.2/ext3-don-t-warn-from-writepage-when-readonly-inode-is-spotted-after-error.patch new file mode 100644 index 00000000000..0eff4594201 --- /dev/null +++ b/queue-3.2/ext3-don-t-warn-from-writepage-when-readonly-inode-is-spotted-after-error.patch @@ -0,0 +1,70 @@ +From 33c104d415e92a51aaf638dc3d93920cfa601e5c Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 22 Dec 2011 16:49:05 +0100 +Subject: ext3: Don't warn from writepage when readonly inode is spotted after error + +From: Jan Kara + +commit 33c104d415e92a51aaf638dc3d93920cfa601e5c upstream. + +WARN_ON_ONCE(IS_RDONLY(inode)) tends to trip when filesystem hits error and is +remounted read-only. This unnecessarily scares users (well, they should be +scared because of filesystem error, but the stack trace distracts them from the +right source of their fear ;-). We could as well just remove the WARN_ON but +it's not hard to fix it to not trip on filesystem with errors and not use more +cycles in the common case so that's what we do. + +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext3/inode.c | 24 +++++++++++++++++++++--- + 1 file changed, 21 insertions(+), 3 deletions(-) + +--- a/fs/ext3/inode.c ++++ b/fs/ext3/inode.c +@@ -1617,7 +1617,13 @@ static int ext3_ordered_writepage(struct + int err; + + J_ASSERT(PageLocked(page)); +- WARN_ON_ONCE(IS_RDONLY(inode)); ++ /* ++ * We don't want to warn for emergency remount. The condition is ++ * ordered to avoid dereferencing inode->i_sb in non-error case to ++ * avoid slow-downs. ++ */ ++ WARN_ON_ONCE(IS_RDONLY(inode) && ++ !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS)); + + /* + * We give up here if we're reentered, because it might be for a +@@ -1692,7 +1698,13 @@ static int ext3_writeback_writepage(stru + int err; + + J_ASSERT(PageLocked(page)); +- WARN_ON_ONCE(IS_RDONLY(inode)); ++ /* ++ * We don't want to warn for emergency remount. The condition is ++ * ordered to avoid dereferencing inode->i_sb in non-error case to ++ * avoid slow-downs. ++ */ ++ WARN_ON_ONCE(IS_RDONLY(inode) && ++ !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS)); + + if (ext3_journal_current_handle()) + goto out_fail; +@@ -1735,7 +1747,13 @@ static int ext3_journalled_writepage(str + int err; + + J_ASSERT(PageLocked(page)); +- WARN_ON_ONCE(IS_RDONLY(inode)); ++ /* ++ * We don't want to warn for emergency remount. The condition is ++ * ordered to avoid dereferencing inode->i_sb in non-error case to ++ * avoid slow-downs. ++ */ ++ WARN_ON_ONCE(IS_RDONLY(inode) && ++ !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS)); + + if (ext3_journal_current_handle()) + goto no_write; diff --git a/queue-3.2/ib-qib-fix-a-possible-data-corruption-when-receiving.patch b/queue-3.2/ib-qib-fix-a-possible-data-corruption-when-receiving.patch new file mode 100644 index 00000000000..d9d945972c4 --- /dev/null +++ b/queue-3.2/ib-qib-fix-a-possible-data-corruption-when-receiving.patch @@ -0,0 +1,72 @@ +From eddfb675256f49d14e8c5763098afe3eb2c93701 Mon Sep 17 00:00:00 2001 +From: Ram Vepa +Date: Fri, 23 Dec 2011 08:01:43 -0500 +Subject: IB/qib: Fix a possible data corruption when receiving + packets + +From: Ram Vepa + +commit eddfb675256f49d14e8c5763098afe3eb2c93701 upstream. + +Prevent a receive data corruption by ensuring that the write to update +the rcvhdrheadn register to generate an interrupt is at the very end +of the receive processing. + +Signed-off-by: Ramkrishna Vepa +Signed-off-by: Mike Marciniszyn +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/qib/qib_iba6120.c | 4 +++- + drivers/infiniband/hw/qib/qib_iba7220.c | 4 +++- + drivers/infiniband/hw/qib/qib_iba7322.c | 6 ++++-- + 3 files changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/infiniband/hw/qib/qib_iba6120.c ++++ b/drivers/infiniband/hw/qib/qib_iba6120.c +@@ -2076,9 +2076,11 @@ static void qib_6120_config_ctxts(struct + static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd, + u32 updegr, u32 egrhd, u32 npkts) + { +- qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); + if (updegr) + qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); ++ mmiowb(); ++ qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); ++ mmiowb(); + } + + static u32 qib_6120_hdrqempty(struct qib_ctxtdata *rcd) +--- a/drivers/infiniband/hw/qib/qib_iba7220.c ++++ b/drivers/infiniband/hw/qib/qib_iba7220.c +@@ -2725,9 +2725,11 @@ static int qib_7220_set_loopback(struct + static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd, + u32 updegr, u32 egrhd, u32 npkts) + { +- qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); + if (updegr) + qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); ++ mmiowb(); ++ qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); ++ mmiowb(); + } + + static u32 qib_7220_hdrqempty(struct qib_ctxtdata *rcd) +--- a/drivers/infiniband/hw/qib/qib_iba7322.c ++++ b/drivers/infiniband/hw/qib/qib_iba7322.c +@@ -4082,10 +4082,12 @@ static void qib_update_7322_usrhead(stru + */ + if (hd >> IBA7322_HDRHEAD_PKTINT_SHIFT) + adjust_rcv_timeout(rcd, npkts); +- qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); +- qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); + if (updegr) + qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); ++ mmiowb(); ++ qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); ++ qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); ++ mmiowb(); + } + + static u32 qib_7322_hdrqempty(struct qib_ctxtdata *rcd) diff --git a/queue-3.2/ib-uverbs-protect-qp-multicast-list.patch b/queue-3.2/ib-uverbs-protect-qp-multicast-list.patch new file mode 100644 index 00000000000..72129ca6042 --- /dev/null +++ b/queue-3.2/ib-uverbs-protect-qp-multicast-list.patch @@ -0,0 +1,94 @@ +From e214a0fe2b382fa302c036ecd6e6ffe99e3b9875 Mon Sep 17 00:00:00 2001 +From: Eli Cohen +Date: Tue, 3 Jan 2012 20:36:48 -0800 +Subject: IB/uverbs: Protect QP multicast list + +From: Eli Cohen + +commit e214a0fe2b382fa302c036ecd6e6ffe99e3b9875 upstream. + +Userspace verbs multicast attach/detach operations on a QP are done +while holding the rwsem of the QP for reading. That's not sufficient +since a reader lock allows more than one reader to acquire the +lock. However, multicast attach/detach does list manipulation that +can corrupt the list if multiple threads run in parallel. + +Fix this by acquiring the rwsem as a writer to serialize attach/detach +operations. Add idr_write_qp() and put_qp_write() to encapsulate +this. + +This fixes oops seen when running applications that perform multicast +joins/leaves. + +Reported by: Mike Dubman +Signed-off-by: Eli Cohen +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/uverbs_cmd.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -241,11 +241,24 @@ static struct ib_qp *idr_read_qp(int qp_ + return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context, 0); + } + ++static struct ib_qp *idr_write_qp(int qp_handle, struct ib_ucontext *context) ++{ ++ struct ib_uobject *uobj; ++ ++ uobj = idr_write_uobj(&ib_uverbs_qp_idr, qp_handle, context); ++ return uobj ? uobj->object : NULL; ++} ++ + static void put_qp_read(struct ib_qp *qp) + { + put_uobj_read(qp->uobject); + } + ++static void put_qp_write(struct ib_qp *qp) ++{ ++ put_uobj_write(qp->uobject); ++} ++ + static struct ib_srq *idr_read_srq(int srq_handle, struct ib_ucontext *context) + { + return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context, 0); +@@ -2375,7 +2388,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + +- qp = idr_read_qp(cmd.qp_handle, file->ucontext); ++ qp = idr_write_qp(cmd.qp_handle, file->ucontext); + if (!qp) + return -EINVAL; + +@@ -2404,7 +2417,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib + kfree(mcast); + + out_put: +- put_qp_read(qp); ++ put_qp_write(qp); + + return ret ? ret : in_len; + } +@@ -2422,7 +2435,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib + if (copy_from_user(&cmd, buf, sizeof cmd)) + return -EFAULT; + +- qp = idr_read_qp(cmd.qp_handle, file->ucontext); ++ qp = idr_write_qp(cmd.qp_handle, file->ucontext); + if (!qp) + return -EINVAL; + +@@ -2441,7 +2454,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib + } + + out_put: +- put_qp_read(qp); ++ put_qp_write(qp); + + return ret ? ret : in_len; + } diff --git a/queue-3.2/iwlagn-fix-remove-use-of-page_size.patch b/queue-3.2/iwlagn-fix-remove-use-of-page_size.patch new file mode 100644 index 00000000000..ef78910c5d4 --- /dev/null +++ b/queue-3.2/iwlagn-fix-remove-use-of-page_size.patch @@ -0,0 +1,178 @@ +From 106671369e6d046c0b3e1e72b18ad6dd9cb298b0 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Mon, 19 Dec 2011 14:00:59 -0800 +Subject: iwlagn: fix (remove) use of PAGE_SIZE + +From: Johannes Berg + +commit 106671369e6d046c0b3e1e72b18ad6dd9cb298b0 upstream. + +The ICT code erroneously uses PAGE_SIZE. The bug +is that PAGE_SIZE isn't necessarily 4096, so on +such platforms this code will not work correctly +as we'll try to attempt to read an index in the +table that the device never wrote, it always has +4096-byte pages. + +Additionally, the manual alignment code here is +unnecessary -- Documentation/DMA-API-HOWTO.txt +states: + The cpu return address and the DMA bus master address are both + guaranteed to be aligned to the smallest PAGE_SIZE order which + is greater than or equal to the requested size. This invariant + exists (for example) to guarantee that if you allocate a chunk + which is smaller than or equal to 64 kilobytes, the extent of the + buffer you receive will not cross a 64K boundary. + +Just use appropriate new constants and get rid of +the alignment code. + +Cc: Emmanuel Grumbach +Signed-off-by: Johannes Berg +Signed-off-by: Wey-Yi Guy +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 + drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 77 +++++++++------------- + 2 files changed, 33 insertions(+), 46 deletions(-) + +--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h ++++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +@@ -219,9 +219,7 @@ struct iwl_trans_pcie { + + /* INT ICT Table */ + __le32 *ict_tbl; +- void *ict_tbl_vir; + dma_addr_t ict_tbl_dma; +- dma_addr_t aligned_ict_tbl_dma; + int ict_index; + u32 inta; + bool use_ict; +--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c ++++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +@@ -1136,7 +1136,11 @@ void iwl_irq_tasklet(struct iwl_trans *t + * ICT functions + * + ******************************************************************************/ +-#define ICT_COUNT (PAGE_SIZE/sizeof(u32)) ++ ++/* a device (PCI-E) page is 4096 bytes long */ ++#define ICT_SHIFT 12 ++#define ICT_SIZE (1 << ICT_SHIFT) ++#define ICT_COUNT (ICT_SIZE / sizeof(u32)) + + /* Free dram table */ + void iwl_free_isr_ict(struct iwl_trans *trans) +@@ -1144,21 +1148,19 @@ void iwl_free_isr_ict(struct iwl_trans * + struct iwl_trans_pcie *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + +- if (trans_pcie->ict_tbl_vir) { +- dma_free_coherent(bus(trans)->dev, +- (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, +- trans_pcie->ict_tbl_vir, ++ if (trans_pcie->ict_tbl) { ++ dma_free_coherent(bus(trans)->dev, ICT_SIZE, ++ trans_pcie->ict_tbl, + trans_pcie->ict_tbl_dma); +- trans_pcie->ict_tbl_vir = NULL; +- memset(&trans_pcie->ict_tbl_dma, 0, +- sizeof(trans_pcie->ict_tbl_dma)); +- memset(&trans_pcie->aligned_ict_tbl_dma, 0, +- sizeof(trans_pcie->aligned_ict_tbl_dma)); ++ trans_pcie->ict_tbl = NULL; ++ trans_pcie->ict_tbl_dma = 0; + } + } + + +-/* allocate dram shared table it is a PAGE_SIZE aligned ++/* ++ * allocate dram shared table, it is an aligned memory ++ * block of ICT_SIZE. + * also reset all data related to ICT table interrupt. + */ + int iwl_alloc_isr_ict(struct iwl_trans *trans) +@@ -1166,36 +1168,26 @@ int iwl_alloc_isr_ict(struct iwl_trans * + struct iwl_trans_pcie *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + +- /* allocate shrared data table */ +- trans_pcie->ict_tbl_vir = +- dma_alloc_coherent(bus(trans)->dev, +- (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, +- &trans_pcie->ict_tbl_dma, GFP_KERNEL); +- if (!trans_pcie->ict_tbl_vir) ++ trans_pcie->ict_tbl = ++ dma_alloc_coherent(bus(trans)->dev, ICT_SIZE, ++ &trans_pcie->ict_tbl_dma, ++ GFP_KERNEL); ++ if (!trans_pcie->ict_tbl) + return -ENOMEM; + +- /* align table to PAGE_SIZE boundary */ +- trans_pcie->aligned_ict_tbl_dma = +- ALIGN(trans_pcie->ict_tbl_dma, PAGE_SIZE); +- +- IWL_DEBUG_ISR(trans, "ict dma addr %Lx dma aligned %Lx diff %d\n", +- (unsigned long long)trans_pcie->ict_tbl_dma, +- (unsigned long long)trans_pcie->aligned_ict_tbl_dma, +- (int)(trans_pcie->aligned_ict_tbl_dma - +- trans_pcie->ict_tbl_dma)); +- +- trans_pcie->ict_tbl = trans_pcie->ict_tbl_vir + +- (trans_pcie->aligned_ict_tbl_dma - +- trans_pcie->ict_tbl_dma); +- +- IWL_DEBUG_ISR(trans, "ict vir addr %p vir aligned %p diff %d\n", +- trans_pcie->ict_tbl, trans_pcie->ict_tbl_vir, +- (int)(trans_pcie->aligned_ict_tbl_dma - +- trans_pcie->ict_tbl_dma)); ++ /* just an API sanity check ... it is guaranteed to be aligned */ ++ if (WARN_ON(trans_pcie->ict_tbl_dma & (ICT_SIZE - 1))) { ++ iwl_free_isr_ict(trans); ++ return -EINVAL; ++ } ++ ++ IWL_DEBUG_ISR(trans, "ict dma addr %Lx\n", ++ (unsigned long long)trans_pcie->ict_tbl_dma); ++ ++ IWL_DEBUG_ISR(trans, "ict vir addr %p\n", trans_pcie->ict_tbl); + + /* reset table and index to all 0 */ +- memset(trans_pcie->ict_tbl_vir, 0, +- (sizeof(u32) * ICT_COUNT) + PAGE_SIZE); ++ memset(trans_pcie->ict_tbl, 0, ICT_SIZE); + trans_pcie->ict_index = 0; + + /* add periodic RX interrupt */ +@@ -1213,23 +1205,20 @@ int iwl_reset_ict(struct iwl_trans *tran + struct iwl_trans_pcie *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + +- if (!trans_pcie->ict_tbl_vir) ++ if (!trans_pcie->ict_tbl) + return 0; + + spin_lock_irqsave(&trans->shrd->lock, flags); + iwl_disable_interrupts(trans); + +- memset(&trans_pcie->ict_tbl[0], 0, sizeof(u32) * ICT_COUNT); ++ memset(trans_pcie->ict_tbl, 0, ICT_SIZE); + +- val = trans_pcie->aligned_ict_tbl_dma >> PAGE_SHIFT; ++ val = trans_pcie->ict_tbl_dma >> ICT_SHIFT; + + val |= CSR_DRAM_INT_TBL_ENABLE; + val |= CSR_DRAM_INIT_TBL_WRAP_CHECK; + +- IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%X " +- "aligned dma address %Lx\n", +- val, +- (unsigned long long)trans_pcie->aligned_ict_tbl_dma); ++ IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%x\n", val); + + iwl_write32(bus(trans), CSR_DRAM_INT_TBL_REG, val); + trans_pcie->use_ict = true; diff --git a/queue-3.2/iwlagn-fix-tid-use-bug.patch b/queue-3.2/iwlagn-fix-tid-use-bug.patch new file mode 100644 index 00000000000..22102afb138 --- /dev/null +++ b/queue-3.2/iwlagn-fix-tid-use-bug.patch @@ -0,0 +1,48 @@ +From 9a215e40d70ae63762963ab3ccc7f31dd966dc6a Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 2 Dec 2011 12:22:54 -0800 +Subject: iwlagn: fix TID use bug + +From: Johannes Berg + +commit 9a215e40d70ae63762963ab3ccc7f31dd966dc6a upstream. + +The driver everywhere uses max TID count as 9, +which is wrong, it should be 8. + +I think the reason it uses 9 here is off-by-one +confusion by whoever wrote this. We do use the +value IWL_MAX_TID_COUNT for "not QoS/no TID" +but that is completely correct even if it is 8 +and not 9 since 0-7 are only valid. + +As a side effect, this fixes the following bug: + + Open BA session requested for 00:23:cd:16:8a:7e tid 8 + ------------[ cut here ]------------ + kernel BUG at drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h:350! + ... + +when you do +echo "tx start 8" > /sys/kernel/debug/ieee80211/*/*/*/*/agg_status + +Reported-by: Nikolay Martynov +Signed-off-by: Johannes Berg +Signed-off-by: Wey-Yi Guy +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/iwlwifi/iwl-commands.h ++++ b/drivers/net/wireless/iwlwifi/iwl-commands.h +@@ -809,7 +809,7 @@ struct iwl_qosparam_cmd { + #define IWLAGN_STATION_COUNT 16 + + #define IWL_INVALID_STATION 255 +-#define IWL_MAX_TID_COUNT 9 ++#define IWL_MAX_TID_COUNT 8 + + #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) + #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8) diff --git a/queue-3.2/ore-fix-breakage-when-misc_filesystems-is-not-set.patch b/queue-3.2/ore-fix-breakage-when-misc_filesystems-is-not-set.patch new file mode 100644 index 00000000000..39a504b55de --- /dev/null +++ b/queue-3.2/ore-fix-breakage-when-misc_filesystems-is-not-set.patch @@ -0,0 +1,81 @@ +From 831c2dc5f47c1dc79c32229d75065ada1dcc66e1 Mon Sep 17 00:00:00 2001 +From: Boaz Harrosh +Date: Tue, 29 Nov 2011 15:35:53 -0800 +Subject: ore: FIX breakage when MISC_FILESYSTEMS is not set + +From: Boaz Harrosh + +commit 831c2dc5f47c1dc79c32229d75065ada1dcc66e1 upstream. + +As Reported by Randy Dunlap + +When MISC_FILESYSTEMS is not enabled and NFS4.1 is: + +fs/built-in.o: In function `objio_alloc_io_state': +objio_osd.c:(.text+0xcb525): undefined reference to `ore_get_rw_state' +fs/built-in.o: In function `_write_done': +objio_osd.c:(.text+0xcb58d): undefined reference to `ore_check_io' +fs/built-in.o: In function `_read_done': +... + +When MISC_FILESYSTEMS, which is more of a GUI thing then anything else, +is not selected. exofs/Kconfig is never examined during Kconfig, +and it can not do it's magic stuff to automatically select everything +needed. + +We must split exofs/Kconfig in two. The ore one is always included. +And the exofs one is left in it's old place in the menu. + +Reported-by: Randy Dunlap +Signed-off-by: Boaz Harrosh +Signed-off-by: Greg Kroah-Hartman + +--- + fs/Kconfig | 2 ++ + fs/exofs/Kconfig | 11 ----------- + fs/exofs/Kconfig.ore | 12 ++++++++++++ + 3 files changed, 14 insertions(+), 11 deletions(-) + +--- a/fs/Kconfig ++++ b/fs/Kconfig +@@ -218,6 +218,8 @@ source "fs/exofs/Kconfig" + + endif # MISC_FILESYSTEMS + ++source "fs/exofs/Kconfig.ore" ++ + menuconfig NETWORK_FILESYSTEMS + bool "Network File Systems" + default y +--- a/fs/exofs/Kconfig ++++ b/fs/exofs/Kconfig +@@ -1,14 +1,3 @@ +-# Note ORE needs to "select ASYNC_XOR". So Not to force multiple selects +-# for every ORE user we do it like this. Any user should add itself here +-# at the "depends on EXOFS_FS || ..." with an ||. The dependencies are +-# selected here, and we default to "ON". So in effect it is like been +-# selected by any of the users. +-config ORE +- tristate +- depends on EXOFS_FS || PNFS_OBJLAYOUT +- select ASYNC_XOR +- default SCSI_OSD_ULD +- + config EXOFS_FS + tristate "exofs: OSD based file system support" + depends on SCSI_OSD_ULD +--- /dev/null ++++ b/fs/exofs/Kconfig.ore +@@ -0,0 +1,12 @@ ++# ORE - Objects Raid Engine (libore.ko) ++# ++# Note ORE needs to "select ASYNC_XOR". So Not to force multiple selects ++# for every ORE user we do it like this. Any user should add itself here ++# at the "depends on EXOFS_FS || ..." with an ||. The dependencies are ++# selected here, and we default to "ON". So in effect it is like been ++# selected by any of the users. ++config ORE ++ tristate ++ depends on EXOFS_FS || PNFS_OBJLAYOUT ++ select ASYNC_XOR ++ default SCSI_OSD_ULD diff --git a/queue-3.2/ore-fix-bug_on-too-few-sgs-when-reading.patch b/queue-3.2/ore-fix-bug_on-too-few-sgs-when-reading.patch new file mode 100644 index 00000000000..1f63f9e24e4 --- /dev/null +++ b/queue-3.2/ore-fix-bug_on-too-few-sgs-when-reading.patch @@ -0,0 +1,52 @@ +From 361aba569f55dd159b850489a3538253afbb3973 Mon Sep 17 00:00:00 2001 +From: Boaz Harrosh +Date: Wed, 28 Dec 2011 19:14:23 +0200 +Subject: ore: fix BUG_ON, too few sgs when reading + +From: Boaz Harrosh + +commit 361aba569f55dd159b850489a3538253afbb3973 upstream. + +When reading RAID5 files, in rare cases, we calculated too +few sg segments. There should be two extra for the beginning +and end partial units. + +Also "too few sg segments" should not be a BUG_ON there is +all the mechanics in place to handle it, as a short read. +So just return -ENOMEM and the rest of the code will gracefully +split the IO. + +Signed-off-by: Boaz Harrosh +Signed-off-by: Greg Kroah-Hartman + +--- + fs/exofs/ore.c | 2 +- + fs/exofs/ore_raid.c | 6 +++++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/fs/exofs/ore.c ++++ b/fs/exofs/ore.c +@@ -266,7 +266,7 @@ int ore_get_rw_state(struct ore_layout + + /* first/last seg is split */ + num_raid_units += layout->group_width; +- sgs_per_dev = div_u64(num_raid_units, data_devs); ++ sgs_per_dev = div_u64(num_raid_units, data_devs) + 2; + } else { + /* For Writes add parity pages array. */ + max_par_pages = num_raid_units * pages_in_unit * +--- a/fs/exofs/ore_raid.c ++++ b/fs/exofs/ore_raid.c +@@ -551,7 +551,11 @@ int _ore_add_parity_unit(struct ore_io_s + unsigned cur_len) + { + if (ios->reading) { +- BUG_ON(per_dev->cur_sg >= ios->sgs_per_dev); ++ if (per_dev->cur_sg >= ios->sgs_per_dev) { ++ ORE_DBGMSG("cur_sg(%d) >= sgs_per_dev(%d)\n" , ++ per_dev->cur_sg, ios->sgs_per_dev); ++ return -ENOMEM; ++ } + _ore_add_sg_seg(per_dev, cur_len, true); + } else { + struct __stripe_pages_2d *sp2d = ios->sp2d; diff --git a/queue-3.2/ore-fix-crash-in-case-of-an-io-error.patch b/queue-3.2/ore-fix-crash-in-case-of-an-io-error.patch new file mode 100644 index 00000000000..335e479b2dd --- /dev/null +++ b/queue-3.2/ore-fix-crash-in-case-of-an-io-error.patch @@ -0,0 +1,39 @@ +From ffefb8eaa367e8a5c14f779233d9da1fbc23d164 Mon Sep 17 00:00:00 2001 +From: Boaz Harrosh +Date: Tue, 27 Dec 2011 19:23:36 +0200 +Subject: ore: Fix crash in case of an IO error. + +From: Boaz Harrosh + +commit ffefb8eaa367e8a5c14f779233d9da1fbc23d164 upstream. + +The users of ore_check_io() expect the reported device +(In case of error) to be indexed relative to the passed-in +ore_components table, and not the logical dev index. + +This causes a crash inside objlayoutdriver in case of +an IO error. + +Signed-off-by: Boaz Harrosh +Signed-off-by: Greg Kroah-Hartman + +--- + fs/exofs/ore.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/exofs/ore.c ++++ b/fs/exofs/ore.c +@@ -445,10 +445,10 @@ int ore_check_io(struct ore_io_state *io + u64 residual = ios->reading ? + or->in.residual : or->out.residual; + u64 offset = (ios->offset + ios->length) - residual; +- struct ore_dev *od = ios->oc->ods[ +- per_dev->dev - ios->oc->first_dev]; ++ unsigned dev = per_dev->dev - ios->oc->first_dev; ++ struct ore_dev *od = ios->oc->ods[dev]; + +- on_dev_error(ios, od, per_dev->dev, osi.osd_err_pri, ++ on_dev_error(ios, od, dev, osi.osd_err_pri, + offset, residual); + } + if (osi.osd_err_pri >= acumulated_osd_err) { diff --git a/queue-3.2/ore-must-support-none-page-aligned-io.patch b/queue-3.2/ore-must-support-none-page-aligned-io.patch new file mode 100644 index 00000000000..c2c3cb197ee --- /dev/null +++ b/queue-3.2/ore-must-support-none-page-aligned-io.patch @@ -0,0 +1,161 @@ +From 724577ca355795b0a25c93ccbeee927871ca1a77 Mon Sep 17 00:00:00 2001 +From: Boaz Harrosh +Date: Wed, 28 Dec 2011 19:21:45 +0200 +Subject: ore: Must support none-PAGE-aligned IO + +From: Boaz Harrosh + +commit 724577ca355795b0a25c93ccbeee927871ca1a77 upstream. + +NFS might send us offsets that are not PAGE aligned. So +we must read in the reminder of the first/last pages, in cases +we need it for Parity calculations. + +We only add an sg segments to read the partial page. But +we don't mark it as read=true because it is a lock-for-write +page. + +TODO: In some cases (IO spans a single unit) we can just +adjust the raid_unit offset/length, but this is left for +later Kernels. + +Signed-off-by: Boaz Harrosh +Signed-off-by: Greg Kroah-Hartman + +--- + fs/exofs/ore_raid.c | 72 +++++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 60 insertions(+), 12 deletions(-) + +--- a/fs/exofs/ore_raid.c ++++ b/fs/exofs/ore_raid.c +@@ -328,8 +328,8 @@ static int _alloc_read_4_write(struct or + /* @si contains info of the to-be-inserted page. Update of @si should be + * maintained by caller. Specificaly si->dev, si->obj_offset, ... + */ +-static int _add_to_read_4_write(struct ore_io_state *ios, +- struct ore_striping_info *si, struct page *page) ++static int _add_to_r4w(struct ore_io_state *ios, struct ore_striping_info *si, ++ struct page *page, unsigned pg_len) + { + struct request_queue *q; + struct ore_per_dev_state *per_dev; +@@ -366,17 +366,60 @@ static int _add_to_read_4_write(struct o + _ore_add_sg_seg(per_dev, gap, true); + } + q = osd_request_queue(ore_comp_dev(read_ios->oc, per_dev->dev)); +- added_len = bio_add_pc_page(q, per_dev->bio, page, PAGE_SIZE, 0); +- if (unlikely(added_len != PAGE_SIZE)) { ++ added_len = bio_add_pc_page(q, per_dev->bio, page, pg_len, ++ si->obj_offset % PAGE_SIZE); ++ if (unlikely(added_len != pg_len)) { + ORE_DBGMSG("Failed to bio_add_pc_page bi_vcnt=%d\n", + per_dev->bio->bi_vcnt); + return -ENOMEM; + } + +- per_dev->length += PAGE_SIZE; ++ per_dev->length += pg_len; + return 0; + } + ++/* read the beginning of an unaligned first page */ ++static int _add_to_r4w_first_page(struct ore_io_state *ios, struct page *page) ++{ ++ struct ore_striping_info si; ++ unsigned pg_len; ++ ++ ore_calc_stripe_info(ios->layout, ios->offset, 0, &si); ++ ++ pg_len = si.obj_offset % PAGE_SIZE; ++ si.obj_offset -= pg_len; ++ ++ ORE_DBGMSG("offset=0x%llx len=0x%x index=0x%lx dev=%x\n", ++ _LLU(si.obj_offset), pg_len, page->index, si.dev); ++ ++ return _add_to_r4w(ios, &si, page, pg_len); ++} ++ ++/* read the end of an incomplete last page */ ++static int _add_to_r4w_last_page(struct ore_io_state *ios, u64 *offset) ++{ ++ struct ore_striping_info si; ++ struct page *page; ++ unsigned pg_len, p, c; ++ ++ ore_calc_stripe_info(ios->layout, *offset, 0, &si); ++ ++ p = si.unit_off / PAGE_SIZE; ++ c = _dev_order(ios->layout->group_width * ios->layout->mirrors_p1, ++ ios->layout->mirrors_p1, si.par_dev, si.dev); ++ page = ios->sp2d->_1p_stripes[p].pages[c]; ++ ++ pg_len = PAGE_SIZE - (si.unit_off % PAGE_SIZE); ++ *offset += pg_len; ++ ++ ORE_DBGMSG("p=%d, c=%d next-offset=0x%llx len=0x%x dev=%x par_dev=%d\n", ++ p, c, _LLU(*offset), pg_len, si.dev, si.par_dev); ++ ++ BUG_ON(!page); ++ ++ return _add_to_r4w(ios, &si, page, pg_len); ++} ++ + static void _mark_read4write_pages_uptodate(struct ore_io_state *ios, int ret) + { + struct bio_vec *bv; +@@ -444,9 +487,13 @@ static int _read_4_write(struct ore_io_s + struct page **pp = &_1ps->pages[c]; + bool uptodate; + +- if (*pp) ++ if (*pp) { ++ if (ios->offset % PAGE_SIZE) ++ /* Read the remainder of the page */ ++ _add_to_r4w_first_page(ios, *pp); + /* to-be-written pages start here */ + goto read_last_stripe; ++ } + + *pp = ios->r4w->get_page(ios->private, offset, + &uptodate); +@@ -454,7 +501,7 @@ static int _read_4_write(struct ore_io_s + return -ENOMEM; + + if (!uptodate) +- _add_to_read_4_write(ios, &read_si, *pp); ++ _add_to_r4w(ios, &read_si, *pp, PAGE_SIZE); + + /* Mark read-pages to be cache_released */ + _1ps->page_is_read[c] = true; +@@ -465,8 +512,11 @@ static int _read_4_write(struct ore_io_s + } + + read_last_stripe: +- offset = ios->offset + (ios->length + PAGE_SIZE - 1) / +- PAGE_SIZE * PAGE_SIZE; ++ offset = ios->offset + ios->length; ++ if (offset % PAGE_SIZE) ++ _add_to_r4w_last_page(ios, &offset); ++ /* offset will be aligned to next page */ ++ + last_stripe_end = div_u64(offset + bytes_in_stripe - 1, bytes_in_stripe) + * bytes_in_stripe; + if (offset == last_stripe_end) /* Optimize for the aligned case */ +@@ -503,7 +553,7 @@ read_last_stripe: + /* Mark read-pages to be cache_released */ + _1ps->page_is_read[c] = true; + if (!uptodate) +- _add_to_read_4_write(ios, &read_si, page); ++ _add_to_r4w(ios, &read_si, page, PAGE_SIZE); + } + + offset += PAGE_SIZE; +@@ -616,8 +666,6 @@ int _ore_post_alloc_raid_stuff(struct or + return -ENOMEM; + } + +- BUG_ON(ios->offset % PAGE_SIZE); +- + /* Round io down to last full strip */ + first_stripe = div_u64(ios->offset, stripe_size); + last_stripe = div_u64(ios->offset + ios->length, stripe_size); diff --git a/queue-3.2/perf-fix-parsing-of-__print_flags-in-tp_printk.patch b/queue-3.2/perf-fix-parsing-of-__print_flags-in-tp_printk.patch new file mode 100644 index 00000000000..50a71b89f95 --- /dev/null +++ b/queue-3.2/perf-fix-parsing-of-__print_flags-in-tp_printk.patch @@ -0,0 +1,35 @@ +From 49908a1b25d448d68fd26faca260e1850201575f Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Fri, 4 Nov 2011 16:32:25 -0400 +Subject: perf: Fix parsing of __print_flags() in TP_printk() + +From: Steven Rostedt + +commit 49908a1b25d448d68fd26faca260e1850201575f upstream. + +A update is made to the sched:sched_switch event that adds some +logic to the first parameter of the __print_flags() that shows the +state of tasks. This change cause perf to fail parsing the flags. + +A simple fix is needed to have the parser be able to process ops +within the argument. + +Reported-by: Andrew Vagin +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/util/trace-event-parse.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/tools/perf/util/trace-event-parse.c ++++ b/tools/perf/util/trace-event-parse.c +@@ -1582,6 +1582,8 @@ process_symbols(struct event *event, str + field = malloc_or_die(sizeof(*field)); + + type = process_arg(event, field, &token); ++ while (type == EVENT_OP) ++ type = process_op(event, field, &token); + if (test_type_token(type, token, EVENT_DELIM, ",")) + goto out_free; + diff --git a/queue-3.2/reiserfs-fix-quota-mount-option-parsing.patch b/queue-3.2/reiserfs-fix-quota-mount-option-parsing.patch new file mode 100644 index 00000000000..bdae507670d --- /dev/null +++ b/queue-3.2/reiserfs-fix-quota-mount-option-parsing.patch @@ -0,0 +1,32 @@ +From a06d789b424190e9f59da391681f908486db2554 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Wed, 21 Dec 2011 17:35:34 +0100 +Subject: reiserfs: Fix quota mount option parsing + +From: Jan Kara + +commit a06d789b424190e9f59da391681f908486db2554 upstream. + +When jqfmt mount option is not specified on remount, we mistakenly clear +s_jquota_fmt value stored in superblock. Fix the problem. + +CC: reiserfs-devel@vger.kernel.org +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/reiserfs/super.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/reiserfs/super.c ++++ b/fs/reiserfs/super.c +@@ -1164,7 +1164,8 @@ static void handle_quota_files(struct su + kfree(REISERFS_SB(s)->s_qf_names[i]); + REISERFS_SB(s)->s_qf_names[i] = qf_names[i]; + } +- REISERFS_SB(s)->s_jquota_fmt = *qfmt; ++ if (*qfmt) ++ REISERFS_SB(s)->s_jquota_fmt = *qfmt; + } + #endif + diff --git a/queue-3.2/reiserfs-force-inode-evictions-before-umount-to-avoid-crash.patch b/queue-3.2/reiserfs-force-inode-evictions-before-umount-to-avoid-crash.patch new file mode 100644 index 00000000000..dea6af2a823 --- /dev/null +++ b/queue-3.2/reiserfs-force-inode-evictions-before-umount-to-avoid-crash.patch @@ -0,0 +1,67 @@ +From a9e36da655e54545c3289b2a0700b5c443de0edd Mon Sep 17 00:00:00 2001 +From: Jeff Mahoney +Date: Wed, 21 Dec 2011 21:18:43 +0100 +Subject: reiserfs: Force inode evictions before umount to avoid crash + +From: Jeff Mahoney + +commit a9e36da655e54545c3289b2a0700b5c443de0edd upstream. + +This patch fixes a crash in reiserfs_delete_xattrs during umount. + +When shrink_dcache_for_umount clears the dcache from +generic_shutdown_super, delayed evictions are forced to disk. If an +evicted inode has extended attributes associated with it, it will +need to walk the xattr tree to locate and remove them. + +But since shrink_dcache_for_umount will BUG if it encounters active +dentries, the xattr tree must be released before it's called or it will +crash during every umount. + +This patch forces the evictions to occur before generic_shutdown_super +by calling shrink_dcache_sb first. The additional evictions caused +by the removal of each associated xattr file and dir will be automatically +handled as they're added to the LRU list. + +CC: reiserfs-devel@vger.kernel.org +Signed-off-by: Jeff Mahoney +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/reiserfs/super.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +--- a/fs/reiserfs/super.c ++++ b/fs/reiserfs/super.c +@@ -453,16 +453,20 @@ int remove_save_link(struct inode *inode + static void reiserfs_kill_sb(struct super_block *s) + { + if (REISERFS_SB(s)) { +- if (REISERFS_SB(s)->xattr_root) { +- d_invalidate(REISERFS_SB(s)->xattr_root); +- dput(REISERFS_SB(s)->xattr_root); +- REISERFS_SB(s)->xattr_root = NULL; +- } +- if (REISERFS_SB(s)->priv_root) { +- d_invalidate(REISERFS_SB(s)->priv_root); +- dput(REISERFS_SB(s)->priv_root); +- REISERFS_SB(s)->priv_root = NULL; +- } ++ /* ++ * Force any pending inode evictions to occur now. Any ++ * inodes to be removed that have extended attributes ++ * associated with them need to clean them up before ++ * we can release the extended attribute root dentries. ++ * shrink_dcache_for_umount will BUG if we don't release ++ * those before it's called so ->put_super is too late. ++ */ ++ shrink_dcache_sb(s); ++ ++ dput(REISERFS_SB(s)->xattr_root); ++ REISERFS_SB(s)->xattr_root = NULL; ++ dput(REISERFS_SB(s)->priv_root); ++ REISERFS_SB(s)->priv_root = NULL; + } + + kill_block_super(s); diff --git a/queue-3.2/series b/queue-3.2/series index 2d38c4fbe2a..6b29595230e 100644 --- a/queue-3.2/series +++ b/queue-3.2/series @@ -11,3 +11,24 @@ wl12xx-check-buffer-bound-when-processing-nvs-data.patch wl12xx-restore-testmode-abi.patch powerpc-time-handle-wrapping-of-decrementer.patch powerpc-fix-unpaired-probe_hcall_entry-and-probe_hcall_exit.patch +ib-qib-fix-a-possible-data-corruption-when-receiving.patch +ib-uverbs-protect-qp-multicast-list.patch +iwlagn-fix-tid-use-bug.patch +iwlagn-fix-remove-use-of-page_size.patch +perf-fix-parsing-of-__print_flags-in-tp_printk.patch +ore-fix-crash-in-case-of-an-io-error.patch +ore-fix-bug_on-too-few-sgs-when-reading.patch +ore-must-support-none-page-aligned-io.patch +ore-fix-breakage-when-misc_filesystems-is-not-set.patch +reiserfs-fix-quota-mount-option-parsing.patch +reiserfs-force-inode-evictions-before-umount-to-avoid-crash.patch +ext3-don-t-warn-from-writepage-when-readonly-inode-is-spotted-after-error.patch +drivers-hv-don-t-oops-when-you-cannot-init-vmbus.patch +drivers-hv-fix-a-bug-in-vmbus_driver_unregister.patch +usb-update-documentation-for-usbmon.patch +usbfs-fix-oops-related-to-user-namespace-conversion.patch +atmel_serial-fix-spinlock-lockup-in-rs485-code.patch +cgroup-fix-to-allow-mounting-a-hierarchy-by-name.patch +udf-fix-deadlock-when-converting-file-from-in-icb-one-to-normal-one.patch +drivers-usb-class-cdc-acm.c-clear-dangling-pointer.patch +usb-isight-fix-kernel-bug-when-loading-firmware.patch diff --git a/queue-3.2/udf-fix-deadlock-when-converting-file-from-in-icb-one-to-normal-one.patch b/queue-3.2/udf-fix-deadlock-when-converting-file-from-in-icb-one-to-normal-one.patch new file mode 100644 index 00000000000..2daecdab870 --- /dev/null +++ b/queue-3.2/udf-fix-deadlock-when-converting-file-from-in-icb-one-to-normal-one.patch @@ -0,0 +1,125 @@ +From d2eb8c359309ec45d6bf5b147303ab8e13be86ea Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Sat, 10 Dec 2011 02:30:48 +0100 +Subject: udf: Fix deadlock when converting file from in-ICB one to normal one + +From: Jan Kara + +commit d2eb8c359309ec45d6bf5b147303ab8e13be86ea upstream. + +During BKL removal in 2.6.38, conversion of files from in-ICB format to normal +format got broken. We call ->writepage with i_data_sem held but udf_get_block() +also acquires i_data_sem thus creating A-A deadlock. + +We fix the problem by dropping i_data_sem before calling ->writepage() which is +safe since i_mutex still protects us against any changes in the file. Also fix +pagelock - i_data_sem lock inversion in udf_expand_file_adinicb() by dropping +i_data_sem before calling find_or_create_page(). + +Reported-by: Matthias Matiak +Tested-by: Matthias Matiak +Reviewed-by: Namjae Jeon +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/udf/file.c | 6 +++--- + fs/udf/inode.c | 21 ++++++++++++++++++--- + 2 files changed, 21 insertions(+), 6 deletions(-) + +--- a/fs/udf/file.c ++++ b/fs/udf/file.c +@@ -125,7 +125,6 @@ static ssize_t udf_file_aio_write(struct + err = udf_expand_file_adinicb(inode); + if (err) { + udf_debug("udf_expand_adinicb: err=%d\n", err); +- up_write(&iinfo->i_data_sem); + return err; + } + } else { +@@ -133,9 +132,10 @@ static ssize_t udf_file_aio_write(struct + iinfo->i_lenAlloc = pos + count; + else + iinfo->i_lenAlloc = inode->i_size; ++ up_write(&iinfo->i_data_sem); + } +- } +- up_write(&iinfo->i_data_sem); ++ } else ++ up_write(&iinfo->i_data_sem); + + retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); + if (retval > 0) +--- a/fs/udf/inode.c ++++ b/fs/udf/inode.c +@@ -151,6 +151,12 @@ const struct address_space_operations ud + .bmap = udf_bmap, + }; + ++/* ++ * Expand file stored in ICB to a normal one-block-file ++ * ++ * This function requires i_data_sem for writing and releases it. ++ * This function requires i_mutex held ++ */ + int udf_expand_file_adinicb(struct inode *inode) + { + struct page *page; +@@ -169,9 +175,15 @@ int udf_expand_file_adinicb(struct inode + iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; + /* from now on we have normal address_space methods */ + inode->i_data.a_ops = &udf_aops; ++ up_write(&iinfo->i_data_sem); + mark_inode_dirty(inode); + return 0; + } ++ /* ++ * Release i_data_sem so that we can lock a page - page lock ranks ++ * above i_data_sem. i_mutex still protects us against file changes. ++ */ ++ up_write(&iinfo->i_data_sem); + + page = find_or_create_page(inode->i_mapping, 0, GFP_NOFS); + if (!page) +@@ -187,6 +199,7 @@ int udf_expand_file_adinicb(struct inode + SetPageUptodate(page); + kunmap(page); + } ++ down_write(&iinfo->i_data_sem); + memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0x00, + iinfo->i_lenAlloc); + iinfo->i_lenAlloc = 0; +@@ -196,17 +209,20 @@ int udf_expand_file_adinicb(struct inode + iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG; + /* from now on we have normal address_space methods */ + inode->i_data.a_ops = &udf_aops; ++ up_write(&iinfo->i_data_sem); + err = inode->i_data.a_ops->writepage(page, &udf_wbc); + if (err) { + /* Restore everything back so that we don't lose data... */ + lock_page(page); + kaddr = kmap(page); ++ down_write(&iinfo->i_data_sem); + memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr, + inode->i_size); + kunmap(page); + unlock_page(page); + iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; + inode->i_data.a_ops = &udf_adinicb_aops; ++ up_write(&iinfo->i_data_sem); + } + page_cache_release(page); + mark_inode_dirty(inode); +@@ -1111,10 +1127,9 @@ int udf_setsize(struct inode *inode, lof + if (bsize < + (udf_file_entry_alloc_offset(inode) + newsize)) { + err = udf_expand_file_adinicb(inode); +- if (err) { +- up_write(&iinfo->i_data_sem); ++ if (err) + return err; +- } ++ down_write(&iinfo->i_data_sem); + } else + iinfo->i_lenAlloc = newsize; + } diff --git a/queue-3.2/usb-isight-fix-kernel-bug-when-loading-firmware.patch b/queue-3.2/usb-isight-fix-kernel-bug-when-loading-firmware.patch new file mode 100644 index 00000000000..57ad593033c --- /dev/null +++ b/queue-3.2/usb-isight-fix-kernel-bug-when-loading-firmware.patch @@ -0,0 +1,45 @@ +From 59bf5cf94f0fa3b08fb1258b52649077b7d0914d Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Mon, 5 Dec 2011 14:02:59 -0800 +Subject: USB: isight: fix kernel bug when loading firmware + +From: Greg Kroah-Hartman + +commit 59bf5cf94f0fa3b08fb1258b52649077b7d0914d upstream. + +We were sending data on the stack when uploading firmware, which causes +some machines fits, and is not allowed. Fix this by using the buffer we +already had around for this very purpose. + +Reported-by: Wouter M. Koolen +Tested-by: Wouter M. Koolen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/isight_firmware.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/usb/misc/isight_firmware.c ++++ b/drivers/usb/misc/isight_firmware.c +@@ -55,8 +55,9 @@ static int isight_firmware_load(struct u + + ptr = firmware->data; + ++ buf[0] = 0x01; + if (usb_control_msg +- (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1, ++ (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1, + 300) != 1) { + printk(KERN_ERR + "Failed to initialise isight firmware loader\n"); +@@ -100,8 +101,9 @@ static int isight_firmware_load(struct u + } + } + ++ buf[0] = 0x00; + if (usb_control_msg +- (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1, ++ (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1, + 300) != 1) { + printk(KERN_ERR "isight firmware loading completion failed\n"); + ret = -ENODEV; diff --git a/queue-3.2/usb-update-documentation-for-usbmon.patch b/queue-3.2/usb-update-documentation-for-usbmon.patch new file mode 100644 index 00000000000..d7cdebbe610 --- /dev/null +++ b/queue-3.2/usb-update-documentation-for-usbmon.patch @@ -0,0 +1,52 @@ +From d8cae98cddd286e38db1724dda1b0e7b467f9237 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Wed, 4 Jan 2012 16:36:35 -0500 +Subject: USB: update documentation for usbmon + +From: Alan Stern + +commit d8cae98cddd286e38db1724dda1b0e7b467f9237 upstream. + +The documentation for usbmon is out of date; the usbfs "devices" file +now exists in /sys/kernel/debug/usb rather than /proc/bus/usb. This +patch (as1505) updates the documentation accordingly, and also +mentions that the necessary information can be found by running lsusb. + +Signed-off-by: Alan Stern +CC: Pete Zaitcev +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/usb/usbmon.txt | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/Documentation/usb/usbmon.txt ++++ b/Documentation/usb/usbmon.txt +@@ -47,10 +47,11 @@ This allows to filter away annoying devi + + 2. Find which bus connects to the desired device + +-Run "cat /proc/bus/usb/devices", and find the T-line which corresponds to +-the device. Usually you do it by looking for the vendor string. If you have +-many similar devices, unplug one and compare two /proc/bus/usb/devices outputs. +-The T-line will have a bus number. Example: ++Run "cat /sys/kernel/debug/usb/devices", and find the T-line which corresponds ++to the device. Usually you do it by looking for the vendor string. If you have ++many similar devices, unplug one and compare the two ++/sys/kernel/debug/usb/devices outputs. The T-line will have a bus number. ++Example: + + T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 + D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 +@@ -58,7 +59,10 @@ P: Vendor=0557 ProdID=2004 Rev= 1.00 + S: Manufacturer=ATEN + S: Product=UC100KM V2.00 + +-Bus=03 means it's bus 3. ++"Bus=03" means it's bus 3. Alternatively, you can look at the output from ++"lsusb" and get the bus number from the appropriate line. Example: ++ ++Bus 003 Device 002: ID 0557:2004 ATEN UC100KM V2.00 + + 3. Start 'cat' + diff --git a/queue-3.2/usbfs-fix-oops-related-to-user-namespace-conversion.patch b/queue-3.2/usbfs-fix-oops-related-to-user-namespace-conversion.patch new file mode 100644 index 00000000000..897b87caa60 --- /dev/null +++ b/queue-3.2/usbfs-fix-oops-related-to-user-namespace-conversion.patch @@ -0,0 +1,123 @@ +From 1b41c8321e495337e877ca02d0b9680bc4112eff Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 16 Dec 2011 11:26:30 -0800 +Subject: usbfs: Fix oops related to user namespace conversion. + +From: Sarah Sharp + +commit 1b41c8321e495337e877ca02d0b9680bc4112eff upstream. + +When running the Point Grey "flycap" program for their USB 3.0 camera +(which was running as a USB 2.0 device for some reason), I trigger this +oops whenever I try to open a video stream: + +Dec 15 16:48:34 puck kernel: [ 1798.715559] BUG: unable to handle kernel NULL pointer dereference at (null) +Dec 15 16:48:34 puck kernel: [ 1798.719153] IP: [] free_async+0x1e/0x70 +Dec 15 16:48:34 puck kernel: [ 1798.720991] PGD 6f833067 PUD 6fc56067 PMD 0 +Dec 15 16:48:34 puck kernel: [ 1798.722815] Oops: 0002 [#1] SMP +Dec 15 16:48:34 puck kernel: [ 1798.724627] CPU 0 +Dec 15 16:48:34 puck kernel: [ 1798.724636] Modules linked in: ecryptfs encrypted_keys sha1_generic trusted binfmt_misc sha256_generic aesni_intel cryptd aes_x86_64 aes_generic parport_pc dm_crypt ppdev joydev snd_hda_codec_hdmi snd_hda_codec_conexant arc4 iwlwifi snd_hda_intel snd_hda_codec snd_hwdep snd_pcm thinkpad_acpi mac80211 snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq snd_timer btusb uvcvideo snd_seq_device bluetooth videodev psmouse snd v4l2_compat_ioctl32 serio_raw tpm_tis cfg80211 tpm tpm_bios nvram soundcore snd_page_alloc lp parport i915 xhci_hcd ahci libahci drm_kms_helper drm sdhci_pci sdhci e1000e i2c_algo_bit video +Dec 15 16:48:34 puck kernel: [ 1798.734212] +Dec 15 16:48:34 puck kernel: [ 1798.736162] Pid: 2713, comm: FlyCap2 Not tainted 3.2.0-rc5+ #28 LENOVO 4286CTO/4286CTO +Dec 15 16:48:34 puck kernel: [ 1798.738148] RIP: 0010:[] [] free_async+0x1e/0x70 +Dec 15 16:48:34 puck kernel: [ 1798.740134] RSP: 0018:ffff88005715fd78 EFLAGS: 00010296 +Dec 15 16:48:34 puck kernel: [ 1798.742118] RAX: 00000000fffffff4 RBX: ffff88006fe8f900 RCX: 0000000000004118 +Dec 15 16:48:34 puck kernel: [ 1798.744116] RDX: 0000000001000000 RSI: 0000000000016390 RDI: 0000000000000000 +Dec 15 16:48:34 puck kernel: [ 1798.746087] RBP: ffff88005715fd88 R08: 0000000000000000 R09: ffffffff8146f22e +Dec 15 16:48:34 puck kernel: [ 1798.748018] R10: ffff88006e520ac0 R11: 0000000000000001 R12: ffff88005715fe28 +Dec 15 16:48:34 puck kernel: [ 1798.749916] R13: ffff88005d31df00 R14: ffff88006fe8f900 R15: 00007f688c995cb8 +Dec 15 16:48:34 puck kernel: [ 1798.751785] FS: 00007f68a366da40(0000) GS:ffff880100200000(0000) knlGS:0000000000000000 +Dec 15 16:48:34 puck kernel: [ 1798.753659] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +Dec 15 16:48:34 puck kernel: [ 1798.755509] CR2: 0000000000000000 CR3: 00000000706bb000 CR4: 00000000000406f0 +Dec 15 16:48:34 puck kernel: [ 1798.757334] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +Dec 15 16:48:34 puck kernel: [ 1798.759124] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +Dec 15 16:48:34 puck kernel: [ 1798.760871] Process FlyCap2 (pid: 2713, threadinfo ffff88005715e000, task ffff88006c675b80) +Dec 15 16:48:34 puck kernel: [ 1798.762605] Stack: +Dec 15 16:48:34 puck kernel: [ 1798.764297] ffff88005715fe28 0000000000000000 ffff88005715fe08 ffffffff81479058 +Dec 15 16:48:34 puck kernel: [ 1798.766020] 0000000000000000 ffffea0000004000 ffff880000004118 0000000000000000 +Dec 15 16:48:34 puck kernel: [ 1798.767750] ffff880000000001 ffff88006e520ac0 fffffff46fd81180 0000000000000000 +Dec 15 16:48:34 puck kernel: [ 1798.769472] Call Trace: +Dec 15 16:48:34 puck kernel: [ 1798.771147] [] proc_do_submiturb+0x778/0xa00 +Dec 15 16:48:34 puck kernel: [ 1798.772798] [] usbdev_do_ioctl+0x24d/0x1200 +Dec 15 16:48:34 puck kernel: [ 1798.774410] [] usbdev_ioctl+0xe/0x20 +Dec 15 16:48:34 puck kernel: [ 1798.775975] [] do_vfs_ioctl+0x99/0x600 +Dec 15 16:48:34 puck kernel: [ 1798.777534] [] sys_ioctl+0x91/0xa0 +Dec 15 16:48:34 puck kernel: [ 1798.779088] [] system_call_fastpath+0x16/0x1b +ec 15 16:48:34 puck kernel: [ 1798.780634] Code: 51 ff ff ff e9 29 ff ff ff 0f 1f 40 00 55 48 89 e5 53 48 83 ec 08 66 66 66 66 90 48 89 fb 48 8b 7f 18 e8 a6 ea c0 ff 4 +8 8b 7b 20 ff 0f 0f 94 c0 84 c0 74 05 e8 d3 99 c1 ff 48 8b 43 40 48 8b +Dec 15 16:48:34 puck kernel: [ 1798.783970] RIP [] free_async+0x1e/0x70 +Dec 15 16:48:34 puck kernel: [ 1798.785630] RSP +Dec 15 16:48:34 puck kernel: [ 1798.787274] CR2: 0000000000000000 +Dec 15 16:48:34 puck kernel: [ 1798.794728] ---[ end trace 52894d3355f88d19 ]--- + +markup_oops.pl says the oops is in put_cred: + + ffffffff81478401: 48 89 e5 mov %rsp,%rbp + ffffffff81478404: 53 push %rbx + ffffffff81478405: 48 83 ec 08 sub $0x8,%rsp + ffffffff81478409: e8 f2 c0 1a 00 callq ffffffff81624500 + ffffffff8147840e: 48 89 fb mov %rdi,%rbx | %ebx => ffff88006fe8f900 + put_pid(as->pid); + ffffffff81478411: 48 8b 7f 18 mov 0x18(%rdi),%rdi + ffffffff81478415: e8 a6 ea c0 ff callq ffffffff81086ec0 + put_cred(as->cred); + ffffffff8147841a: 48 8b 7b 20 mov 0x20(%rbx),%rdi | %edi => 0 %ebx = ffff88006fe8f900 + */ + static inline int atomic_dec_and_test(atomic_t *v) + { + unsigned char c; + + asm volatile(LOCK_PREFIX "decl %0; sete %1" +*ffffffff8147841e: f0 ff 0f lock decl (%rdi) | %edi = 0 <--- faulting instruction + ffffffff81478421: 0f 94 c0 sete %al + static inline void put_cred(const struct cred *_cred) + { + struct cred *cred = (struct cred *) _cred; + + validate_creds(cred); + if (atomic_dec_and_test(&(cred)->usage)) + ffffffff81478424: 84 c0 test %al,%al + ffffffff81478426: 74 05 je ffffffff8147842d + __put_cred(cred); + ffffffff81478428: e8 d3 99 c1 ff callq ffffffff81091e00 <__put_cred> + kfree(as->urb->transfer_buffer); + ffffffff8147842d: 48 8b 43 40 mov 0x40(%rbx),%rax + ffffffff81478431: 48 8b 78 68 mov 0x68(%rax),%rdi + ffffffff81478435: e8 a6 e1 ce ff callq ffffffff811665e0 + kfree(as->urb->setup_packet); + ffffffff8147843a: 48 8b 43 40 mov 0x40(%rbx),%rax + ffffffff8147843e: 48 8b b8 90 00 00 00 mov 0x90(%rax),%rdi + ffffffff81478445: e8 96 e1 ce ff callq ffffffff811665e0 + usb_free_urb(as->urb); + ffffffff8147844a: 48 8b 7b 40 mov 0x40(%rbx),%rdi + ffffffff8147844e: e8 0d 6b ff ff callq ffffffff8146ef60 + +This bug seems to have been introduced by commit +d178bc3a708f39cbfefc3fab37032d3f2511b4ec "user namespace: usb: make usb +urbs user namespace aware (v2)" + +I'm not sure if this is right fix, but it does stop the oops. + +Unfortunately, the Point Grey software still refuses to work, but it's a +closed source app, so I can't fix it. + +Signed-off-by: Sarah Sharp +Acked-by: Serge Hallyn +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/devio.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -249,7 +249,8 @@ static struct async *alloc_async(unsigne + static void free_async(struct async *as) + { + put_pid(as->pid); +- put_cred(as->cred); ++ if (as->cred) ++ put_cred(as->cred); + kfree(as->urb->transfer_buffer); + kfree(as->urb->setup_packet); + usb_free_urb(as->urb); -- 2.47.3