Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7caa63c0 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/nvif: fix a number of notify thinkos



Note to self: more sleep

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 27111a23
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -132,12 +132,12 @@ nvkm_client_notify_new(struct nouveau_client *client,
		if (ret == 0) {
			client->notify[index] = notify;
			notify->client = client;
			return 0;
			return index;
		}
	}

	kfree(notify);
	return 0;
	return ret;
}

static int
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ struct nouveau_client {
	void *data;

	int (*ntfy)(const void *, u32, const void *, u32);
	struct nvkm_client_notify *notify[8];
	struct nvkm_client_notify *notify[16];
};

static inline struct nouveau_client *
+17 −8
Original line number Diff line number Diff line
@@ -87,12 +87,25 @@ nvif_notify_get(struct nvif_notify *notify)
	return 0;
}

static inline int
nvif_notify_func(struct nvif_notify *notify, bool keep)
{
	int ret = notify->func(notify);
	if (ret == NVIF_NOTIFY_KEEP ||
	    !test_and_clear_bit(NVKM_NOTIFY_USER, &notify->flags)) {
		if (!keep)
			atomic_dec(&notify->putcnt);
		else
			nvif_notify_get_(notify);
	}
	return ret;
}

static void
nvif_notify_work(struct work_struct *work)
{
	struct nvif_notify *notify = container_of(work, typeof(*notify), work);
	if (notify->func(notify) == NVIF_NOTIFY_KEEP)
		nvif_notify_get_(notify);
	nvif_notify_func(notify, true);
}

int
@@ -113,19 +126,15 @@ nvif_notify(const void *header, u32 length, const void *data, u32 size)
	if (!WARN_ON(notify == NULL)) {
		struct nvif_client *client = nvif_client(notify->object);
		if (!WARN_ON(notify->size != size)) {
			if (test_bit(NVIF_NOTIFY_WORK, &notify->flags)) {
			atomic_inc(&notify->putcnt);
			if (test_bit(NVIF_NOTIFY_WORK, &notify->flags)) {
				memcpy((void *)notify->data, data, size);
				schedule_work(&notify->work);
				return NVIF_NOTIFY_DROP;
			}
			notify->data = data;
			ret = notify->func(notify);
			ret = nvif_notify_func(notify, client->driver->keep);
			notify->data = NULL;
			if (ret != NVIF_NOTIFY_DROP && client->driver->keep) {
				atomic_inc(&notify->putcnt);
				nvif_notify_get_(notify);
			}
		}
	}