From 7a1082e14fc28dcc9ed3baf3f5f29b62126c1d55 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 14 Jun 2013 14:03:03 -0700 Subject: [PATCH] 3.0-stable patches added patches: 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 --- ...er-vbt-modes-for-svdo-lvds-over-edid.patch | 70 +++++++++++++++++++ queue-3.0/series | 2 + ...le-waiting-on-discard-i-o-completion.patch | 66 +++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 queue-3.0/drm-i915-prefer-vbt-modes-for-svdo-lvds-over-edid.patch create mode 100644 queue-3.0/swap-avoid-read_swap_cache_async-race-to-deadlock-while-waiting-on-discard-i-o-completion.patch diff --git a/queue-3.0/drm-i915-prefer-vbt-modes-for-svdo-lvds-over-edid.patch b/queue-3.0/drm-i915-prefer-vbt-modes-for-svdo-lvds-over-edid.patch new file mode 100644 index 00000000000..8393c1196e6 --- /dev/null +++ b/queue-3.0/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 +@@ -1610,10 +1610,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); +@@ -1625,7 +1628,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.0/series b/queue-3.0/series index 8588fbd541b..5c37f5a2964 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -1,2 +1,4 @@ b43-stop-format-string-leaking-into-error-msgs.patch ath9k-disable-powersave-by-default.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.0/swap-avoid-read_swap_cache_async-race-to-deadlock-while-waiting-on-discard-i-o-completion.patch b/queue-3.0/swap-avoid-read_swap_cache_async-race-to-deadlock-while-waiting-on-discard-i-o-completion.patch new file mode 100644 index 00000000000..34c43a54e69 --- /dev/null +++ b/queue-3.0/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 +@@ -315,8 +315,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 ? */ -- 2.47.3