Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/external/bsd/drm2 Rework ttm tt swapin/swapout logic.



details:   https://anonhg.NetBSD.org/src/rev/1d83ed349a7a
branches:  trunk
changeset: 814990:1d83ed349a7a
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Apr 24 04:26:12 2016 +0000

description:
Rework ttm tt swapin/swapout logic.

Rather than handling `swapping in/out' here, per se, we let uvm do
that, we interpret `swap out' as `deactivate pages', and we add
generic ttm operations to wire and unwire pages, for the ttm_tt
driver to use.

This fixes certain graphics buffer eviction logic, which enables
nouveau to suspend/resume on one of my machines.  (The machine
doesn't resume overall for other reasons, but the nouveau device
suspends and resumes in isolation.)

XXX pullup to netbsd-7 after a couple weeks

diffstat:

 sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c        |   15 +-
 sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c         |   10 +
 sys/external/bsd/drm2/dist/drm/ttm/ttm_tt.c                |   83 ++++++--
 sys/external/bsd/drm2/dist/include/drm/ttm/ttm_bo_driver.h |   29 +++
 sys/external/bsd/drm2/include/drm/ttm/ttm_page_alloc.h     |    3 +-
 sys/external/bsd/drm2/ttm/ttm_bus_dma.c                    |  110 ++++++++++--
 6 files changed, 206 insertions(+), 44 deletions(-)

diffs (truncated from 433 to 300 lines):

diff -r ef2755cb4e46 -r 1d83ed349a7a sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c
--- a/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c       Sun Apr 24 00:05:28 2016 +0000
+++ b/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c       Sun Apr 24 04:26:12 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nouveau_bo.c,v 1.6 2015/10/29 08:08:52 mrg Exp $       */
+/*     $NetBSD: nouveau_bo.c,v 1.7 2016/04/24 04:26:12 riastradh Exp $ */
 
 /*
  * Copyright 2007 Dave Airlied
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_bo.c,v 1.6 2015/10/29 08:08:52 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_bo.c,v 1.7 2016/04/24 04:26:12 riastradh Exp $");
 
 #include <core/engine.h>
 #include <linux/swiotlb.h>
@@ -1524,6 +1524,16 @@
 #endif
 }
 
+#ifdef __NetBSD__
+static void
+nouveau_ttm_tt_swapout(struct ttm_tt *ttm)
+{
+       struct ttm_dma_tt *ttm_dma = container_of(ttm, struct ttm_dma_tt, ttm);
+
+       ttm_bus_dma_swapout(ttm_dma);
+}
+#endif
+
 void
 nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence)
 {
@@ -1581,6 +1591,7 @@
        .ttm_tt_populate = &nouveau_ttm_tt_populate,
        .ttm_tt_unpopulate = &nouveau_ttm_tt_unpopulate,
 #ifdef __NetBSD__
+       .ttm_tt_swapout = &nouveau_ttm_tt_swapout,
        .ttm_uvm_ops = &nouveau_uvm_ops,
 #endif
        .invalidate_caches = nouveau_bo_invalidate_caches,
diff -r ef2755cb4e46 -r 1d83ed349a7a sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c
--- a/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c        Sun Apr 24 00:05:28 2016 +0000
+++ b/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c        Sun Apr 24 04:26:12 2016 +0000
@@ -716,6 +716,15 @@
 }
 
 #ifdef __NetBSD__
+static void radeon_ttm_tt_swapout(struct ttm_tt *ttm)
+{
+       struct radeon_ttm_tt *gtt = container_of(ttm, struct radeon_ttm_tt,
+           ttm.ttm);
+       struct ttm_dma_tt *ttm_dma = &gtt->ttm;
+
+       ttm_bus_dma_swapout(ttm_dma);
+}
+
 static int     radeon_ttm_fault(struct uvm_faultinfo *, vaddr_t,
                    struct vm_page **, int, int, vm_prot_t, int);
 
@@ -731,6 +740,7 @@
        .ttm_tt_populate = &radeon_ttm_tt_populate,
        .ttm_tt_unpopulate = &radeon_ttm_tt_unpopulate,
 #ifdef __NetBSD__
+       .ttm_tt_swapout = &radeon_ttm_tt_swapout,
        .ttm_uvm_ops = &radeon_uvm_ops,
 #endif
        .invalidate_caches = &radeon_invalidate_caches,
diff -r ef2755cb4e46 -r 1d83ed349a7a sys/external/bsd/drm2/dist/drm/ttm/ttm_tt.c
--- a/sys/external/bsd/drm2/dist/drm/ttm/ttm_tt.c       Sun Apr 24 00:05:28 2016 +0000
+++ b/sys/external/bsd/drm2/dist/drm/ttm/ttm_tt.c       Sun Apr 24 04:26:12 2016 +0000
@@ -349,15 +349,30 @@
 }
 EXPORT_SYMBOL(ttm_tt_bind);
 
-int ttm_tt_swapin(struct ttm_tt *ttm)
+#ifdef __NetBSD__
+/*
+ * ttm_tt_wire(ttm)
+ *
+ *     Wire the uvm pages of ttm and fill the ttm page array.  ttm
+ *     must be unpopulated or unbound, and must be marked swapped.
+ *     This does not change either state -- the caller is expected to
+ *     include it among other operations for such a state transition.
+ */
+int
+ttm_tt_wire(struct ttm_tt *ttm)
 {
-#ifdef __NetBSD__
        struct uvm_object *uobj = ttm->swap_storage;
        struct vm_page *page;
        unsigned i;
        int error;
 
+       KASSERTMSG((ttm->state == tt_unpopulated || ttm->state == tt_unbound),
+           "ttm_tt %p must be unpopulated or unbound for wiring,"
+           " but state=%d",
+           ttm, (int)ttm->state);
+       KASSERT(ISSET(ttm->page_flags, TTM_PAGE_FLAG_SWAPPED));
        KASSERT(uobj != NULL);
+
        error = uvm_obj_wirepages(uobj, 0, (ttm->num_pages << PAGE_SHIFT),
            &ttm->pglist);
        if (error)
@@ -375,7 +390,37 @@
 
        /* Success!  */
        return 0;
-#else
+}
+
+/*
+ * ttm_tt_unwire(ttm)
+ *
+ *     Nullify the ttm page array and unwire the uvm pages of ttm.
+ *     ttm must be unbound and must be marked swapped.  This does not
+ *     change either state -- the caller is expected to include it
+ *     among other operations for such a state transition.
+ */
+void
+ttm_tt_unwire(struct ttm_tt *ttm)
+{
+       struct uvm_object *uobj = ttm->swap_storage;
+       unsigned i;
+
+       KASSERTMSG((ttm->state == tt_unbound),
+           "ttm_tt %p must be unbound for unwiring, but state=%d",
+           ttm, (int)ttm->state);
+       KASSERT(!ISSET(ttm->page_flags, TTM_PAGE_FLAG_SWAPPED));
+       KASSERT(uobj != NULL);
+
+       uvm_obj_unwirepages(uobj, 0, (ttm->num_pages << PAGE_SHIFT));
+       for (i = 0; i < ttm->num_pages; i++)
+               ttm->pages[i] = NULL;
+}
+#endif
+
+#ifndef __NetBSD__
+int ttm_tt_swapin(struct ttm_tt *ttm)
+{
        struct address_space *swap_space;
        struct file *swap_storage;
        struct page *from_page;
@@ -410,35 +455,25 @@
        return 0;
 out_err:
        return ret;
+}
 #endif
-}
 
-#ifdef __NetBSD__
 int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
 {
-       struct uvm_object *uobj = ttm->swap_storage;
-       unsigned i;
+#ifdef __NetBSD__
 
-       KASSERT((ttm->state == tt_unbound) || (ttm->state == tt_unpopulated));
-       KASSERT(ttm->caching_state == tt_cached);
-       KASSERT(uobj != NULL);
-
-       /*
-        * XXX Dunno what this persistent swap storage business is all
-        * about, but I see nothing using it and it doesn't make sense.
-        */
+       KASSERTMSG((ttm->state == tt_unpopulated || ttm->state == tt_unbound),
+           "ttm_tt %p must be unpopulated or unbound for swapout,"
+           " but state=%d",
+           ttm, (int)ttm->state);
+       KASSERTMSG((ttm->caching_state == tt_cached),
+           "ttm_tt %p must be cached for swapout, but caching_state=%d",
+           ttm, (int)ttm->caching_state);
        KASSERT(persistent_swap_storage == NULL);
 
-       uvm_obj_unwirepages(uobj, 0, (ttm->num_pages << PAGE_SHIFT));
-       for (i = 0; i < ttm->num_pages; i++)
-               ttm->pages[i] = NULL;
-
-       /* Success!  */
+       ttm->bdev->driver->ttm_tt_swapout(ttm);
        return 0;
-}
 #else
-int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
-{
        struct address_space *swap_space;
        struct file *swap_storage;
        struct page *from_page;
@@ -489,8 +524,8 @@
                fput(swap_storage);
 
        return ret;
+#endif
 }
