diff options
author | Francisco Jerez | 2010-01-12 18:49:43 +0100 |
---|---|---|
committer | Dave Airlie | 2010-02-01 11:15:37 +1000 |
commit | db78e27de7e29a6db6be7caf607cf803d84094aa (patch) | |
tree | c387de94b95e444205361bc31ce59acd29b10aee | |
parent | f28cf33945cc112f8ee835512b7440905dc29ad2 (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.c | 23 |
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, |