Commit b418ff88 authored by Ben Skeggs's avatar Ben Skeggs

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

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent 55520832
......@@ -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
......@@ -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 @@ static int nouveau_range_fault(struct nouveau_svmm *svmm,
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,9 +1004,9 @@ 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,
ret = nvif_event_ctor(&buffer->object, "svmFault", id, nouveau_svm_event, true, NULL, 0,
&buffer->notify);
if (ret)
return ret;
......
......@@ -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,
};
......
......@@ -22,33 +22,37 @@
#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_map(struct nvkm_object *object, void *argv, u32 argc,
enum nvkm_object_map *type, u64 *addr, u64 *size)
nvkm_ufault_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_uevent *uevent)
{
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
struct nvkm_device *device = buffer->fault->subdev.device;
*type = NVKM_OBJECT_MAP_IO;
*addr = device->func->resource_addr(device, 3) + buffer->addr;
*size = nvkm_memory_size(buffer->mem);
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_ntfy(struct nvkm_object *object, u32 type,
struct nvkm_event **pevent)
nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc,
enum nvkm_object_map *type, u64 *addr, u64 *size)
{
struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object);
if (type == NVB069_V0_NTFY_FAULT) {
*pevent = &buffer->fault->event;
struct nvkm_device *device = buffer->fault->subdev.device;
*type = NVKM_OBJECT_MAP_IO;
*addr = device->func->resource_addr(device, 3) + buffer->addr;
*size = nvkm_memory_size(buffer->mem);
return 0;
}
return -EINVAL;
}
static int
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment