Commit f43e47c0 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/nvkm: add a replacement for nvkm_notify



This replaces the twisty, confusing, relationship between nvkm_event and
nvkm_notify with something much simpler, and less racey.  It also places
events in the object tree hierarchy, which will allow a heap of the code
tracking events across allocation/teardown/suspend to be removed.

This commit just adds the new interfaces, and passes the owning subdev to
the event constructor to enable debug-tracing in the new code.

v2:
- use ?: (lyude)

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent 361863ce
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
#define NVIF_CLASS_VMM_GM200                         /* ifb00d.h */  0x8000b00d
#define NVIF_CLASS_VMM_GP100                         /* ifc00d.h */  0x8000c00d

#define NVIF_CLASS_EVENT                             /* if000e.h */  0x8000000e

#define NVIF_CLASS_DISP                              /* if0010.h */  0x80000010
#define NVIF_CLASS_CONN                              /* if0011.h */  0x80000011
#define NVIF_CLASS_OUTP                              /* if0012.h */  0x80000012
+32 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_EVENT_H__
#define __NVIF_EVENT_H__
#include <nvif/object.h>
#include <nvif/if000e.h>
struct nvif_event;

#define NVIF_EVENT_KEEP 0
#define NVIF_EVENT_DROP 1
typedef int (*nvif_event_func)(struct nvif_event *, void *repv, u32 repc);

struct nvif_event {
	struct nvif_object object;
	nvif_event_func func;
};

static inline bool
nvif_event_constructed(struct nvif_event *event)
{
	return nvif_object_constructed(&event->object);
}

int nvif_event_ctor_(struct nvif_object *, const char *, u32, nvif_event_func, bool,
		     struct nvif_event_v0 *, u32, bool, struct nvif_event *);

static inline int
nvif_event_ctor(struct nvif_object *parent, const char *name, u32 handle, nvif_event_func func,
		bool wait, struct nvif_event_v0 *args, u32 argc, struct nvif_event *event)
{
	return nvif_event_ctor_(parent, name, handle, func, wait, args, argc, true, event);
}

void nvif_event_dtor(struct nvif_event *);
int nvif_event_allow(struct nvif_event *);
int nvif_event_block(struct nvif_event *);

struct nvif_notify_req_v0 {
	__u8  version;
+26 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_IF000E_H__
#define __NVIF_IF000E_H__

union nvif_event_args {
	struct nvif_event_v0 {
		__u8 version;
		__u8 wait;
		__u8 pad02[6];
		__u8 data[];
	} v0;
};

#define NVIF_EVENT_V0_ALLOW 0x00
#define NVIF_EVENT_V0_BLOCK 0x01

union nvif_event_allow_args {
	struct nvif_event_allow_vn {
	} vn;
};

union nvif_event_block_args {
	struct nvif_event_block_vn {
	} vn;
};
#endif
+2 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ struct nvkm_client {

	void *data;
	int (*ntfy)(const void *, u32, const void *, u32);
	int (*event)(u64 token, void *argv, u32 argc);

	struct list_head umem;
	spinlock_t lock;
@@ -23,6 +24,7 @@ struct nvkm_client {
int  nvkm_client_new(const char *name, u64 device, const char *cfg,
		     const char *dbg,
		     int (*)(const void *, u32, const void *, u32),
		     int (*)(u64, void *, u32),
		     struct nvkm_client **);
struct nvkm_client *nvkm_client_search(struct nvkm_client *, u64 handle);

+37 −1
Original line number Diff line number Diff line
@@ -4,9 +4,12 @@
#include <core/os.h>
struct nvkm_notify;
struct nvkm_object;
struct nvkm_oclass;
struct nvkm_uevent;

struct nvkm_event {
	const struct nvkm_event_func *func;
	struct nvkm_subdev *subdev;

	int types_nr;
	int index_nr;
@@ -15,6 +18,8 @@ struct nvkm_event {
	spinlock_t list_lock;
	struct list_head list;
	int *refs;

	struct list_head ntfy;
};

struct nvkm_event_func {
@@ -25,11 +30,42 @@ struct nvkm_event_func {
	void (*fini)(struct nvkm_event *, int type, int index);
};

int  nvkm_event_init(const struct nvkm_event_func *func, int types_nr,
int  nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *, int types_nr,
		     int index_nr, struct nvkm_event *);
void nvkm_event_fini(struct nvkm_event *);
void nvkm_event_get(struct nvkm_event *, u32 types, int index);
void nvkm_event_put(struct nvkm_event *, u32 types, int index);
void nvkm_event_send(struct nvkm_event *, u32 types, int index,
		     void *data, u32 size);

#define NVKM_EVENT_KEEP 0
#define NVKM_EVENT_DROP 1
struct nvkm_event_ntfy;
typedef int (*nvkm_event_func)(struct nvkm_event_ntfy *, u32 bits);

struct nvkm_event_ntfy {
	struct nvkm_event *event;
	int id;
	u32 bits;
	bool wait;
	nvkm_event_func func;

	atomic_t allowed;
	bool running;

	struct list_head head;
};

void nvkm_event_ntfy(struct nvkm_event *, int id, u32 bits);
bool nvkm_event_ntfy_valid(struct nvkm_event *, int id, u32 bits);
void nvkm_event_ntfy_add(struct nvkm_event *, int id, u32 bits, bool wait, nvkm_event_func,
			 struct nvkm_event_ntfy *);
void nvkm_event_ntfy_del(struct nvkm_event_ntfy *);
void nvkm_event_ntfy_allow(struct nvkm_event_ntfy *);
void nvkm_event_ntfy_block(struct nvkm_event_ntfy *);

typedef int (*nvkm_uevent_func)(struct nvkm_object *, u64 token, u32 bits);

int nvkm_uevent_new(const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **);
int nvkm_uevent_add(struct nvkm_uevent *, struct nvkm_event *, int id, u32 bits, nvkm_uevent_func);
#endif
Loading