drm/nouveau/imem: support allocations not preserved across suspend
authorBen Skeggs <bskeggs@redhat.com>
Tue, 19 Sep 2023 21:55:57 +0000 (17:55 -0400)
committerLyude Paul <lyude@redhat.com>
Tue, 19 Sep 2023 22:21:49 +0000 (18:21 -0400)
Will initially be used to tag some large grctx allocations which don't
need to be saved, to speedup suspend/resume.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Acked-by: Danilo Krummrich <me@dakr.org>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230919220442.202488-3-lyude@redhat.com
drivers/gpu/drm/nouveau/include/nvkm/core/memory.h
drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
drivers/gpu/drm/nouveau/nvkm/core/memory.c
drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h

index d3b6a68ddda363882628fde4609d123aef56757d..fc0f38981391664cacfb107eeb733794b7a2f7ab 100644 (file)
@@ -12,6 +12,7 @@ struct nvkm_tags {
 };
 
 enum nvkm_memory_target {
+       NVKM_MEM_TARGET_INST_SR_LOST, /* instance memory - not preserved across suspend */
        NVKM_MEM_TARGET_INST, /* instance memory */
        NVKM_MEM_TARGET_VRAM, /* video memory */
        NVKM_MEM_TARGET_HOST, /* coherent system memory */
index fcdaefc99fe85a84f56aa157055e22a7e52a5fa9..92a36ddfc29ffe66a14a2648c9dc8a156440ecb2 100644 (file)
@@ -26,7 +26,7 @@ struct nvkm_instmem {
 
 u32 nvkm_instmem_rd32(struct nvkm_instmem *, u32 addr);
 void nvkm_instmem_wr32(struct nvkm_instmem *, u32 addr, u32 data);
-int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero,
+int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero, bool preserve,
                     struct nvkm_memory **);
 int nvkm_instobj_wrap(struct nvkm_device *, struct nvkm_memory *, struct nvkm_memory **);
 
index c69daac9bac7b0761e99815fc3dce7f51798e836..a705c2dfca809cf69eeca687ee4bf61cd6f90e37 100644 (file)
@@ -140,12 +140,23 @@ nvkm_memory_new(struct nvkm_device *device, enum nvkm_memory_target target,
 {
        struct nvkm_instmem *imem = device->imem;
        struct nvkm_memory *memory;
+       bool preserve = true;
        int ret;
 
-       if (unlikely(target != NVKM_MEM_TARGET_INST || !imem))
+       if (unlikely(!imem))
                return -ENOSYS;
 
-       ret = nvkm_instobj_new(imem, size, align, zero, &memory);
+       switch (target) {
+       case NVKM_MEM_TARGET_INST_SR_LOST:
+               preserve = false;
+               break;
+       case NVKM_MEM_TARGET_INST:
+               break;
+       default:
+               return -ENOSYS;
+       }
+
+       ret = nvkm_instobj_new(imem, size, align, zero, preserve, &memory);
        if (ret)
                return ret;
 
index e0e4f97be029472f4744eb9b162b5c4a10045b97..24886eabe8dc3f2eaa655f39decb9e12d2b03f3f 100644 (file)
@@ -94,15 +94,21 @@ nvkm_instobj_wrap(struct nvkm_device *device,
                  struct nvkm_memory *memory, struct nvkm_memory **pmemory)
 {
        struct nvkm_instmem *imem = device->imem;
+       int ret;
 
        if (!imem->func->memory_wrap)
                return -ENOSYS;
 
-       return imem->func->memory_wrap(imem, memory, pmemory);
+       ret = imem->func->memory_wrap(imem, memory, pmemory);
+       if (ret)
+               return ret;
+
+       container_of(*pmemory, struct nvkm_instobj, memory)->preserve = true;
+       return 0;
 }
 
 int
-nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
+nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, bool preserve,
                 struct nvkm_memory **pmemory)
 {
        struct nvkm_subdev *subdev = &imem->subdev;
@@ -130,6 +136,7 @@ nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
                nvkm_done(memory);
        }
 
+       container_of(memory, struct nvkm_instobj, memory)->preserve = preserve;
 done:
        if (ret)
                nvkm_memory_unref(&memory);
@@ -176,9 +183,11 @@ nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend)
 
        if (suspend) {
                list_for_each_entry(iobj, &imem->list, head) {
-                       int ret = nvkm_instobj_save(iobj);
-                       if (ret)
-                               return ret;
+                       if (iobj->preserve) {
+                               int ret = nvkm_instobj_save(iobj);
+                               if (ret)
+                                       return ret;
+                       }
                }
 
                nvkm_bar_bar2_fini(subdev->device);
index fe92986a388583f1ff3ce9ce4f51233738a8f961..390ca00ab5678b3bac845eb00f0dc56b5920c3a4 100644 (file)
@@ -25,6 +25,7 @@ void nvkm_instmem_boot(struct nvkm_instmem *);
 struct nvkm_instobj {
        struct nvkm_memory memory;
        struct list_head head;
+       bool preserve;
        u32 *suspend;
 };