Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm, agpgart: Use pgprot_writecombine for AGP maps and make the MTRR optional

I'm not sure I understand the intent of the previous behavior. mmap
on /dev/agpgart and DRM_AGP maps had no cache flags set, so they
would be fully cacheable. But the DRM code (most of the time) would
add a write-combining MTRR that would change the effective memory
type to WC.

The new behavior just requests WC explicitly for all AGP maps.

If there is any code out there that expects cacheable access to the
AGP aperture (because the drm driver doesn't request an MTRR or
because it's using /dev/agpgart directly), then it will now end up
with a UC or WC mapping, depending on the architecture and PAT
availability. But cacheable access to the aperture seems like it's
asking for trouble, because, AIUI, the aperture is an alias of RAM.

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Andy Lutomirski and committed by
Dave Airlie
f435046d ff47eaf2

+15 -22
+5 -3
drivers/char/agp/frontend.c
··· 603 603 vma->vm_ops = kerninfo.vm_ops; 604 604 } else if (io_remap_pfn_range(vma, vma->vm_start, 605 605 (kerninfo.aper_base + offset) >> PAGE_SHIFT, 606 - size, vma->vm_page_prot)) { 606 + size, 607 + pgprot_writecombine(vma->vm_page_prot))) { 607 608 goto out_again; 608 609 } 609 610 mutex_unlock(&(agp_fe.agp_mutex)); ··· 619 618 if (kerninfo.vm_ops) { 620 619 vma->vm_ops = kerninfo.vm_ops; 621 620 } else if (io_remap_pfn_range(vma, vma->vm_start, 622 - kerninfo.aper_base >> PAGE_SHIFT, 623 - size, vma->vm_page_prot)) { 621 + kerninfo.aper_base >> PAGE_SHIFT, 622 + size, 623 + pgprot_writecombine(vma->vm_page_prot))) { 624 624 goto out_again; 625 625 } 626 626 mutex_unlock(&(agp_fe.agp_mutex));
+4 -4
drivers/gpu/drm/drm_pci.c
··· 278 278 } 279 279 if (drm_core_has_MTRR(dev)) { 280 280 if (dev->agp) 281 - dev->agp->agp_mtrr = 282 - mtrr_add(dev->agp->agp_info.aper_base, 283 - dev->agp->agp_info.aper_size * 284 - 1024 * 1024, MTRR_TYPE_WRCOMB, 1); 281 + dev->agp->agp_mtrr = arch_phys_wc_add( 282 + dev->agp->agp_info.aper_base, 283 + dev->agp->agp_info.aper_size * 284 + 1024 * 1024); 285 285 } 286 286 } 287 287 return 0;
+2 -8
drivers/gpu/drm/drm_stub.c
··· 451 451 452 452 drm_lastclose(dev); 453 453 454 - if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && 455 - dev->agp && dev->agp->agp_mtrr >= 0) { 456 - int retval; 457 - retval = mtrr_del(dev->agp->agp_mtrr, 458 - dev->agp->agp_info.aper_base, 459 - dev->agp->agp_info.aper_size * 1024 * 1024); 460 - DRM_DEBUG("mtrr_del=%d\n", retval); 461 - } 454 + if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && dev->agp) 455 + arch_phys_wc_del(dev->agp->agp_mtrr); 462 456 463 457 if (dev->driver->unload) 464 458 dev->driver->unload(dev);
+4 -7
drivers/gpu/drm/drm_vm.c
··· 49 49 pgprot_t tmp = vm_get_page_prot(vma->vm_flags); 50 50 51 51 #if defined(__i386__) || defined(__x86_64__) 52 - if (map->type != _DRM_AGP) { 53 - if (map->type == _DRM_FRAME_BUFFER || 54 - map->flags & _DRM_WRITE_COMBINING) 55 - tmp = pgprot_writecombine(tmp); 56 - else 57 - tmp = pgprot_noncached(tmp); 58 - } 52 + if (map->type == _DRM_REGISTERS && !(map->flags & _DRM_WRITE_COMBINING)) 53 + tmp = pgprot_noncached(tmp); 54 + else 55 + tmp = pgprot_writecombine(tmp); 59 56 #elif defined(__powerpc__) 60 57 pgprot_val(tmp) |= _PAGE_NO_CACHE; 61 58 if (map->type == _DRM_REGISTERS)