aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-08-10 21:36:45 -0400
committerBen Skeggs <bskeggs@redhat.com>2014-08-14 17:58:38 -0400
commit7caa63c04029c5882865867470c106ef73eafb2b (patch)
treebb3c6bf6243c620b222a4ce9930df01dd82536d4 /drivers/gpu
parent27111a23d01c1dba3180c998629004ab4c9ac985 (diff)
drm/nouveau/nvif: fix a number of notify thinkos
Note to self: more sleep Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/core/core/client.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/client.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvif/notify.c25
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 10598dede9e9..68bf06768123 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,
132 if (ret == 0) { 132 if (ret == 0) {
133 client->notify[index] = notify; 133 client->notify[index] = notify;
134 notify->client = client; 134 notify->client = client;
135 return 0; 135 return index;
136 } 136 }
137 } 137 }
138 138
139 kfree(notify); 139 kfree(notify);
140 return 0; 140 return ret;
141} 141}
142 142
143static int 143static int
diff --git a/drivers/gpu/drm/nouveau/core/include/core/client.h b/drivers/gpu/drm/nouveau/core/include/core/client.h
index 4fc6ab12382d..1794a05205d8 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 {
14 void *data; 14 void *data;
15 15
16 int (*ntfy)(const void *, u32, const void *, u32); 16 int (*ntfy)(const void *, u32, const void *, u32);
17 struct nvkm_client_notify *notify[8]; 17 struct nvkm_client_notify *notify[16];
18}; 18};
19 19
20static inline struct nouveau_client * 20static inline struct nouveau_client *
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
90static inline int
91nvif_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, &notify->flags)) {
96 if (!keep)
97 atomic_dec(&notify->putcnt);
98 else
99 nvif_notify_get_(notify);
100 }
101 return ret;
102}
103
90static void 104static void
91nvif_notify_work(struct work_struct *work) 105nvif_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
98int 111int
@@ -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(&notify->putcnt);
116 if (test_bit(NVIF_NOTIFY_WORK, &notify->flags)) { 130 if (test_bit(NVIF_NOTIFY_WORK, &notify->flags)) {
117 atomic_inc(&notify->putcnt);
118 memcpy((void *)notify->data, data, size); 131 memcpy((void *)notify->data, data, size);
119 schedule_work(&notify->work); 132 schedule_work(&notify->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(&notify->putcnt);
127 nvif_notify_get_(notify);
128 }
129 } 138 }
130 } 139 }
131 140