Am 09.08.2018 um 14:08 schrieb Chris Wilson: > Quoting Christian König (2018-08-09 12:37:08) >> void reservation_object_add_shared_fence(struct reservation_object *obj, >> struct dma_fence *fence) >> { >> - struct reservation_object_list *old, *fobj = obj->staged; >> + struct reservation_object_list *fobj; >> + unsigned int i; >> >> - old = reservation_object_get_list(obj); >> - obj->staged = NULL; >> + dma_fence_get(fence); >> + >> + fobj = reservation_object_get_list(obj); >> >> - if (!fobj) { >> - BUG_ON(old->shared_count >= old->shared_max); >> - reservation_object_add_shared_inplace(obj, old, fence); >> - } else >> - reservation_object_add_shared_replace(obj, old, fobj, fence); >> + preempt_disable(); >> + write_seqcount_begin(&obj->seq); >> + >> + for (i = 0; i < fobj->shared_count; ++i) { >> + struct dma_fence *old_fence; >> + >> + old_fence = rcu_dereference_protected(fobj->shared[i], >> + reservation_object_held(obj)); >> + if (old_fence->context == fence->context || >> + dma_fence_is_signaled(old_fence)) { > Are you happy with the possibility that the shared[] may contain two > fences belonging to the same context? That was a sticking point earlier. Yeah, that is fixed by now. I've removed the dependency on this in our VM handling code quite a while ago. > >> + /* memory barrier is added by write_seqcount_begin */ >> + RCU_INIT_POINTER(fobj->shared[i], fence); >> + write_seqcount_end(&obj->seq); >> + preempt_enable(); >> + dma_fence_put(old_fence); > You can rearrange this to have a single exit. Good point, going to rearrange the code. Christian. > > for (i = 0; i < fobj->shared_count; ++i) { > struct dma_fence *old_fence; > > old_fence = rcu_dereference_protected(fobj->shared[i], > reservation_object_held(obj)); > if (old_fence->context == fence->context || > dma_fence_is_signaled(old_fence)) { > dma_fence_put(old_fence); > goto replace; > } > } > fobj->shared_count++; > replace: > /* > * memory barrier is added by write_seqcount_begin, > * fobj->shared_count is protected by this lock too > */ > RCU_INIT_POINTER(fobj->shared[i], fence); > write_seqcount_end(&obj->seq); > preempt_enable(); > } > -Chris