aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Jerez2010-01-12 18:49:43 +0100
committerDave Airlie2010-02-01 11:15:37 +1000
commitdb78e27de7e29a6db6be7caf607cf803d84094aa (patch)
treec387de94b95e444205361bc31ce59acd29b10aee
parentf28cf33945cc112f8ee835512b7440905dc29ad2 (diff)
drm/ttm: Avoid conflicting reserve_memtype during ttm_tt_set_page_caching.
Fixes errors like: > reserve_ram_pages_type failed 0x15b7a000-0x15b7b000, track 0x8, req 0x10 when a BO is moved between WC and UC areas. Reported-by: Xavier Chantry <shiningxc@gmail.com> Signed-off-by: Francisco Jerez <currojerez@riseup.net> Acked-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 9c2b1cc5dba5..e2123af7775a 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -198,17 +198,26 @@ EXPORT_SYMBOL(ttm_tt_populate);
static inline int ttm_tt_set_page_caching(struct page *p,
enum ttm_caching_state c_state)
{
+ int ret = 0;
+
if (PageHighMem(p))
return 0;
- switch (c_state) {
- case tt_cached:
- return set_pages_wb(p, 1);
- case tt_wc:
- return set_memory_wc((unsigned long) page_address(p), 1);
- default:
- return set_pages_uc(p, 1);
+ if (get_page_memtype(p) != -1) {
+ /* p isn't in the default caching state, set it to
+ * writeback first to free its current memtype. */
+
+ ret = set_pages_wb(p, 1);
+ if (ret)
+ return ret;
}
+
+ if (c_state == tt_wc)
+ ret = set_memory_wc((unsigned long) page_address(p), 1);
+ else if (c_state == tt_uncached)
+ ret = set_pages_uc(p, 1);
+
+ return ret;
}
#else /* CONFIG_X86 */
static inline int ttm_tt_set_page_caching(struct page *p,