kernel: PAT work, test_and_set_bit()
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 25 Jun 2013 18:07:05 +0000 (20:07 +0200)
committerFran├žois Tigeot <ftigeot@wolfpond.org>
Tue, 30 Jul 2013 18:46:02 +0000 (20:46 +0200)
Partially based on work by
Aggelos Economopoulos <aoiko@cc.ece.ntua.gr>

sys/dev/drm2/drmP.h
sys/dev/drm2/drm_atomic.h
sys/dev/drm2/drm_gem.c
sys/dev/drm2/drm_vm.c
sys/dev/drm2/i915/i915_gem_execbuffer.c
sys/vm/device_pager.c

index c48f597..4d0cd80 100644 (file)
@@ -355,7 +355,7 @@ vm_page_t
 vm_phys_fictitious_to_vm_page(vm_paddr_t pa);
 
 int
-vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end);
+vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end, int pat_mode);
 
 
 #define DRM_ERROR(fmt, ...) \
index d6cc804..5736528 100644 (file)
@@ -45,12 +45,16 @@ typedef u_int32_t atomic_t;
 static __inline atomic_t
 test_and_set_bit(int b, volatile void *p)
 {
-       int s = splhigh();
-       unsigned int m = 1<<b;
-       unsigned int r = *(volatile int *)p & m;
-       *(volatile int *)p |= m;
-       splx(s);
-       return r;
+       unsigned int mask = 1 << b;
+       unsigned int v;
+
+       for (;;) {
+               v = *(volatile unsigned int *)p;
+               cpu_ccfence();
+               if (atomic_cmpset_int(p, v, v | mask))
+                       break;
+       }
+       return (v & mask);
 }
 
 static __inline void
index 509a733..bfd15a1 100644 (file)
@@ -106,6 +106,7 @@ drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj,
        obj->refcount = 1;
        obj->handle_count = 0;
        obj->size = size;
+       obj->vm_obj->pat_mode = PAT_WRITE_COMBINING;    /* XXX */
 
        return (0);
 }
index f10ce16..44720df 100644 (file)
@@ -120,19 +120,13 @@ drm_mmap(struct dev_mmap_args *ap)
        switch (type) {
        case _DRM_FRAME_BUFFER:
        case _DRM_AGP:
-#if 0
-               /* FIXME */
-               *memattr = VM_MEMATTR_WRITE_COMBINING;
-#endif
+               /* memattr set by type in map's object */
                /* FALLTHROUGH */
        case _DRM_REGISTERS:
                phys = map->offset + offset;
                break;
        case _DRM_SCATTER_GATHER:
-#if 0
-               /* FIXME */
-               *memattr = VM_MEMATTR_WRITE_COMBINING;
-#endif
+               /* memattr set by type in map's object */
                /* FALLTHROUGH */
        case _DRM_CONSISTENT:
        case _DRM_SHM:
@@ -186,7 +180,7 @@ vm_phys_fictitious_to_vm_page(vm_paddr_t pa)
         return (m);
 }
 
-static void page_init(vm_page_t m, vm_paddr_t paddr)
+static void page_init(vm_page_t m, vm_paddr_t paddr, int pat_mode)
 {
        bzero(m, sizeof(*m));
 
@@ -197,6 +191,7 @@ static void page_init(vm_page_t m, vm_paddr_t paddr)
         m->busy = 0;
         m->queue = PQ_NONE;
         m->object = NULL;
+       m->pat_mode = pat_mode;
 
         m->wire_count = 1;
         m->hold_count = 0;
@@ -204,7 +199,7 @@ static void page_init(vm_page_t m, vm_paddr_t paddr)
 }
 
 int
-vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end)
+vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end, int pat_mode)
 {
         struct vm_phys_fictitious_seg *seg;
         vm_page_t fp;
@@ -217,7 +212,7 @@ vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end)
                     M_WAITOK | M_ZERO);
 
         for (i = 0; i < page_count; i++) {
-                page_init(&fp[i], start + PAGE_SIZE * i);
+                page_init(&fp[i], start + PAGE_SIZE * i, pat_mode);
         }
         mtx_lock(&vm_phys_fictitious_reg_mtx);
         for (segind = 0; segind < VM_PHYS_FICTITIOUS_NSEGS; segind++) {
index 54ab7a4..937bd42 100644 (file)
@@ -380,7 +380,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
                char *reloc_page;
 
                /* We can't wait for rendering with pagefaults disabled */
-               if (obj->active && (curthread->td_pflags & TDP_NOFAULTING) != 0)
+               if (obj->active && (curthread->td_flags & TDF_NOFAULT))
                        return (-EFAULT);
                ret = i915_gem_object_set_to_gtt_domain(obj, 1);
                if (ret)
@@ -456,7 +456,9 @@ i915_gem_execbuffer_relocate(struct drm_device *dev,
                             struct list_head *objects)
 {
        struct drm_i915_gem_object *obj;
-       int ret, pflags;
+       thread_t td = curthread;
+       int ret;
+       int pflags;
 
        /* Try to move as many of the relocation targets off the active list
         * to avoid unnecessary fallbacks to the slow path, as we cannot wait
@@ -465,11 +467,9 @@ i915_gem_execbuffer_relocate(struct drm_device *dev,
        i915_gem_retire_requests(dev);
 
        ret = 0;
-#if 0
-       pflags = vm_fault_disable_pagefaults();
-else
-       kprintf("i915_gem_execbuffer_relocate: pagefault_disable\n");
-#endif
+       pflags = td->td_flags & TDF_NOFAULT;
+       atomic_set_int(&td->td_flags, TDF_NOFAULT);
+
        /* This is the fast path and we cannot handle a pagefault whilst
         * holding the device lock lest the user pass in the relocations
         * contained within a mmaped bo. For in such a case we, the page
@@ -482,11 +482,10 @@ else
                if (ret != 0)
                        break;
        }
-#if 0
-       vm_fault_enable_pagefaults(pflags);
-#else
-       kprintf("i915_gem_execbuffer_relocate: pagefault_enable\n");
-#endif
+
+       if ((pflags & TDF_NOFAULT) == 0)
+               atomic_clear_int(&td->td_flags, TDF_NOFAULT);
+
        return (ret);
 }
 
index cf1311b..57ea82a 100644 (file)
@@ -66,7 +66,7 @@ static TAILQ_HEAD(, vm_page) dev_freepages_list =
 static MALLOC_DEFINE(M_FICTITIOUS_PAGES, "device-mapped pages",
                "Device mapped pages");
 
-static vm_page_t dev_pager_getfake (vm_paddr_t);
+static vm_page_t dev_pager_getfake (vm_paddr_t, int);
 static void dev_pager_putfake (vm_page_t);
 
 struct pagerops devicepagerops = {
@@ -258,7 +258,7 @@ dev_pager_haspage(vm_object_t object, vm_pindex_t pindex)
  * The caller must hold dev_pager_mtx
  */
 static vm_page_t
-dev_pager_getfake(vm_paddr_t paddr)
+dev_pager_getfake(vm_paddr_t paddr, int pat_mode)
 {
        vm_page_t m;
 
@@ -274,6 +274,7 @@ dev_pager_getfake(vm_paddr_t paddr)
        m->wire_count = 1;
        m->hold_count = 0;
        m->phys_addr = paddr;
+       m->pat_mode = pat_mode;
 
        return (m);
 }
@@ -359,7 +360,7 @@ static int old_dev_pager_fault(vm_object_t object, vm_ooffset_t offset,
                 * Replace the passed in reqpage page with our own fake page
                 * and free up all the original pages.
                 */
-               page = dev_pager_getfake(paddr);
+               page = dev_pager_getfake(paddr, object->pat_mode);
                TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist,
                                  page, pageq);
                vm_object_hold(object);