@@ -103,6 +103,7 @@ nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error)
103
103
void
104
104
nouveau_fence_context_del (struct nouveau_fence_chan * fctx )
105
105
{
106
+ cancel_work_sync (& fctx -> uevent_work );
106
107
nouveau_fence_context_kill (fctx , 0 );
107
108
nvif_event_dtor (& fctx -> event );
108
109
fctx -> dead = 1 ;
@@ -145,12 +146,13 @@ nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fc
145
146
return drop ;
146
147
}
147
148
148
- static int
149
- nouveau_fence_wait_uevent_handler (struct nvif_event * event , void * repv , u32 repc )
149
+ static void
150
+ nouveau_fence_uevent_work (struct work_struct * work )
150
151
{
151
- struct nouveau_fence_chan * fctx = container_of (event , typeof (* fctx ), event );
152
+ struct nouveau_fence_chan * fctx = container_of (work , struct nouveau_fence_chan ,
153
+ uevent_work );
152
154
unsigned long flags ;
153
- int ret = NVIF_EVENT_KEEP ;
155
+ int drop = 0 ;
154
156
155
157
spin_lock_irqsave (& fctx -> lock , flags );
156
158
if (!list_empty (& fctx -> pending )) {
@@ -160,11 +162,20 @@ nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, u32 repc
160
162
fence = list_entry (fctx -> pending .next , typeof (* fence ), head );
161
163
chan = rcu_dereference_protected (fence -> channel , lockdep_is_held (& fctx -> lock ));
162
164
if (nouveau_fence_update (chan , fctx ))
163
- ret = NVIF_EVENT_DROP ;
165
+ drop = 1 ;
164
166
}
167
+ if (drop )
168
+ nvif_event_block (& fctx -> event );
169
+
165
170
spin_unlock_irqrestore (& fctx -> lock , flags );
171
+ }
166
172
167
- return ret ;
173
+ static int
174
+ nouveau_fence_wait_uevent_handler (struct nvif_event * event , void * repv , u32 repc )
175
+ {
176
+ struct nouveau_fence_chan * fctx = container_of (event , typeof (* fctx ), event );
177
+ schedule_work (& fctx -> uevent_work );
178
+ return NVIF_EVENT_KEEP ;
168
179
}
169
180
170
181
void
@@ -178,6 +189,7 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha
178
189
} args ;
179
190
int ret ;
180
191
192
+ INIT_WORK (& fctx -> uevent_work , nouveau_fence_uevent_work );
181
193
INIT_LIST_HEAD (& fctx -> flip );
182
194
INIT_LIST_HEAD (& fctx -> pending );
183
195
spin_lock_init (& fctx -> lock );
0 commit comments