提交 b418ff88 编写于 作者: B Ben Skeggs

drm/nouveau/fault: expose replayable fault buffer event class

Signed-off-by: NBen Skeggs <bskeggs@redhat.com>
Reviewed-by: NLyude Paul <lyude@redhat.com>
上级 55520832
...@@ -8,5 +8,8 @@ struct nvif_clb069_v0 { ...@@ -8,5 +8,8 @@ struct nvif_clb069_v0 {
__u32 put; __u32 put;
}; };
#define NVB069_V0_NTFY_FAULT 0x00 union nvif_clb069_event_args {
struct nvif_clb069_event_vn {
} vn;
};
#endif #endif
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "nouveau_chan.h" #include "nouveau_chan.h"
#include "nouveau_dmem.h" #include "nouveau_dmem.h"
#include <nvif/notify.h> #include <nvif/event.h>
#include <nvif/object.h> #include <nvif/object.h>
#include <nvif/vmm.h> #include <nvif/vmm.h>
...@@ -51,7 +51,8 @@ struct nouveau_svm { ...@@ -51,7 +51,8 @@ struct nouveau_svm {
u32 putaddr; u32 putaddr;
u32 get; u32 get;
u32 put; u32 put;
struct nvif_notify notify; struct nvif_event notify;
struct work_struct work;
struct nouveau_svm_fault { struct nouveau_svm_fault {
u64 inst; u64 inst;
...@@ -711,13 +712,11 @@ static int nouveau_range_fault(struct nouveau_svmm *svmm, ...@@ -711,13 +712,11 @@ static int nouveau_range_fault(struct nouveau_svmm *svmm,
return ret; return ret;
} }
static int static void
nouveau_svm_fault(struct nvif_notify *notify) nouveau_svm_fault(struct work_struct *work)
{ {
struct nouveau_svm_fault_buffer *buffer = struct nouveau_svm_fault_buffer *buffer = container_of(work, typeof(*buffer), work);
container_of(notify, typeof(*buffer), notify); struct nouveau_svm *svm = container_of(buffer, typeof(*svm), buffer[buffer->id]);
struct nouveau_svm *svm =
container_of(buffer, typeof(*svm), buffer[buffer->id]);
struct nvif_object *device = &svm->drm->client.device.object; struct nvif_object *device = &svm->drm->client.device.object;
struct nouveau_svmm *svmm; struct nouveau_svmm *svmm;
struct { struct {
...@@ -737,7 +736,7 @@ nouveau_svm_fault(struct nvif_notify *notify) ...@@ -737,7 +736,7 @@ nouveau_svm_fault(struct nvif_notify *notify)
buffer->put = nvif_rd32(device, buffer->putaddr); buffer->put = nvif_rd32(device, buffer->putaddr);
buffer->get = nvif_rd32(device, buffer->getaddr); buffer->get = nvif_rd32(device, buffer->getaddr);
if (buffer->get == buffer->put) if (buffer->get == buffer->put)
return NVIF_NOTIFY_KEEP; return;
} }
buffer->fault_nr = 0; buffer->fault_nr = 0;
...@@ -881,7 +880,15 @@ nouveau_svm_fault(struct nvif_notify *notify) ...@@ -881,7 +880,15 @@ nouveau_svm_fault(struct nvif_notify *notify)
/* Issue fault replay to the GPU. */ /* Issue fault replay to the GPU. */
if (replay) if (replay)
nouveau_svm_fault_replay(svm); 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 * static struct nouveau_pfnmap_args *
...@@ -936,7 +943,9 @@ static void ...@@ -936,7 +943,9 @@ static void
nouveau_svm_fault_buffer_fini(struct nouveau_svm *svm, int id) nouveau_svm_fault_buffer_fini(struct nouveau_svm *svm, int id)
{ {
struct nouveau_svm_fault_buffer *buffer = &svm->buffer[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 static int
...@@ -944,10 +953,12 @@ nouveau_svm_fault_buffer_init(struct nouveau_svm *svm, int id) ...@@ -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 nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
struct nvif_object *device = &svm->drm->client.device.object; struct nvif_object *device = &svm->drm->client.device.object;
buffer->get = nvif_rd32(device, buffer->getaddr); buffer->get = nvif_rd32(device, buffer->getaddr);
buffer->put = nvif_rd32(device, buffer->putaddr); buffer->put = nvif_rd32(device, buffer->putaddr);
SVM_DBG(svm, "get %08x put %08x (init)", buffer->get, buffer->put); 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 static void
...@@ -956,15 +967,18 @@ nouveau_svm_fault_buffer_dtor(struct nouveau_svm *svm, int id) ...@@ -956,15 +967,18 @@ nouveau_svm_fault_buffer_dtor(struct nouveau_svm *svm, int id)
struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id]; struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
int i; int i;
if (!nvif_object_constructed(&buffer->object))
return;
nouveau_svm_fault_buffer_fini(svm, id);
if (buffer->fault) { if (buffer->fault) {
for (i = 0; buffer->fault[i] && i < buffer->entries; i++) for (i = 0; buffer->fault[i] && i < buffer->entries; i++)
kfree(buffer->fault[i]); kfree(buffer->fault[i]);
kvfree(buffer->fault); kvfree(buffer->fault);
} }
nouveau_svm_fault_buffer_fini(svm, id); nvif_event_dtor(&buffer->notify);
nvif_notify_dtor(&buffer->notify);
nvif_object_dtor(&buffer->object); nvif_object_dtor(&buffer->object);
} }
...@@ -990,9 +1004,9 @@ nouveau_svm_fault_buffer_ctor(struct nouveau_svm *svm, s32 oclass, int id) ...@@ -990,9 +1004,9 @@ nouveau_svm_fault_buffer_ctor(struct nouveau_svm *svm, s32 oclass, int id)
buffer->entries = args.entries; buffer->entries = args.entries;
buffer->getaddr = args.get; buffer->getaddr = args.get;
buffer->putaddr = args.put; buffer->putaddr = args.put;
INIT_WORK(&buffer->work, nouveau_svm_fault);
ret = nvif_notify_ctor(&buffer->object, "svmFault", nouveau_svm_fault, ret = nvif_event_ctor(&buffer->object, "svmFault", id, nouveau_svm_event, true, NULL, 0,
true, NVB069_V0_NTFY_FAULT, NULL, 0, 0,
&buffer->notify); &buffer->notify);
if (ret) if (ret)
return ret; return ret;
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include "priv.h" #include "priv.h"
#include <core/memory.h> #include <core/memory.h>
#include <core/notify.h>
static void static void
nvkm_fault_ntfy_fini(struct nvkm_event *event, int type, int index) 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) ...@@ -38,23 +37,8 @@ nvkm_fault_ntfy_init(struct nvkm_event *event, int type, int index)
fault->func->buffer.intr(fault->buffer[index], true); 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 static const struct nvkm_event_func
nvkm_fault_ntfy = { nvkm_fault_ntfy = {
.ctor = nvkm_fault_ntfy_ctor,
.init = nvkm_fault_ntfy_init, .init = nvkm_fault_ntfy_init,
.fini = nvkm_fault_ntfy_fini, .fini = nvkm_fault_ntfy_fini,
}; };
......
...@@ -22,33 +22,37 @@ ...@@ -22,33 +22,37 @@
#include "priv.h" #include "priv.h"
#include <core/memory.h> #include <core/memory.h>
#include <core/event.h>
#include <subdev/mmu.h> #include <subdev/mmu.h>
#include <nvif/clb069.h> #include <nvif/clb069.h>
#include <nvif/unpack.h> #include <nvif/unpack.h>
static int static int
nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc, nvkm_ufault_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_uevent *uevent)
enum nvkm_object_map *type, u64 *addr, u64 *size)
{ {
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object); struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
struct nvkm_device *device = buffer->fault->subdev.device; union nvif_clb069_event_args *args = argv;
*type = NVKM_OBJECT_MAP_IO;
*addr = device->func->resource_addr(device, 3) + buffer->addr; if (!uevent)
*size = nvkm_memory_size(buffer->mem);
return 0; 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 static int
nvkm_ufault_ntfy(struct nvkm_object *object, u32 type, nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc,
struct nvkm_event **pevent) enum nvkm_object_map *type, u64 *addr, u64 *size)
{ {
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object); struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
if (type == NVB069_V0_NTFY_FAULT) { struct nvkm_device *device = buffer->fault->subdev.device;
*pevent = &buffer->fault->event; *type = NVKM_OBJECT_MAP_IO;
*addr = device->func->resource_addr(device, 3) + buffer->addr;
*size = nvkm_memory_size(buffer->mem);
return 0; return 0;
}
return -EINVAL;
} }
static int static int
...@@ -78,8 +82,8 @@ nvkm_ufault = { ...@@ -78,8 +82,8 @@ nvkm_ufault = {
.dtor = nvkm_ufault_dtor, .dtor = nvkm_ufault_dtor,
.init = nvkm_ufault_init, .init = nvkm_ufault_init,
.fini = nvkm_ufault_fini, .fini = nvkm_ufault_fini,
.ntfy = nvkm_ufault_ntfy,
.map = nvkm_ufault_map, .map = nvkm_ufault_map,
.uevent = nvkm_ufault_uevent,
}; };
int int
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册