-#endif
 
 static void ttm_tt_clear_mapping(struct ttm_tt *ttm)
 {
diff -r ef2755cb4e46 -r 1d83ed349a7a sys/external/bsd/drm2/dist/include/drm/ttm/ttm_bo_driver.h
--- a/sys/external/bsd/drm2/dist/include/drm/ttm/ttm_bo_driver.h        Sun Apr 24 00:05:28 2016 +0000
+++ b/sys/external/bsd/drm2/dist/include/drm/ttm/ttm_bo_driver.h        Sun Apr 24 04:26:12 2016 +0000
@@ -368,6 +368,15 @@
        void (*ttm_tt_unpopulate)(struct ttm_tt *ttm);
 
        /**
+        * ttm_tt_swapout
+        *
+        * @ttm: The struct ttm_tt to contain the backing pages.
+        *
+        * Deactivate all backing pages, but don't free them
+        */
+       void (*ttm_tt_swapout)(struct ttm_tt *ttm);
+
+       /**
         * struct ttm_bo_driver member invalidate_caches
         *
         * @bdev: the buffer object device.
@@ -666,6 +675,25 @@
  */
 extern void ttm_tt_unbind(struct ttm_tt *ttm);
 
+#ifdef __NetBSD__
+/**
+ * ttm_tt_wire
+ *
+ * @ttm The struct ttm_tt.
+ *
+ * Wire the pages of a ttm_tt, allocating pages for it if necessary.
+ */
+extern int ttm_tt_wire(struct ttm_tt *ttm);
+
+/**
+ * ttm_tt_unwire
+ *
+ * @ttm The struct ttm_tt.
+ *
+ * Unwire the pages of a ttm_tt.
+ */
+extern void ttm_tt_unwire(struct ttm_tt *ttm);
+#else
 /**
  * ttm_tt_swapin:
  *
@@ -674,6 +702,7 @@
  * Swap in a previously swap out ttm_tt.
  */
 extern int ttm_tt_swapin(struct ttm_tt *ttm);
+#endif
 
 /**
  * ttm_tt_cache_flush:
diff -r ef2755cb4e46 -r 1d83ed349a7a sys/external/bsd/drm2/include/drm/ttm/ttm_page_alloc.h
--- a/sys/external/bsd/drm2/include/drm/ttm/ttm_page_alloc.h    Sun Apr 24 00:05:28 2016 +0000
+++ b/sys/external/bsd/drm2/include/drm/ttm/ttm_page_alloc.h    Sun Apr 24 04:26:12 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ttm_page_alloc.h,v 1.1 2014/07/16 20:59:58 riastradh Exp $     */
+/*     $NetBSD: ttm_page_alloc.h,v 1.2 2016/04/24 04:26:12 riastradh Exp $     */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -37,6 +37,7 @@
 
 int    ttm_bus_dma_populate(struct ttm_dma_tt *);
 void   ttm_bus_dma_unpopulate(struct ttm_dma_tt *);
+void   ttm_bus_dma_swapout(struct ttm_dma_tt *);
 
 static inline int
 ttm_page_alloc_init(struct ttm_mem_global *glob __unused,
diff -r ef2755cb4e46 -r 1d83ed349a7a sys/external/bsd/drm2/ttm/ttm_bus_dma.c
--- a/sys/external/bsd/drm2/ttm/ttm_bus_dma.c   Sun Apr 24 00:05:28 2016 +0000
+++ b/sys/external/bsd/drm2/ttm/ttm_bus_dma.c   Sun Apr 24 04:26:12 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ttm_bus_dma.c,v 1.1 2014/07/16 20:59:58 riastradh Exp $        */
+/*     $NetBSD: ttm_bus_dma.c,v 1.2 2016/04/24 04:26:12 riastradh Exp $        */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ttm_bus_dma.c,v 1.1 2014/07/16 20:59:58 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ttm_bus_dma.c,v 1.2 2016/04/24 04:26:12 riastradh Exp $");
 
 #include <sys/bus.h>
 
@@ -40,17 +40,41 @@
 #include <ttm/ttm_bo_driver.h>
 #include <ttm/ttm_page_alloc.h>
 
+/*
+ * ttm_bus_dma_populate(ttm_dma)
+ *
+ *     If ttm_dma is not already populated, wire its pages and load
+ *     its DMA map.  The wiring and loading are stable as long as the
+ *     associated bo is reserved.
+ *



Home | Main Index | Thread Index | Old Index