On Thu, Jun 11, 2015 at 09:25:16AM +0100, Dave Gordon wrote:
On 10/06/15 15:58, Chris Wilson wrote:
As the clflush operates on cache lines, and we can flush any byte address, in order to flush all bytes given in the range we issue an extra clflush on the last byte to ensure the last cacheline is flushed. We can can the iteration to be over the actual cache lines to avoid this double clflush on the last byte.
Signed-off-by: Chris Wilson chris@chris-wilson.co.uk Cc: Imre Deak imre.deak@intel.com
drivers/gpu/drm/drm_cache.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c index 9a62d7a53553..6743ff7dccfa 100644 --- a/drivers/gpu/drm/drm_cache.c +++ b/drivers/gpu/drm/drm_cache.c @@ -130,11 +130,12 @@ drm_clflush_virt_range(void *addr, unsigned long length) { #if defined(CONFIG_X86) if (cpu_has_clflush) {
void *end = addr + length;const int size = boot_cpu_data.x86_clflush_size;
addr = (void *)(((unsigned long)addr) & -size);
Should this cast be to uintptr_t?
The kernel has a strict equivalence between sizeof(unsigned long) and sizeof(pointer). You will see unsigned long used universally to pass along pointers to functions and as closures.
Or intptr_t, as size has somewhat strangely been defined as signed? To complete the mix, x86_clflush_size is 'u16'! So maybe we should write
const size_t size = boot_cpu_data.x86_clflush_size;
void *end = addr + length;const size_t mask = ~(size - 1);
addr = (void *)(((uintptr_t)addr) & mask);
No. size_t has very poor definition inside the kernel - what does the maximum size of a userspace allocation have to do with kernel internals?
Let's keep userspace types in userspace, or else we end up with i915_gem_gtt.c. -Chris