From 7caa63c04029c5882865867470c106ef73eafb2b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 11 Aug 2014 11:36:45 +1000 Subject: [PATCH] drm/nouveau/nvif: fix a number of notify thinkos Note to self: more sleep Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/core/client.c | 4 ++-- drivers/gpu/drm/nouveau/core/include/core/client.h | 2 +- drivers/gpu/drm/nouveau/nvif/notify.c | 25 +++++++++++++++------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/core/client.c b/drivers/gpu/drm/nouveau/core/core/client.c index 10598de..68bf067 100644 --- a/drivers/gpu/drm/nouveau/core/core/client.c +++ b/drivers/gpu/drm/nouveau/core/core/client.c @@ -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 diff --git a/drivers/gpu/drm/nouveau/core/include/core/client.h b/drivers/gpu/drm/nouveau/core/include/core/client.h index 4fc6ab1..1794a05 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/client.h +++ b/drivers/gpu/drm/nouveau/core/include/core/client.h @@ -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 * diff --git a/drivers/gpu/drm/nouveau/nvif/notify.c b/drivers/gpu/drm/nouveau/nvif/notify.c index 7c06123..7e03cdd 100644 --- a/drivers/gpu/drm/nouveau/nvif/notify.c +++ b/drivers/gpu/drm/nouveau/nvif/notify.c @@ -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, ¬ify->flags)) { + if (!keep) + atomic_dec(¬ify->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)) { + atomic_inc(¬ify->putcnt); if (test_bit(NVIF_NOTIFY_WORK, ¬ify->flags)) { - atomic_inc(¬ify->putcnt); memcpy((void *)notify->data, data, size); schedule_work(¬ify->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(¬ify->putcnt); - nvif_notify_get_(notify); - } } } -- 2.7.4