summaryrefslogtreecommitdiff
path: root/nvif
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-08-11 11:36:45 +1000
committerBen Skeggs <bskeggs@redhat.com>2014-08-15 07:55:34 +1000
commitc970951a4fe30d476beb45c9323c65ca673053f5 (patch)
tree919810c0a103772b6f336d7169e850ba0cacb237 /nvif
parent19ae6962b47db91803f3100e9cab6f43ef348fc7 (diff)
downloadnouveau-c970951a4fe30d476beb45c9323c65ca673053f5.tar.gz
nvif: fix a number of notify thinkos
Note to self: more sleep Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'nvif')
-rw-r--r--nvif/notify.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/nvif/notify.c b/nvif/notify.c
index 7c06123a5..7e03cdd17 100644
--- a/nvif/notify.c
+++ b/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, &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)) {
+ atomic_inc(&notify->putcnt);
if (test_bit(NVIF_NOTIFY_WORK, &notify->flags)) {
- atomic_inc(&notify->putcnt);
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);
- }
}
}