drm/nouveau/fault: expose replayable fault buffer event class
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:46:37 +0000 (20:46 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 9 Nov 2022 00:44:27 +0000 (10:44 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
drivers/gpu/drm/nouveau/include/nvif/clb069.h
drivers/gpu/drm/nouveau/nouveau_svm.c
drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c
drivers/gpu/drm/nouveau/nvkm/subdev/fault/user.c

index eef5d02..d7689de 100644 (file)
@@ -8,5 +8,8 @@ struct nvif_clb069_v0 {
        __u32 put;
 };
 
-#define NVB069_V0_NTFY_FAULT                                                0x00
+union nvif_clb069_event_args {
+       struct nvif_clb069_event_vn {
+       } vn;
+};
 #endif
index 31a5b81..a74ba8d 100644 (file)
@@ -24,7 +24,7 @@
 #include "nouveau_chan.h"
 #include "nouveau_dmem.h"
 
-#include <nvif/notify.h>
+#include <nvif/event.h>
 #include <nvif/object.h>
 #include <nvif/vmm.h>
 
@@ -51,7 +51,8 @@ struct nouveau_svm {
                u32 putaddr;
                u32 get;
                u32 put;
-               struct nvif_notify notify;
+               struct nvif_event notify;
+               struct work_struct work;
 
                struct nouveau_svm_fault {
                        u64 inst;
@@ -711,13 +712,11 @@ out:
        return ret;
 }
 
-static int
-nouveau_svm_fault(struct nvif_notify *notify)
+static void
+nouveau_svm_fault(struct work_struct *work)
 {
-       struct nouveau_svm_fault_buffer *buffer =
-               container_of(notify, typeof(*buffer), notify);
-       struct nouveau_svm *svm =
-               container_of(buffer, typeof(*svm), buffer[buffer->id]);
+       struct nouveau_svm_fault_buffer *buffer = container_of(work, typeof(*buffer), work);
+       struct nouveau_svm *svm = container_of(buffer, typeof(*svm), buffer[buffer->id]);
        struct nvif_object *device = &svm->drm->client.device.object;
        struct nouveau_svmm *svmm;
        struct {
@@ -737,7 +736,7 @@ nouveau_svm_fault(struct nvif_notify *notify)
                buffer->put = nvif_rd32(device, buffer->putaddr);
                buffer->get = nvif_rd32(device, buffer->getaddr);
                if (buffer->get == buffer->put)
-                       return NVIF_NOTIFY_KEEP;
+                       return;
        }
        buffer->fault_nr = 0;
 
@@ -881,7 +880,15 @@ nouveau_svm_fault(struct nvif_notify *notify)
        /* Issue fault replay to the GPU. */
        if (replay)
                nouveau_svm_fault_replay(svm);
-       return NVIF_NOTIFY_KEEP;
+}
+
+static int
+nouveau_svm_event(struct nvif_event *event, void *argv, u32 argc)
+{
+       struct nouveau_svm_fault_buffer *buffer = container_of(event, typeof(*buffer), notify);
+
+       schedule_work(&buffer->work);
+       return NVIF_EVENT_KEEP;
 }
 
 static struct nouveau_pfnmap_args *
@@ -936,7 +943,9 @@ static void
 nouveau_svm_fault_buffer_fini(struct nouveau_svm *svm, int id)
 {
        struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
-       nvif_notify_put(&buffer->notify);
+
+       nvif_event_block(&buffer->notify);
+       flush_work(&buffer->work);
 }
 
 static int
@@ -944,10 +953,12 @@ nouveau_svm_fault_buffer_init(struct nouveau_svm *svm, int id)
 {
        struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
        struct nvif_object *device = &svm->drm->client.device.object;
+
        buffer->get = nvif_rd32(device, buffer->getaddr);
        buffer->put = nvif_rd32(device, buffer->putaddr);
        SVM_DBG(svm, "get %08x put %08x (init)", buffer->get, buffer->put);
-       return nvif_notify_get(&buffer->notify);
+
+       return nvif_event_allow(&buffer->notify);
 }
 
 static void
@@ -956,15 +967,18 @@ nouveau_svm_fault_buffer_dtor(struct nouveau_svm *svm, int id)
        struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
        int i;
 
+       if (!nvif_object_constructed(&buffer->object))
+               return;
+
+       nouveau_svm_fault_buffer_fini(svm, id);
+
        if (buffer->fault) {
                for (i = 0; buffer->fault[i] && i < buffer->entries; i++)
                        kfree(buffer->fault[i]);
                kvfree(buffer->fault);
        }
 
-       nouveau_svm_fault_buffer_fini(svm, id);
-
-       nvif_notify_dtor(&buffer->notify);
+       nvif_event_dtor(&buffer->notify);
        nvif_object_dtor(&buffer->object);
 }
 
@@ -990,10 +1004,10 @@ nouveau_svm_fault_buffer_ctor(struct nouveau_svm *svm, s32 oclass, int id)
        buffer->entries = args.entries;
        buffer->getaddr = args.get;
        buffer->putaddr = args.put;
+       INIT_WORK(&buffer->work, nouveau_svm_fault);
 
-       ret = nvif_notify_ctor(&buffer->object, "svmFault", nouveau_svm_fault,
-                              true, NVB069_V0_NTFY_FAULT, NULL, 0, 0,
-                              &buffer->notify);
+       ret = nvif_event_ctor(&buffer->object, "svmFault", id, nouveau_svm_event, true, NULL, 0,
+                             &buffer->notify);
        if (ret)
                return ret;
 
index 7dd722c..b53ac9a 100644 (file)
@@ -22,7 +22,6 @@
 #include "priv.h"
 
 #include <core/memory.h>
-#include <core/notify.h>
 
 static void
 nvkm_fault_ntfy_fini(struct nvkm_event *event, int type, int index)
@@ -38,23 +37,8 @@ nvkm_fault_ntfy_init(struct nvkm_event *event, int type, int index)
        fault->func->buffer.intr(fault->buffer[index], true);
 }
 
-static int
-nvkm_fault_ntfy_ctor(struct nvkm_object *object, void *argv, u32 argc,
-                    struct nvkm_notify *notify)
-{
-       struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
-       if (argc == 0) {
-               notify->size  = 0;
-               notify->types = 1;
-               notify->index = buffer->id;
-               return 0;
-       }
-       return -ENOSYS;
-}
-
 static const struct nvkm_event_func
 nvkm_fault_ntfy = {
-       .ctor = nvkm_fault_ntfy_ctor,
        .init = nvkm_fault_ntfy_init,
        .fini = nvkm_fault_ntfy_fini,
 };
index ac835c9..c123e58 100644 (file)
 #include "priv.h"
 
 #include <core/memory.h>
+#include <core/event.h>
 #include <subdev/mmu.h>
 
 #include <nvif/clb069.h>
 #include <nvif/unpack.h>
 
 static int
+nvkm_ufault_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_uevent *uevent)
+{
+       struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
+       union nvif_clb069_event_args *args = argv;
+
+       if (!uevent)
+               return 0;
+       if (argc != sizeof(args->vn))
+               return -ENOSYS;
+
+       return nvkm_uevent_add(uevent, &buffer->fault->event, buffer->id,
+                              NVKM_FAULT_BUFFER_EVENT_PENDING, NULL);
+}
+
+static int
 nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc,
                enum nvkm_object_map *type, u64 *addr, u64 *size)
 {
@@ -40,18 +56,6 @@ nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc,
 }
 
 static int
-nvkm_ufault_ntfy(struct nvkm_object *object, u32 type,
-                struct nvkm_event **pevent)
-{
-       struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
-       if (type == NVB069_V0_NTFY_FAULT) {
-               *pevent = &buffer->fault->event;
-               return 0;
-       }
-       return -EINVAL;
-}
-
-static int
 nvkm_ufault_fini(struct nvkm_object *object, bool suspend)
 {
        struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
@@ -78,8 +82,8 @@ nvkm_ufault = {
        .dtor = nvkm_ufault_dtor,
        .init = nvkm_ufault_init,
        .fini = nvkm_ufault_fini,
-       .ntfy = nvkm_ufault_ntfy,
        .map = nvkm_ufault_map,
+       .uevent = nvkm_ufault_uevent,
 };
 
 int