From 20b6ae7dc1ffb0e723d960f39ddb0fc7c06770e8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 14 Jun 2013 14:28:44 -0700 Subject: [PATCH] 3.9-stable patches added patches: cciss-fix-broken-mutex-usage-in-ioctl.patch drm-i915-prefer-vbt-modes-for-svdo-lvds-over-edid.patch memcg-don-t-initialize-kmem-cache-destroying-work-for-root-caches.patch swap-avoid-read_swap_cache_async-race-to-deadlock-while-waiting-on-discard-i-o-completion.patch wl12xx-fix-minimum-required-firmware-version-for-wl127x-multirole.patch --- ...ciss-fix-broken-mutex-usage-in-ioctl.patch | 179 ++++++++++++++++++ ...er-vbt-modes-for-svdo-lvds-over-edid.patch | 70 +++++++ ...ache-destroying-work-for-root-caches.patch | 55 ++++++ queue-3.9/series | 5 + ...le-waiting-on-discard-i-o-completion.patch | 66 +++++++ ...irmware-version-for-wl127x-multirole.patch | 35 ++++ 6 files changed, 410 insertions(+) create mode 100644 queue-3.9/cciss-fix-broken-mutex-usage-in-ioctl.patch create mode 100644 queue-3.9/drm-i915-prefer-vbt-modes-for-svdo-lvds-over-edid.patch create mode 100644 queue-3.9/memcg-don-t-initialize-kmem-cache-destroying-work-for-root-caches.patch create mode 100644 queue-3.9/swap-avoid-read_swap_cache_async-race-to-deadlock-while-waiting-on-discard-i-o-completion.patch create mode 100644 queue-3.9/wl12xx-fix-minimum-required-firmware-version-for-wl127x-multirole.patch diff --git a/queue-3.9/cciss-fix-broken-mutex-usage-in-ioctl.patch b/queue-3.9/cciss-fix-broken-mutex-usage-in-ioctl.patch new file mode 100644 index 00000000000..142aa36fdbb --- /dev/null +++ b/queue-3.9/cciss-fix-broken-mutex-usage-in-ioctl.patch @@ -0,0 +1,179 @@ +From 03f47e888daf56c8e9046c674719a0bcc644eed5 Mon Sep 17 00:00:00 2001 +From: "Stephen M. Cameron" +Date: Wed, 12 Jun 2013 14:04:47 -0700 +Subject: cciss: fix broken mutex usage in ioctl + +From: "Stephen M. Cameron" + +commit 03f47e888daf56c8e9046c674719a0bcc644eed5 upstream. + +If a new logical drive is added and the CCISS_REGNEWD ioctl is invoked +(as is normal with the Array Configuration Utility) the process will +hang as below. It attempts to acquire the same mutex twice, once in +do_ioctl() and once in cciss_unlocked_open(). The BKL was recursive, +the mutex isn't. + + Linux version 3.10.0-rc2 (scameron@localhost.localdomain) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) ) #1 SMP Fri May 24 14:32:12 CDT 2013 + [...] + acu D 0000000000000001 0 3246 3191 0x00000080 + Call Trace: + schedule+0x29/0x70 + schedule_preempt_disabled+0xe/0x10 + __mutex_lock_slowpath+0x17b/0x220 + mutex_lock+0x2b/0x50 + cciss_unlocked_open+0x2f/0x110 [cciss] + __blkdev_get+0xd3/0x470 + blkdev_get+0x5c/0x1e0 + register_disk+0x182/0x1a0 + add_disk+0x17c/0x310 + cciss_add_disk+0x13a/0x170 [cciss] + cciss_update_drive_info+0x39b/0x480 [cciss] + rebuild_lun_table+0x258/0x370 [cciss] + cciss_ioctl+0x34f/0x470 [cciss] + do_ioctl+0x49/0x70 [cciss] + __blkdev_driver_ioctl+0x28/0x30 + blkdev_ioctl+0x200/0x7b0 + block_ioctl+0x3c/0x40 + do_vfs_ioctl+0x89/0x350 + SyS_ioctl+0xa1/0xb0 + system_call_fastpath+0x16/0x1b + +This mutex usage was added into the ioctl path when the big kernel lock +was removed. As it turns out, these paths are all thread safe anyway +(or can easily be made so) and we don't want ioctl() to be single +threaded in any case. + +Signed-off-by: Stephen M. Cameron +Cc: Jens Axboe +Cc: Mike Miller +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/cciss.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +--- a/drivers/block/cciss.c ++++ b/drivers/block/cciss.c +@@ -162,8 +162,6 @@ static irqreturn_t do_cciss_msix_intr(in + static int cciss_open(struct block_device *bdev, fmode_t mode); + static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode); + static int cciss_release(struct gendisk *disk, fmode_t mode); +-static int do_ioctl(struct block_device *bdev, fmode_t mode, +- unsigned int cmd, unsigned long arg); + static int cciss_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg); + static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); +@@ -229,7 +227,7 @@ static const struct block_device_operati + .owner = THIS_MODULE, + .open = cciss_unlocked_open, + .release = cciss_release, +- .ioctl = do_ioctl, ++ .ioctl = cciss_ioctl, + .getgeo = cciss_getgeo, + #ifdef CONFIG_COMPAT + .compat_ioctl = cciss_compat_ioctl, +@@ -1138,16 +1136,6 @@ static int cciss_release(struct gendisk + return 0; + } + +-static int do_ioctl(struct block_device *bdev, fmode_t mode, +- unsigned cmd, unsigned long arg) +-{ +- int ret; +- mutex_lock(&cciss_mutex); +- ret = cciss_ioctl(bdev, mode, cmd, arg); +- mutex_unlock(&cciss_mutex); +- return ret; +-} +- + #ifdef CONFIG_COMPAT + + static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, +@@ -1174,7 +1162,7 @@ static int cciss_compat_ioctl(struct blo + case CCISS_REGNEWD: + case CCISS_RESCANDISK: + case CCISS_GETLUNINFO: +- return do_ioctl(bdev, mode, cmd, arg); ++ return cciss_ioctl(bdev, mode, cmd, arg); + + case CCISS_PASSTHRU32: + return cciss_ioctl32_passthru(bdev, mode, cmd, arg); +@@ -1214,7 +1202,7 @@ static int cciss_ioctl32_passthru(struct + if (err) + return -EFAULT; + +- err = do_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p); ++ err = cciss_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p); + if (err) + return err; + err |= +@@ -1256,7 +1244,7 @@ static int cciss_ioctl32_big_passthru(st + if (err) + return -EFAULT; + +- err = do_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p); ++ err = cciss_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p); + if (err) + return err; + err |= +@@ -1306,11 +1294,14 @@ static int cciss_getpciinfo(ctlr_info_t + static int cciss_getintinfo(ctlr_info_t *h, void __user *argp) + { + cciss_coalint_struct intinfo; ++ unsigned long flags; + + if (!argp) + return -EINVAL; ++ spin_lock_irqsave(&h->lock, flags); + intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay); + intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount); ++ spin_unlock_irqrestore(&h->lock, flags); + if (copy_to_user + (argp, &intinfo, sizeof(cciss_coalint_struct))) + return -EFAULT; +@@ -1351,12 +1342,15 @@ static int cciss_setintinfo(ctlr_info_t + static int cciss_getnodename(ctlr_info_t *h, void __user *argp) + { + NodeName_type NodeName; ++ unsigned long flags; + int i; + + if (!argp) + return -EINVAL; ++ spin_lock_irqsave(&h->lock, flags); + for (i = 0; i < 16; i++) + NodeName[i] = readb(&h->cfgtable->ServerName[i]); ++ spin_unlock_irqrestore(&h->lock, flags); + if (copy_to_user(argp, NodeName, sizeof(NodeName_type))) + return -EFAULT; + return 0; +@@ -1393,10 +1387,13 @@ static int cciss_setnodename(ctlr_info_t + static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp) + { + Heartbeat_type heartbeat; ++ unsigned long flags; + + if (!argp) + return -EINVAL; ++ spin_lock_irqsave(&h->lock, flags); + heartbeat = readl(&h->cfgtable->HeartBeat); ++ spin_unlock_irqrestore(&h->lock, flags); + if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type))) + return -EFAULT; + return 0; +@@ -1405,10 +1402,13 @@ static int cciss_getheartbeat(ctlr_info_ + static int cciss_getbustypes(ctlr_info_t *h, void __user *argp) + { + BusTypes_type BusTypes; ++ unsigned long flags; + + if (!argp) + return -EINVAL; ++ spin_lock_irqsave(&h->lock, flags); + BusTypes = readl(&h->cfgtable->BusTypes); ++ spin_unlock_irqrestore(&h->lock, flags); + if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type))) + return -EFAULT; + return 0; diff --git a/queue-3.9/drm-i915-prefer-vbt-modes-for-svdo-lvds-over-edid.patch b/queue-3.9/drm-i915-prefer-vbt-modes-for-svdo-lvds-over-edid.patch new file mode 100644 index 00000000000..d61fda83f13 --- /dev/null +++ b/queue-3.9/drm-i915-prefer-vbt-modes-for-svdo-lvds-over-edid.patch @@ -0,0 +1,70 @@ +From c3456fb3e4712d0448592af3c5d644c9472cd3c1 Mon Sep 17 00:00:00 2001 +From: Daniel Vetter +Date: Mon, 10 Jun 2013 09:47:58 +0200 +Subject: drm/i915: prefer VBT modes for SVDO-LVDS over EDID + +From: Daniel Vetter + +commit c3456fb3e4712d0448592af3c5d644c9472cd3c1 upstream. + +In + +commit 53d3b4d7778daf15900867336c85d3f8dd70600c +Author: Egbert Eich +Date: Tue Jun 4 17:13:21 2013 +0200 + + drm/i915/sdvo: Use &intel_sdvo->ddc instead of intel_sdvo->i2c for DDC + +Egbert Eich fixed a long-standing bug where we simply used a +non-working i2c controller to read the EDID for SDVO-LVDS panels. +Unfortunately some machines seem to not be able to cope with the mode +provided in the EDID. Specifically they seem to not be able to cope +with a 4x pixel mutliplier instead of a 2x one, which seems to have +been worked around by slightly changing the panels native mode in the +VBT so that the dotclock is just barely above 50MHz. + +Since it took forever to notice the breakage it's fairly safe to +assume that at least for SDVO-LVDS panels the VBT contains fairly sane +data. So just switch around the order and use VBT modes first. + +v2: Also add EDID modes just in case, and spell Egbert correctly. + +v3: Elaborate a bit more about what's going on on Chris' machine. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65524 +Reported-and-tested-by: Chris Wilson +Cc: Egbert Eich +Signed-off-by: Daniel Vetter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_sdvo.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -1771,10 +1771,13 @@ static void intel_sdvo_get_lvds_modes(st + * arranged in priority order. + */ + intel_ddc_get_modes(connector, &intel_sdvo->ddc); +- if (list_empty(&connector->probed_modes) == false) +- goto end; + +- /* Fetch modes from VBT */ ++ /* ++ * Fetch modes from VBT. For SDVO prefer the VBT mode since some ++ * SDVO->LVDS transcoders can't cope with the EDID mode. Since ++ * drm_mode_probed_add adds the mode at the head of the list we add it ++ * last. ++ */ + if (dev_priv->sdvo_lvds_vbt_mode != NULL) { + newmode = drm_mode_duplicate(connector->dev, + dev_priv->sdvo_lvds_vbt_mode); +@@ -1786,7 +1789,6 @@ static void intel_sdvo_get_lvds_modes(st + } + } + +-end: + list_for_each_entry(newmode, &connector->probed_modes, head) { + if (newmode->type & DRM_MODE_TYPE_PREFERRED) { + intel_sdvo->sdvo_lvds_fixed_mode = diff --git a/queue-3.9/memcg-don-t-initialize-kmem-cache-destroying-work-for-root-caches.patch b/queue-3.9/memcg-don-t-initialize-kmem-cache-destroying-work-for-root-caches.patch new file mode 100644 index 00000000000..8ab06238b8b --- /dev/null +++ b/queue-3.9/memcg-don-t-initialize-kmem-cache-destroying-work-for-root-caches.patch @@ -0,0 +1,55 @@ +From f101a9464bfbda42730b54a66f926d75ed2cd31e Mon Sep 17 00:00:00 2001 +From: Andrey Vagin +Date: Wed, 12 Jun 2013 14:04:42 -0700 +Subject: memcg: don't initialize kmem-cache destroying work for root caches + +From: Andrey Vagin + +commit f101a9464bfbda42730b54a66f926d75ed2cd31e upstream. + +struct memcg_cache_params has a union. Different parts of this union +are used for root and non-root caches. A part with destroying work is +used only for non-root caches. + + BUG: unable to handle kernel paging request at 0000000fffffffe0 + IP: kmem_cache_alloc+0x41/0x1f0 + Modules linked in: netlink_diag af_packet_diag udp_diag tcp_diag inet_diag unix_diag ip6table_filter ip6_tables i2c_piix4 virtio_net virtio_balloon microcode i2c_core pcspkr floppy + CPU: 0 PID: 1929 Comm: lt-vzctl Tainted: G D 3.10.0-rc1+ #2 + Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 + RIP: kmem_cache_alloc+0x41/0x1f0 + Call Trace: + getname_flags.part.34+0x30/0x140 + getname+0x38/0x60 + do_sys_open+0xc5/0x1e0 + SyS_open+0x22/0x30 + system_call_fastpath+0x16/0x1b + Code: f4 53 48 83 ec 18 8b 05 8e 53 b7 00 4c 8b 4d 08 21 f0 a8 10 74 0d 4c 89 4d c0 e8 1b 76 4a 00 4c 8b 4d c0 e9 92 00 00 00 4d 89 f5 <4d> 8b 45 00 65 4c 03 04 25 48 cd 00 00 49 8b 50 08 4d 8b 38 49 + RIP [] kmem_cache_alloc+0x41/0x1f0 + +Signed-off-by: Andrey Vagin +Cc: Konstantin Khlebnikov +Cc: Glauber Costa +Cc: Johannes Weiner +Cc: Balbir Singh +Cc: KAMEZAWA Hiroyuki +Reviewed-by: Michal Hocko +Cc: Li Zefan +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/memcontrol.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -3033,8 +3033,6 @@ int memcg_update_cache_size(struct kmem_ + return -ENOMEM; + } + +- INIT_WORK(&s->memcg_params->destroy, +- kmem_cache_destroy_work_func); + s->memcg_params->is_root_cache = true; + + /* diff --git a/queue-3.9/series b/queue-3.9/series index edf83ab7cbf..ad17f78ab5f 100644 --- a/queue-3.9/series +++ b/queue-3.9/series @@ -17,3 +17,8 @@ ath9k-use-minstrel-rate-control-by-default.patch cpu-hotplug-provide-a-generic-helper-to-disable-enable-cpu-hotplug.patch reboot-rigrate-shutdown-reboot-to-boot-cpu.patch kmsg-honor-dmesg_restrict-sysctl-on-dev-kmsg.patch +cciss-fix-broken-mutex-usage-in-ioctl.patch +memcg-don-t-initialize-kmem-cache-destroying-work-for-root-caches.patch +wl12xx-fix-minimum-required-firmware-version-for-wl127x-multirole.patch +drm-i915-prefer-vbt-modes-for-svdo-lvds-over-edid.patch +swap-avoid-read_swap_cache_async-race-to-deadlock-while-waiting-on-discard-i-o-completion.patch diff --git a/queue-3.9/swap-avoid-read_swap_cache_async-race-to-deadlock-while-waiting-on-discard-i-o-completion.patch b/queue-3.9/swap-avoid-read_swap_cache_async-race-to-deadlock-while-waiting-on-discard-i-o-completion.patch new file mode 100644 index 00000000000..2285fda7434 --- /dev/null +++ b/queue-3.9/swap-avoid-read_swap_cache_async-race-to-deadlock-while-waiting-on-discard-i-o-completion.patch @@ -0,0 +1,66 @@ +From cbab0e4eec299e9059199ebe6daf48730be46d2b Mon Sep 17 00:00:00 2001 +From: Rafael Aquini +Date: Wed, 12 Jun 2013 14:04:49 -0700 +Subject: swap: avoid read_swap_cache_async() race to deadlock while waiting on discard I/O completion + +From: Rafael Aquini + +commit cbab0e4eec299e9059199ebe6daf48730be46d2b upstream. + +read_swap_cache_async() can race against get_swap_page(), and stumble +across a SWAP_HAS_CACHE entry in the swap map whose page wasn't brought +into the swapcache yet. + +This transient swap_map state is expected to be transitory, but the +actual placement of discard at scan_swap_map() inserts a wait for I/O +completion thus making the thread at read_swap_cache_async() to loop +around its -EEXIST case, while the other end at get_swap_page() is +scheduled away at scan_swap_map(). This can leave the system deadlocked +if the I/O completion happens to be waiting on the CPU waitqueue where +read_swap_cache_async() is busy looping and !CONFIG_PREEMPT. + +This patch introduces a cond_resched() call to make the aforementioned +read_swap_cache_async() busy loop condition to bail out when necessary, +thus avoiding the subtle race window. + +Signed-off-by: Rafael Aquini +Acked-by: Johannes Weiner +Acked-by: KOSAKI Motohiro +Acked-by: Hugh Dickins +Cc: Shaohua Li +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/swap_state.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +--- a/mm/swap_state.c ++++ b/mm/swap_state.c +@@ -336,8 +336,24 @@ struct page *read_swap_cache_async(swp_e + * Swap entry may have been freed since our caller observed it. + */ + err = swapcache_prepare(entry); +- if (err == -EEXIST) { /* seems racy */ ++ if (err == -EEXIST) { + radix_tree_preload_end(); ++ /* ++ * We might race against get_swap_page() and stumble ++ * across a SWAP_HAS_CACHE swap_map entry whose page ++ * has not been brought into the swapcache yet, while ++ * the other end is scheduled away waiting on discard ++ * I/O completion at scan_swap_map(). ++ * ++ * In order to avoid turning this transitory state ++ * into a permanent loop around this -EEXIST case ++ * if !CONFIG_PREEMPT and the I/O completion happens ++ * to be waiting on the CPU waitqueue where we are now ++ * busy looping, we just conditionally invoke the ++ * scheduler here, if there are some more important ++ * tasks to run. ++ */ ++ cond_resched(); + continue; + } + if (err) { /* swp entry is obsolete ? */ diff --git a/queue-3.9/wl12xx-fix-minimum-required-firmware-version-for-wl127x-multirole.patch b/queue-3.9/wl12xx-fix-minimum-required-firmware-version-for-wl127x-multirole.patch new file mode 100644 index 00000000000..0e1012f26ac --- /dev/null +++ b/queue-3.9/wl12xx-fix-minimum-required-firmware-version-for-wl127x-multirole.patch @@ -0,0 +1,35 @@ +From 60c28cf18f970e1c1bd40d615596eeab6efbd9d7 Mon Sep 17 00:00:00 2001 +From: Luciano Coelho +Date: Fri, 10 May 2013 10:19:38 +0300 +Subject: wl12xx: fix minimum required firmware version for wl127x multirole + +From: Luciano Coelho + +commit 60c28cf18f970e1c1bd40d615596eeab6efbd9d7 upstream. + +There was a typo in commit 8675f9 (wlcore/wl12xx/wl18xx: verify +multi-role and single-role fw versions), which was causing the +multirole firmware for wl127x (WiLink6) to be rejected. The actual +minimum version needed for wl127x multirole is 6.5.7.0.42. + +Reported-by: Levi Pearson +Reported-by: Michael Scott +Signed-off-by: Luciano Coelho +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ti/wl12xx/wl12xx.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h ++++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h +@@ -41,7 +41,7 @@ + #define WL127X_IFTYPE_MR_VER 5 + #define WL127X_MAJOR_MR_VER 7 + #define WL127X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE +-#define WL127X_MINOR_MR_VER 115 ++#define WL127X_MINOR_MR_VER 42 + + /* FW chip version for wl128x */ + #define WL128X_CHIP_VER 7 -- 2.47.3