diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-11 11:36:45 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-08-15 07:55:34 +1000 |
commit | c970951a4fe30d476beb45c9323c65ca673053f5 (patch) | |
tree | 919810c0a103772b6f336d7169e850ba0cacb237 /nvif | |
parent | 19ae6962b47db91803f3100e9cab6f43ef348fc7 (diff) | |
download | nouveau-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.c | 25 |
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, ¬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); - } } } |