On Mon, Aug 29, 2016 at 08:08:31AM +0100, Chris Wilson wrote: > In order to be completely generic, we have to double check the read > seqlock after acquiring a reference to the fence. If the driver is > allocating fences from a SLAB_DESTROY_BY_RCU, or similar freelist, then > within an RCU grace period a fence may be freed and reallocated. The RCU > read side critical section does not prevent this reallocation, instead > we have to inspect the reservation's seqlock to double check if the > fences have been reassigned as we were acquiring our reference. > > Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > Cc: Daniel Vetter <daniel.vetter@xxxxxxxx> > Cc: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> > Cc: Christian König <christian.koenig@xxxxxxx> > Cc: Alex Deucher <alexander.deucher@xxxxxxx> > Cc: Sumit Semwal <sumit.semwal@xxxxxxxxxx> > Cc: linux-media@xxxxxxxxxxxxxxx > Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx > Cc: linaro-mm-sig@xxxxxxxxxxxxxxxx Reviewed-by: Daniel Vetter <daniel.vetter@xxxxxxxx> > --- > drivers/dma-buf/reservation.c | 11 +++++------ > 1 file changed, 5 insertions(+), 6 deletions(-) > > diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c > index 10fd441dd4ed..3369e4668e96 100644 > --- a/drivers/dma-buf/reservation.c > +++ b/drivers/dma-buf/reservation.c > @@ -388,9 +388,6 @@ retry: > if (fobj) > shared_count = fobj->shared_count; > > - if (read_seqcount_retry(&obj->seq, seq)) > - goto unlock_retry; > - > for (i = 0; i < shared_count; ++i) { > struct fence *lfence = rcu_dereference(fobj->shared[i]); > > @@ -413,9 +410,6 @@ retry: > if (!shared_count) { > struct fence *fence_excl = rcu_dereference(obj->fence_excl); > > - if (read_seqcount_retry(&obj->seq, seq)) > - goto unlock_retry; > - > if (fence_excl && > !test_bit(FENCE_FLAG_SIGNALED_BIT, &fence_excl->flags)) { > if (!fence_get_rcu(fence_excl)) > @@ -430,6 +424,11 @@ retry: > > rcu_read_unlock(); > if (fence) { > + if (read_seqcount_retry(&obj->seq, seq)) { > + fence_put(fence); > + goto retry; > + } > + > ret = fence_wait_timeout(fence, intr, ret); > fence_put(fence); > if (ret > 0 && wait_all && (i + 1 < shared_count)) > -- > 2.9.3 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx