diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvif/notify.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvif/notify.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/nvif/notify.c b/drivers/gpu/drm/nouveau/nvif/notify.c index 7c06123a559c..7e03cdd17827 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) | |||
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
89 | 89 | ||
90 | static inline int | ||
91 | nvif_notify_func(struct nvif_notify *notify, bool keep) | ||
92 | { | ||
93 | int ret = notify->func(notify); | ||
94 | if (ret == NVIF_NOTIFY_KEEP || | ||
95 | !test_and_clear_bit(NVKM_NOTIFY_USER, ¬ify->flags)) { | ||
96 | if (!keep) | ||
97 | atomic_dec(¬ify->putcnt); | ||
98 | else | ||
99 | nvif_notify_get_(notify); | ||
100 | } | ||
101 | return ret; | ||
102 | } | ||
103 | |||
90 | static void | 104 | static void |
91 | nvif_notify_work(struct work_struct *work) | 105 | nvif_notify_work(struct work_struct *work) |
92 | { | 106 | { |
93 | struct nvif_notify *notify = container_of(work, typeof(*notify), work); | 107 | struct nvif_notify *notify = container_of(work, typeof(*notify), work); |
94 | if (notify->func(notify) == NVIF_NOTIFY_KEEP) | 108 | nvif_notify_func(notify, true); |
95 | nvif_notify_get_(notify); | ||
96 | } | 109 | } |
97 | 110 | ||
98 | int | 111 | int |
@@ -113,19 +126,15 @@ nvif_notify(const void *header, u32 length, const void *data, u32 size) | |||
113 | if (!WARN_ON(notify == NULL)) { | 126 | if (!WARN_ON(notify == NULL)) { |
114 | struct nvif_client *client = nvif_client(notify->object); | 127 | struct nvif_client *client = nvif_client(notify->object); |
115 | if (!WARN_ON(notify->size != size)) { | 128 | if (!WARN_ON(notify->size != size)) { |
129 | atomic_inc(¬ify->putcnt); | ||
116 | if (test_bit(NVIF_NOTIFY_WORK, ¬ify->flags)) { | 130 | if (test_bit(NVIF_NOTIFY_WORK, ¬ify->flags)) { |
117 | atomic_inc(¬ify->putcnt); | ||
118 | memcpy((void *)notify->data, data, size); | 131 | memcpy((void *)notify->data, data, size); |
119 | schedule_work(¬ify->work); | 132 | schedule_work(¬ify->work); |
120 | return NVIF_NOTIFY_DROP; | 133 | return NVIF_NOTIFY_DROP; |
121 | } | 134 | } |
122 | notify->data = data; | 135 | notify->data = data; |
123 | ret = notify->func(notify); | 136 | ret = nvif_notify_func(notify, client->driver->keep); |
124 | notify->data = NULL; | 137 | notify->data = NULL; |
125 | if (ret != NVIF_NOTIFY_DROP && client->driver->keep) { | ||
126 | atomic_inc(¬ify->putcnt); | ||
127 | nvif_notify_get_(notify); | ||
128 | } | ||
129 | } | 138 | } |
130 | } | 139 | } |
131 | 140 | ||