Am 06.12.18 um 02:41 schrieb jglisse@xxxxxxxxxx: > From: Jérôme Glisse <jglisse@xxxxxxxxxx> > > The debugfs take reference on fence without dropping them. Also the > rcu section are not well balance. Fix all that ... > > Signed-off-by: Jérôme Glisse <jglisse@xxxxxxxxxx> > Cc: Christian König <christian.koenig@xxxxxxx> > Cc: Daniel Vetter <daniel.vetter@xxxxxxxx> > Cc: Sumit Semwal <sumit.semwal@xxxxxxxxxx> > Cc: linux-media@xxxxxxxxxxxxxxx > Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx > Cc: linaro-mm-sig@xxxxxxxxxxxxxxxx > Cc: Stéphane Marchesin <marcheu@xxxxxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx Well NAK, you are now taking the RCU lock twice and dropping the RCU and still accessing fobj has a huge potential for accessing freed up memory. The only correct thing I can see here is to grab a reference to the fence before printing any info on it, Christian. > --- > drivers/dma-buf/dma-buf.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > index 13884474d158..f6f4de42ac49 100644 > --- a/drivers/dma-buf/dma-buf.c > +++ b/drivers/dma-buf/dma-buf.c > @@ -1051,24 +1051,31 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused) > fobj = rcu_dereference(robj->fence); > shared_count = fobj ? fobj->shared_count : 0; > fence = rcu_dereference(robj->fence_excl); > + fence = dma_fence_get_rcu(fence); > if (!read_seqcount_retry(&robj->seq, seq)) > break; > rcu_read_unlock(); > } > - > - if (fence) > + if (fence) { > seq_printf(s, "\tExclusive fence: %s %s %ssignalled\n", > fence->ops->get_driver_name(fence), > fence->ops->get_timeline_name(fence), > dma_fence_is_signaled(fence) ? "" : "un"); > + dma_fence_put(fence); > + } > + > + rcu_read_lock(); > for (i = 0; i < shared_count; i++) { > fence = rcu_dereference(fobj->shared[i]); > if (!dma_fence_get_rcu(fence)) > continue; > + rcu_read_unlock(); > seq_printf(s, "\tShared fence: %s %s %ssignalled\n", > fence->ops->get_driver_name(fence), > fence->ops->get_timeline_name(fence), > dma_fence_is_signaled(fence) ? "" : "un"); > + dma_fence_put(fence); > + rcu_read_lock(); > } > rcu_read_unlock(); >