From 19a9485d59ce20ccd13be97b68d2b5cac59bcabd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 25 Mar 2012 19:47:42 +0200 Subject: [PATCH] --- yaml --- r: 307002 b: refs/heads/master c: 23c18c71da801fb7ce11acc3041e4f10a1bb5cb0 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/i915/i915_gem.c | 39 ++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index e8702e187396..db2ef582e9e3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f56f821feb7b36223f309e0ec05986bb137ce418 +refs/heads/master: 23c18c71da801fb7ce11acc3041e4f10a1bb5cb0 diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 6dc832902f53..c964dfbdb577 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -313,6 +313,28 @@ shmem_pread_fast(struct page *page, int shmem_page_offset, int page_length, return ret; } +static void +shmem_clflush_swizzled_range(char *addr, unsigned long length, + bool swizzled) +{ + if (swizzled) { + unsigned long start = (unsigned long) addr; + unsigned long end = (unsigned long) addr + length; + + /* For swizzling simply ensure that we always flush both + * channels. Lame, but simple and it works. Swizzled + * pwrite/pread is far from a hotpath - current userspace + * doesn't use it at all. */ + start = round_down(start, 128); + end = round_up(end, 128); + + drm_clflush_virt_range((void *)start, end - start); + } else { + drm_clflush_virt_range(addr, length); + } + +} + /* Only difference to the fast-path function is that this can handle bit17 * and uses non-atomic copy and kmap functions. */ static int @@ -325,8 +347,9 @@ shmem_pread_slow(struct page *page, int shmem_page_offset, int page_length, vaddr = kmap(page); if (needs_clflush) - drm_clflush_virt_range(vaddr + shmem_page_offset, - page_length); + shmem_clflush_swizzled_range(vaddr + shmem_page_offset, + page_length, + page_do_bit17_swizzling); if (page_do_bit17_swizzling) ret = __copy_to_user_swizzled(user_data, @@ -637,9 +660,10 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length, int ret; vaddr = kmap(page); - if (needs_clflush_before) - drm_clflush_virt_range(vaddr + shmem_page_offset, - page_length); + if (needs_clflush_before || page_do_bit17_swizzling) + shmem_clflush_swizzled_range(vaddr + shmem_page_offset, + page_length, + page_do_bit17_swizzling); if (page_do_bit17_swizzling) ret = __copy_from_user_swizzled(vaddr, shmem_page_offset, user_data, @@ -649,8 +673,9 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length, user_data, page_length); if (needs_clflush_after) - drm_clflush_virt_range(vaddr + shmem_page_offset, - page_length); + shmem_clflush_swizzled_range(vaddr + shmem_page_offset, + page_length, + page_do_bit17_swizzling); kunmap(page); return ret;