[Mesa-dev] [PATCH] etnaviv: Use reentrant screen lock around flush
The flush callback may be called on the same pipe context, and thus the same stream, from two different threads of execution. However, etna_cmd_stream_flush{,2}() must not be called on the same stream from two different threads of execution as that would mess up the etna_bo refcounting and likely have other ugly side effects. Fix this by using a reentrant screen lock around the flush callback. Signed-off-by: Marek Vasut Cc: Christian Gmeiner Cc: Lucas Stach --- src/gallium/drivers/etnaviv/etnaviv_context.c | 5 + 1 file changed, 5 insertions(+) diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index a59338490b6..ab6b2d5e154 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -310,8 +310,11 @@ etna_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, enum pipe_flush_flags flags) { struct etna_context *ctx = etna_context(pctx); + struct etna_screen *screen = ctx->screen; int out_fence_fd = -1; + mtx_lock(>lock); + list_for_each_entry(struct etna_hw_query, hq, >active_hw_queries, node) etna_hw_query_suspend(hq, ctx); @@ -324,6 +327,8 @@ etna_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence, if (fence) *fence = etna_fence_create(pctx, out_fence_fd); + + mtx_unlock(>lock); } static void -- 2.20.1 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH v5] etnaviv: fix resource usage tracking across different pipe_context's
On 3/17/19 10:48 AM, Christian Gmeiner wrote: > Am Sa., 16. März 2019 um 20:55 Uhr schrieb Marek Vasut : >> >> On 2/22/19 10:30 AM, Boris Brezillon wrote: >>> On Thu, 21 Feb 2019 23:29:53 +0100 >>> Boris Brezillon wrote: >>> >>>> Christian, Marek, >>>> >>>> On Wed, 30 Jan 2019 05:28:14 +0100 >>>> Marek Vasut wrote: >>>> >>>>> From: Christian Gmeiner >>>>> >>>>> A pipe_resource can be shared by all the pipe_context's hanging off the >>>>> same pipe_screen. >>>> >>>> We seem to be impacted by the problem you're fixing here, but, while >>>> this patch definitely make things much better, the problem does not >>>> seem to be entirely fixed (at least in our case). >>>> >>>> A bit more context: we have Qt App using QtWebEngine to render html >>>> content. When we call QtWebEngine::initialize(), which as for effect >>>> to allow shared GL contexts, we sometimes notice that part of the web >>>> page is mis-rendered. That does not happen when we omit the >>>> QtWebEngine::initialize() call. >>>> As said above, this patch make those rendering issues less likely to >>>> happen, but we still have the problem from time to time. So I thought >>>> I'd share my guesses about what could cause these issues before >>>> debugging it further. >>>> >>>> First thing I noticed: I couldn't reproduce the problem with [1] >>>> applied (+ a tiny change forcing CPU-based tiling no matter the size of >>>> the region to tile/untile). So, my guess is that it's related to how we >>>> handle GPU-based tiling/untiling. >>>> Also noticed that we're testing the rsc->status here [2] without the >>>> screen->lock held, and there might be a race with another thread calling >>>> resource_used(). We might also lack a resource_read(ctx, >base) >>>> here [3]. But even after fixing those problems, the rendering issues >>>> are not gone. >>> >>> I tested again with the following diff applied on top of your patch, and >>> the remaining rendering issues we had seem to be gone (don't know what I >>> messed up in my previous tests :-/). >>> >>> --->8--- >>> diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c >>> b/src/gallium/drivers/etnaviv/etnaviv_rs.c >>> index fc4f65dbeee1..b8c8b96a6f72 100644 >>> --- a/src/gallium/drivers/etnaviv/etnaviv_rs.c >>> +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c >>> @@ -729,6 +729,7 @@ etna_try_rs_blit(struct pipe_context *pctx, >>> >>> etna_submit_rs_state(ctx, _to_screen); >>> resource_written(ctx, >base); >>> + resource_read(ctx, >base); >>> dst->seqno++; >>> dst->levels[blit_info->dst.level].ts_valid = false; >>> ctx->dirty |= ETNA_DIRTY_DERIVE_TS; >> While the V6 of this patch [1] is now in mesa upstream, this hunk is >> missing from the V6 . Any special reason for that or is this just an >> omission ? >> > > This and an other change was done in separates commits - see: > > https://cgit.freedesktop.org/mesa/mesa/commit/?id=7244e768040859126a5b74023f587beaa8bef81c > https://cgit.freedesktop.org/mesa/mesa/commit/?id=c56e73449698c31fe72b99a95b7e4ecdb2985b73 > > So everything went in. Ah, thanks :) Do you plan to backport those to mesa 18.3.5 too ? -- Best regards, Marek Vasut ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH v5] etnaviv: fix resource usage tracking across different pipe_context's
On 2/22/19 10:30 AM, Boris Brezillon wrote: > On Thu, 21 Feb 2019 23:29:53 +0100 > Boris Brezillon wrote: > >> Christian, Marek, >> >> On Wed, 30 Jan 2019 05:28:14 +0100 >> Marek Vasut wrote: >> >>> From: Christian Gmeiner >>> >>> A pipe_resource can be shared by all the pipe_context's hanging off the >>> same pipe_screen. >> >> We seem to be impacted by the problem you're fixing here, but, while >> this patch definitely make things much better, the problem does not >> seem to be entirely fixed (at least in our case). >> >> A bit more context: we have Qt App using QtWebEngine to render html >> content. When we call QtWebEngine::initialize(), which as for effect >> to allow shared GL contexts, we sometimes notice that part of the web >> page is mis-rendered. That does not happen when we omit the >> QtWebEngine::initialize() call. >> As said above, this patch make those rendering issues less likely to >> happen, but we still have the problem from time to time. So I thought >> I'd share my guesses about what could cause these issues before >> debugging it further. >> >> First thing I noticed: I couldn't reproduce the problem with [1] >> applied (+ a tiny change forcing CPU-based tiling no matter the size of >> the region to tile/untile). So, my guess is that it's related to how we >> handle GPU-based tiling/untiling. >> Also noticed that we're testing the rsc->status here [2] without the >> screen->lock held, and there might be a race with another thread calling >> resource_used(). We might also lack a resource_read(ctx, >base) >> here [3]. But even after fixing those problems, the rendering issues >> are not gone. > > I tested again with the following diff applied on top of your patch, and > the remaining rendering issues we had seem to be gone (don't know what I > messed up in my previous tests :-/). > > --->8--- > diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c > b/src/gallium/drivers/etnaviv/etnaviv_rs.c > index fc4f65dbeee1..b8c8b96a6f72 100644 > --- a/src/gallium/drivers/etnaviv/etnaviv_rs.c > +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c > @@ -729,6 +729,7 @@ etna_try_rs_blit(struct pipe_context *pctx, > > etna_submit_rs_state(ctx, _to_screen); > resource_written(ctx, >base); > + resource_read(ctx, >base); > dst->seqno++; > dst->levels[blit_info->dst.level].ts_valid = false; > ctx->dirty |= ETNA_DIRTY_DERIVE_TS; While the V6 of this patch [1] is now in mesa upstream, this hunk is missing from the V6 . Any special reason for that or is this just an omission ? [1] https://patchwork.freedesktop.org/patch/287603/ -- Best regards, Marek Vasut ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH v5] etnaviv: fix resource usage tracking across different pipe_context's
On 2/22/19 10:30 AM, Boris Brezillon wrote: > On Thu, 21 Feb 2019 23:29:53 +0100 > Boris Brezillon wrote: > >> Christian, Marek, >> >> On Wed, 30 Jan 2019 05:28:14 +0100 >> Marek Vasut wrote: >> >>> From: Christian Gmeiner >>> >>> A pipe_resource can be shared by all the pipe_context's hanging off the >>> same pipe_screen. >> >> We seem to be impacted by the problem you're fixing here, but, while >> this patch definitely make things much better, the problem does not >> seem to be entirely fixed (at least in our case). >> >> A bit more context: we have Qt App using QtWebEngine to render html >> content. When we call QtWebEngine::initialize(), which as for effect >> to allow shared GL contexts, we sometimes notice that part of the web >> page is mis-rendered. That does not happen when we omit the >> QtWebEngine::initialize() call. >> As said above, this patch make those rendering issues less likely to >> happen, but we still have the problem from time to time. So I thought >> I'd share my guesses about what could cause these issues before >> debugging it further. >> >> First thing I noticed: I couldn't reproduce the problem with [1] >> applied (+ a tiny change forcing CPU-based tiling no matter the size of >> the region to tile/untile). So, my guess is that it's related to how we >> handle GPU-based tiling/untiling. >> Also noticed that we're testing the rsc->status here [2] without the >> screen->lock held, and there might be a race with another thread calling >> resource_used(). We might also lack a resource_read(ctx, >base) >> here [3]. But even after fixing those problems, the rendering issues >> are not gone. > > I tested again with the following diff applied on top of your patch, and > the remaining rendering issues we had seem to be gone (don't know what I > messed up in my previous tests :-/). > > --->8--- > diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c > b/src/gallium/drivers/etnaviv/etnaviv_rs.c > index fc4f65dbeee1..b8c8b96a6f72 100644 > --- a/src/gallium/drivers/etnaviv/etnaviv_rs.c > +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c > @@ -729,6 +729,7 @@ etna_try_rs_blit(struct pipe_context *pctx, > > etna_submit_rs_state(ctx, _to_screen); > resource_written(ctx, >base); > + resource_read(ctx, >base); > dst->seqno++; > dst->levels[blit_info->dst.level].ts_valid = false; > ctx->dirty |= ETNA_DIRTY_DERIVE_TS; > diff --git a/src/gallium/drivers/etnaviv/etnaviv_transfer.c > b/src/gallium/drivers/etnaviv/etnaviv_transfer.c > index a3013e624ead..e4b2ac605e63 100644 > --- a/src/gallium/drivers/etnaviv/etnaviv_transfer.c > +++ b/src/gallium/drivers/etnaviv/etnaviv_transfer.c > @@ -356,6 +356,7 @@ etna_transfer_map(struct pipe_context *pctx, struct > pipe_resource *prsc, > * transfers without a temporary resource. > */ > if (trans->rsc || !(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { > + struct etna_screen *screen = ctx->screen; >uint32_t prep_flags = 0; > >/* > @@ -364,11 +365,13 @@ etna_transfer_map(struct pipe_context *pctx, struct > pipe_resource *prsc, > * current GPU usage (reads must wait for GPU writes, writes must have > * exclusive access to the buffer). > */ > + mtx_lock(>lock); >if ((trans->rsc && (etna_resource(trans->rsc)->status & > ETNA_PENDING_WRITE)) || >(!trans->rsc && > (((usage & PIPE_TRANSFER_READ) && (rsc->status & > ETNA_PENDING_WRITE)) || > ((usage & PIPE_TRANSFER_WRITE) && rsc->status > pctx->flush(pctx, NULL, 0); > + mtx_unlock(>lock); > >if (usage & PIPE_TRANSFER_READ) > prep_flags |= DRM_ETNA_PREP_READ; > On iMX6Q Tested-by: Marek Vasut with multiple custom applications. I don't see any breakage. -- Best regards, Marek Vasut ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH v4] etnaviv: fix resource usage tracking across different pipe_context's
On 1/28/19 9:43 AM, Guido Günther wrote: > Hi, > just style nits: > > On Sat, Jan 12, 2019 at 10:22:20PM +0100, Marek Vasut wrote: >> From: Christian Gmeiner >> >> A pipe_resource can be shared by all the pipe_context's hanging off the >> same pipe_screen. Fixed both, thanks. -- Best regards, Marek Vasut ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH v5] etnaviv: fix resource usage tracking across different pipe_context's
From: Christian Gmeiner A pipe_resource can be shared by all the pipe_context's hanging off the same pipe_screen. Signed-off-by: Christian Gmeiner Signed-off-by: Marek Vasut To: mesa-dev@lists.freedesktop.org Cc: etna...@lists.freedesktop.org --- Changes from v1 -> v2: - to remove the resource from the used_resources set when it is destroyed Changes from v2 -> v3: - add locking with mtx_*() to resource and screen (Marek) Changes from v3 -> v4: - drop rsc->lock, just use screen->lock for the entire serialization (Marek) - simplify etna_resource_used() flush condition, which also prevents potentially flushing resources twice (Marek) - don't remove resouces from screen->used_resources in etna_cmd_stream_reset_notify(), they may still be used in other contexts and may need flushing there later on (Marek) Changes from v4 -> v5: - Fix coding style issues reported by Guido --- src/gallium/drivers/etnaviv/etnaviv_context.c | 26 +- src/gallium/drivers/etnaviv/etnaviv_context.h | 3 -- .../drivers/etnaviv/etnaviv_resource.c| 52 +++ .../drivers/etnaviv/etnaviv_resource.h| 8 +-- src/gallium/drivers/etnaviv/etnaviv_screen.c | 12 + src/gallium/drivers/etnaviv/etnaviv_screen.h | 6 +++ 6 files changed, 78 insertions(+), 29 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index 3038d21..2f8cae8 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -36,6 +36,7 @@ #include "etnaviv_query.h" #include "etnaviv_query_hw.h" #include "etnaviv_rasterizer.h" +#include "etnaviv_resource.h" #include "etnaviv_screen.h" #include "etnaviv_shader.h" #include "etnaviv_state.h" @@ -329,7 +330,8 @@ static void etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv) { struct etna_context *ctx = priv; - struct etna_resource *rsc, *rsc_tmp; + struct etna_screen *screen = ctx->screen; + struct set_entry *entry; etna_set_state(stream, VIVS_GL_API_MODE, VIVS_GL_API_MODE_OPENGL); etna_set_state(stream, VIVS_GL_VERTEX_ELEMENT_CONFIG, 0x0001); @@ -384,16 +386,18 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv) ctx->dirty = ~0L; ctx->dirty_sampler_views = ~0L; - /* go through all the used resources and clear their status flag */ - LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, >used_resources, list) - { - debug_assert(rsc->status != 0); - rsc->status = 0; - rsc->pending_ctx = NULL; - list_delinit(>list); - } + /* +* Go through all _resources_ associated with this _screen_, pending +* in this _context_ and mark them as not pending in this _context_ +* anymore, since they were just flushed. +*/ + mtx_lock(>lock); + set_foreach(screen->used_resources, entry) { + struct etna_resource *rsc = (struct etna_resource *)entry->key; - assert(LIST_IS_EMPTY(>used_resources)); + _mesa_set_remove_key(rsc->pending_ctx, ctx); + } + mtx_unlock(>lock); } static void @@ -437,8 +441,6 @@ etna_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) /* need some sane default in case state tracker doesn't set some state: */ ctx->sample_mask = 0x; - list_inithead(>used_resources); - /* Set sensible defaults for state */ etna_cmd_stream_reset_notify(ctx->stream, ctx); diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.h b/src/gallium/drivers/etnaviv/etnaviv_context.h index 584caa7..eff0a23 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.h +++ b/src/gallium/drivers/etnaviv/etnaviv_context.h @@ -136,9 +136,6 @@ struct etna_context { uint32_t prim_hwsupport; struct primconvert_context *primconvert; - /* list of resources used by currently-unsubmitted renders */ - struct list_head used_resources; - struct slab_child_pool transfer_pool; struct blitter_context *blitter; diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c index 3808c29..46ab849 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c @@ -33,6 +33,7 @@ #include "etnaviv_screen.h" #include "etnaviv_translate.h" +#include "util/hash_table.h" #include "util/u_inlines.h" #include "util/u_memory.h" @@ -275,7 +276,6 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout, rsc->halign = halign; pipe_reference_init(>base.reference, 1); - list_inithead(>list); size = setup_miptree(rsc, paddingX, paddingY, msaa_xscale, msaa_yscale); @@ -296,6 +296,11 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout, memset(m
Re: [Mesa-dev] [PATCH v4] etnaviv: fix resource usage tracking across different pipe_context's
On 1/14/19 3:02 PM, Lucas Stach wrote: > Am Montag, den 14.01.2019, 14:54 +0100 schrieb Marek Vasut: >> On 1/14/19 12:16 PM, Lucas Stach wrote: >>> Hi Marek, >>> >>> Am Samstag, den 12.01.2019, 22:22 +0100 schrieb Marek Vasut: >>>>> From: Christian Gmeiner >>>> >>>> A pipe_resource can be shared by all the pipe_context's hanging off the >>>> same pipe_screen. >>>> >>>>>>>>> Signed-off-by: Christian Gmeiner >>>>> Signed-off-by: Marek Vasut >>>> >>>> To: mesa-dev@lists.freedesktop.org >>>> Cc: etna...@lists.freedesktop.org >>>> --- >>>> Changes from v1 -> v2: >>>> - to remove the resource from the used_resources set when it is destroyed >>>> Changes from v2 -> v3: >>>> - add locking with mtx_*() to resource and screen (Marek) >>>> Changes from v3 -> v4: >>>> - drop rsc->lock, just use screen->lock for the entire serialization >>>> (Marek) >>>> - simplify etna_resource_used() flush condition, which also prevents >>>> potentially flushing resources twice (Marek) >>>> - don't remove resouces from screen->used_resources in >>>> etna_cmd_stream_reset_notify(), they may still be used in other >>>> contexts and may need flushing there later on (Marek) >>> >>> The patch mostly makes sense to me now, but don't we need to take the >>> screen->lock on all call sites where we do a ctx->flush? Otherwise we >>> may enter etna_cmd_stream_reset_notify unlocked, changing the >>> used_resources set while other threads might use it at the same time, >>> right? >> >> etna_cmd_stream_reset_notify() takes the lock when accessing the >> used_resources set , see below. > > Uh, sorry seems I mixed this up. But then I don't see how this isn't > deadlocking, as AFAICS mtx_lock isn't recursive. > > In etna_resource_used() you already lock the screen mutex, then when > you find a context that needs flushing you call the context flush, > which flushes the cmd stream and calls into > etna_cmd_stream_reset_notify() where the mutex is locked again -> self > deadlock. [...] >>>> + mtx_init(>lock, mtx_recursive); [...] But it is recursive ... -- Best regards, Marek Vasut ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH v4] etnaviv: fix resource usage tracking across different pipe_context's
On 1/14/19 12:16 PM, Lucas Stach wrote: > Hi Marek, > > Am Samstag, den 12.01.2019, 22:22 +0100 schrieb Marek Vasut: >>> From: Christian Gmeiner >> >> A pipe_resource can be shared by all the pipe_context's hanging off the >> same pipe_screen. >> >>> Signed-off-by: Christian Gmeiner >>> Signed-off-by: Marek Vasut >> To: mesa-dev@lists.freedesktop.org >> Cc: etna...@lists.freedesktop.org >> --- >> Changes from v1 -> v2: >> - to remove the resource from the used_resources set when it is destroyed >> Changes from v2 -> v3: >> - add locking with mtx_*() to resource and screen (Marek) >> Changes from v3 -> v4: >> - drop rsc->lock, just use screen->lock for the entire serialization (Marek) >> - simplify etna_resource_used() flush condition, which also prevents >> potentially flushing resources twice (Marek) >> - don't remove resouces from screen->used_resources in >> etna_cmd_stream_reset_notify(), they may still be used in other >> contexts and may need flushing there later on (Marek) > > The patch mostly makes sense to me now, but don't we need to take the > screen->lock on all call sites where we do a ctx->flush? Otherwise we > may enter etna_cmd_stream_reset_notify unlocked, changing the > used_resources set while other threads might use it at the same time, > right? etna_cmd_stream_reset_notify() takes the lock when accessing the used_resources set , see below. > Regards, > Lucas > >> --- >> src/gallium/drivers/etnaviv/etnaviv_context.c | 26 +- >> src/gallium/drivers/etnaviv/etnaviv_context.h | 3 -- >> .../drivers/etnaviv/etnaviv_resource.c| 52 +++ >> .../drivers/etnaviv/etnaviv_resource.h| 8 +-- >> src/gallium/drivers/etnaviv/etnaviv_screen.c | 12 + >> src/gallium/drivers/etnaviv/etnaviv_screen.h | 6 +++ >> 6 files changed, 78 insertions(+), 29 deletions(-) >> >> diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c >> b/src/gallium/drivers/etnaviv/etnaviv_context.c >> index 3038d21..2f8cae8 100644 >> --- a/src/gallium/drivers/etnaviv/etnaviv_context.c >> +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c >> @@ -36,6 +36,7 @@ >> #include "etnaviv_query.h" >> #include "etnaviv_query_hw.h" >> #include "etnaviv_rasterizer.h" >> +#include "etnaviv_resource.h" >> #include "etnaviv_screen.h" >> #include "etnaviv_shader.h" >> #include "etnaviv_state.h" >> @@ -329,7 +330,8 @@ static void >> etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv) >> { >> struct etna_context *ctx = priv; >> - struct etna_resource *rsc, *rsc_tmp; >> + struct etna_screen *screen = ctx->screen; >> + struct set_entry *entry; >> >> etna_set_state(stream, VIVS_GL_API_MODE, VIVS_GL_API_MODE_OPENGL); >> etna_set_state(stream, VIVS_GL_VERTEX_ELEMENT_CONFIG, 0x0001); >> @@ -384,16 +386,18 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream >> *stream, void *priv) >> ctx->dirty = ~0L; >> ctx->dirty_sampler_views = ~0L; >> >> - /* go through all the used resources and clear their status flag */ >> - LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, >used_resources, list) >> - { >> - debug_assert(rsc->status != 0); >> - rsc->status = 0; >> - rsc->pending_ctx = NULL; >> - list_delinit(>list); >> - } >> + /* >> +* Go through all _resources_ associated with this _screen_, pending >> +* in this _context_ and mark them as not pending in this _context_ >> +* anymore, since they were just flushed. >> +*/ >> + mtx_lock(>lock); >> + set_foreach(screen->used_resources, entry) { >> + struct etna_resource *rsc = (struct etna_resource *)entry->key; >> >> - assert(LIST_IS_EMPTY(>used_resources)); >> + _mesa_set_remove_key(rsc->pending_ctx, ctx); >> + } >> + mtx_unlock(>lock); >> } >> >> static void >> @@ -437,8 +441,6 @@ etna_context_create(struct pipe_screen *pscreen, void >> *priv, unsigned flags) >> /* need some sane default in case state tracker doesn't set some state: >> */ >> ctx->sample_mask = 0x; >> >> - list_inithead(>used_resources); >> - >> /* Set sensible defaults for state */ >> etna_cmd_stream_reset_notify(ctx->stream, ctx); >> >> diff --git a/src/gallium/drivers/etnav
[Mesa-dev] [PATCH v4] etnaviv: fix resource usage tracking across different pipe_context's
From: Christian Gmeiner A pipe_resource can be shared by all the pipe_context's hanging off the same pipe_screen. Signed-off-by: Christian Gmeiner Signed-off-by: Marek Vasut To: mesa-dev@lists.freedesktop.org Cc: etna...@lists.freedesktop.org --- Changes from v1 -> v2: - to remove the resource from the used_resources set when it is destroyed Changes from v2 -> v3: - add locking with mtx_*() to resource and screen (Marek) Changes from v3 -> v4: - drop rsc->lock, just use screen->lock for the entire serialization (Marek) - simplify etna_resource_used() flush condition, which also prevents potentially flushing resources twice (Marek) - don't remove resouces from screen->used_resources in etna_cmd_stream_reset_notify(), they may still be used in other contexts and may need flushing there later on (Marek) --- src/gallium/drivers/etnaviv/etnaviv_context.c | 26 +- src/gallium/drivers/etnaviv/etnaviv_context.h | 3 -- .../drivers/etnaviv/etnaviv_resource.c| 52 +++ .../drivers/etnaviv/etnaviv_resource.h| 8 +-- src/gallium/drivers/etnaviv/etnaviv_screen.c | 12 + src/gallium/drivers/etnaviv/etnaviv_screen.h | 6 +++ 6 files changed, 78 insertions(+), 29 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index 3038d21..2f8cae8 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -36,6 +36,7 @@ #include "etnaviv_query.h" #include "etnaviv_query_hw.h" #include "etnaviv_rasterizer.h" +#include "etnaviv_resource.h" #include "etnaviv_screen.h" #include "etnaviv_shader.h" #include "etnaviv_state.h" @@ -329,7 +330,8 @@ static void etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv) { struct etna_context *ctx = priv; - struct etna_resource *rsc, *rsc_tmp; + struct etna_screen *screen = ctx->screen; + struct set_entry *entry; etna_set_state(stream, VIVS_GL_API_MODE, VIVS_GL_API_MODE_OPENGL); etna_set_state(stream, VIVS_GL_VERTEX_ELEMENT_CONFIG, 0x0001); @@ -384,16 +386,18 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv) ctx->dirty = ~0L; ctx->dirty_sampler_views = ~0L; - /* go through all the used resources and clear their status flag */ - LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, >used_resources, list) - { - debug_assert(rsc->status != 0); - rsc->status = 0; - rsc->pending_ctx = NULL; - list_delinit(>list); - } + /* +* Go through all _resources_ associated with this _screen_, pending +* in this _context_ and mark them as not pending in this _context_ +* anymore, since they were just flushed. +*/ + mtx_lock(>lock); + set_foreach(screen->used_resources, entry) { + struct etna_resource *rsc = (struct etna_resource *)entry->key; - assert(LIST_IS_EMPTY(>used_resources)); + _mesa_set_remove_key(rsc->pending_ctx, ctx); + } + mtx_unlock(>lock); } static void @@ -437,8 +441,6 @@ etna_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) /* need some sane default in case state tracker doesn't set some state: */ ctx->sample_mask = 0x; - list_inithead(>used_resources); - /* Set sensible defaults for state */ etna_cmd_stream_reset_notify(ctx->stream, ctx); diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.h b/src/gallium/drivers/etnaviv/etnaviv_context.h index 584caa7..eff0a23 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.h +++ b/src/gallium/drivers/etnaviv/etnaviv_context.h @@ -136,9 +136,6 @@ struct etna_context { uint32_t prim_hwsupport; struct primconvert_context *primconvert; - /* list of resources used by currently-unsubmitted renders */ - struct list_head used_resources; - struct slab_child_pool transfer_pool; struct blitter_context *blitter; diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c index 3808c29..46ab849 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c @@ -33,6 +33,7 @@ #include "etnaviv_screen.h" #include "etnaviv_translate.h" +#include "util/hash_table.h" #include "util/u_inlines.h" #include "util/u_memory.h" @@ -275,7 +276,6 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout, rsc->halign = halign; pipe_reference_init(>base.reference, 1); - list_inithead(>list); size = setup_miptree(rsc, paddingX, paddingY, msaa_xscale, msaa_yscale); @@ -296,6 +296,11 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout, memset(map, 0, size); } + rsc->pending_ctx = _mesa_set_create(NULL, _mesa_ha
[Mesa-dev] [PATCH v3] etnaviv: fix resource usage tracking across different pipe_context's
From: Christian Gmeiner A pipe_resource can be shared by all the pipe_context's hanging off the same pipe_screen. Signed-off-by: Christian Gmeiner Signed-off-by: Marek Vasut To: mesa-dev@lists.freedesktop.org Cc: etna...@lists.freedesktop.org --- Changes from v1 -> v2: - to remove the resource from the used_resources set when it is destroyed Changes from v2 -> v3: - add locking with mtx_*() to resource and screen (Marek) --- src/gallium/drivers/etnaviv/etnaviv_context.c | 25 src/gallium/drivers/etnaviv/etnaviv_context.h | 3 - .../drivers/etnaviv/etnaviv_resource.c| 58 +++ .../drivers/etnaviv/etnaviv_resource.h| 9 +-- src/gallium/drivers/etnaviv/etnaviv_screen.c | 10 src/gallium/drivers/etnaviv/etnaviv_screen.h | 6 ++ 6 files changed, 82 insertions(+), 29 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index 3038d21..abb2652 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -36,6 +36,7 @@ #include "etnaviv_query.h" #include "etnaviv_query_hw.h" #include "etnaviv_rasterizer.h" +#include "etnaviv_resource.h" #include "etnaviv_screen.h" #include "etnaviv_shader.h" #include "etnaviv_state.h" @@ -329,7 +330,8 @@ static void etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv) { struct etna_context *ctx = priv; - struct etna_resource *rsc, *rsc_tmp; + struct etna_screen *screen = ctx->screen; + struct set_entry *entry; etna_set_state(stream, VIVS_GL_API_MODE, VIVS_GL_API_MODE_OPENGL); etna_set_state(stream, VIVS_GL_VERTEX_ELEMENT_CONFIG, 0x0001); @@ -384,16 +386,17 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv) ctx->dirty = ~0L; ctx->dirty_sampler_views = ~0L; - /* go through all the used resources and clear their status flag */ - LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, >used_resources, list) - { - debug_assert(rsc->status != 0); - rsc->status = 0; - rsc->pending_ctx = NULL; - list_delinit(>list); - } + /* go through all the used context resources and clear their status flag */ + mtx_lock(>lock); + set_foreach(screen->used_resources, entry) { + struct etna_resource *rsc = (struct etna_resource *)entry->key; - assert(LIST_IS_EMPTY(>used_resources)); + mtx_lock(>lock); + _mesa_set_remove_key(rsc->pending_ctx, ctx); + _mesa_set_remove(screen->used_resources, entry); + mtx_unlock(>lock); + } + mtx_unlock(>lock); } static void @@ -437,8 +440,6 @@ etna_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) /* need some sane default in case state tracker doesn't set some state: */ ctx->sample_mask = 0x; - list_inithead(>used_resources); - /* Set sensible defaults for state */ etna_cmd_stream_reset_notify(ctx->stream, ctx); diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.h b/src/gallium/drivers/etnaviv/etnaviv_context.h index 584caa7..eff0a23 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.h +++ b/src/gallium/drivers/etnaviv/etnaviv_context.h @@ -136,9 +136,6 @@ struct etna_context { uint32_t prim_hwsupport; struct primconvert_context *primconvert; - /* list of resources used by currently-unsubmitted renders */ - struct list_head used_resources; - struct slab_child_pool transfer_pool; struct blitter_context *blitter; diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c index 3808c29..6b6d245 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c @@ -33,6 +33,7 @@ #include "etnaviv_screen.h" #include "etnaviv_translate.h" +#include "util/hash_table.h" #include "util/u_inlines.h" #include "util/u_memory.h" @@ -275,7 +276,6 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout, rsc->halign = halign; pipe_reference_init(>base.reference, 1); - list_inithead(>list); size = setup_miptree(rsc, paddingX, paddingY, msaa_xscale, msaa_yscale); @@ -296,6 +296,12 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout, memset(map, 0, size); } + mtx_init(>lock, mtx_recursive); + rsc->pending_ctx = _mesa_set_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); + if (!rsc->pending_ctx) + goto free_rsc; + return >base; free_rsc: @@ -455,8 +461,17 @@ etna_resource_changed(struct pipe_screen *pscreen, struct pipe_resource *prsc) static void etna_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *prsc) { + struct
Re: [Mesa-dev] [PATCH v2] etnaviv: fix resource usage tracking across different pipe_context's
t; > #include "util/os_time.h" > #include "util/u_math.h" > #include "util/u_memory.h" > @@ -82,6 +83,8 @@ etna_screen_destroy(struct pipe_screen *pscreen) > { > struct etna_screen *screen = etna_screen(pscreen); > > + _mesa_set_destroy(screen->used_resources, NULL); > + > if (screen->perfmon) > etna_perfmon_del(screen->perfmon); > > @@ -1026,6 +1029,11 @@ etna_screen_create(struct etna_device *dev, struct > etna_gpu *gpu, > if (screen->drm_version >= ETNA_DRM_VERSION_PERFMON) >etna_pm_query_setup(screen); > > + screen->used_resources = _mesa_set_create(NULL, _mesa_hash_pointer, > + _mesa_key_pointer_equal); > + if (!screen->used_resources) > + goto fail; > + > return pscreen; > > fail: > diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.h > b/src/gallium/drivers/etnaviv/etnaviv_screen.h > index bffd4b6ef94..3f1175fce0e 100644 > --- a/src/gallium/drivers/etnaviv/etnaviv_screen.h > +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.h > @@ -34,6 +34,7 @@ > #include "os/os_thread.h" > #include "pipe/p_screen.h" > #include "renderonly/renderonly.h" > +#include "util/set.h" > #include "util/slab.h" > #include "util/u_dynarray.h" > > @@ -80,6 +81,9 @@ struct etna_screen { > struct etna_specs specs; > > uint32_t drm_version; > + > + /* set of resources used by currently-unsubmitted renders */ > + struct set *used_resources; > }; > > static inline struct etna_screen * > -- Best regards, Marek Vasut ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH] etnaviv: fix resource usage tracking across different pipe_context's
On 12/11/2018 10:40 PM, Lukas F. Hartmann wrote: > Hi, Hi, > I tested the patch on i.MX6QP with: > Linux reform 4.20.0-rc2-00133-g1ce80e0fe98e-dirty #10 SMP Mon Nov 26 > 02:02:42 CET 2018 armv7l GNU/Linux > > Running a recent Xorg built from source with modesetting driver and > etnaviv. > > I was getting segfaults after a few seconds of usage and tracked them > down to a corrupt pointer (probably use-after-free): > > http://dump.mntmn.com/marexpatch-trace1.txt.html > > After looking at your patch for a while I came up with this addition > (last line) in etna_resource.c, to remove the resource from the > used_resources set when it is destroyed. > > @@ -464,6 +469,9 @@ etna_resource_destroy(struct pipe_screen *pscreen, > struct pipe_resource *prsc) { > struct etna_resource *rsc = etna_resource(prsc); > > + _mesa_set_destroy(rsc->pending_ctx, NULL); > + _mesa_set_remove_key(etna_screen(pscreen)->used_resources, rsc); > > I've been running with this version for a few days and it seems stable. > The patch seems to do its job (tested qupzilla and qutebrowser, no > more corrupted tiles). Just sometimes an occassional black tile shows > up. So something is still up, but the patch is a perceived improvement. Nice, thanks. Lemme try that here too. -- Best regards, Marek Vasut ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] etnaviv: fix resource usage tracking across different pipe_context's
From: Christian Gmeiner A pipe_resource can be shared by all the pipe_context's hanging off the same pipe_screen. Signed-off-by: Christian Gmeiner --- src/gallium/drivers/etnaviv/etnaviv_context.c | 21 - src/gallium/drivers/etnaviv/etnaviv_context.h | 3 -- .../drivers/etnaviv/etnaviv_resource.c| 44 ++- .../drivers/etnaviv/etnaviv_resource.h| 7 ++- src/gallium/drivers/etnaviv/etnaviv_screen.c | 8 src/gallium/drivers/etnaviv/etnaviv_screen.h | 4 ++ 6 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index 3038d210e10..28c6b8fab84 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -36,6 +36,7 @@ #include "etnaviv_query.h" #include "etnaviv_query_hw.h" #include "etnaviv_rasterizer.h" +#include "etnaviv_resource.h" #include "etnaviv_screen.h" #include "etnaviv_shader.h" #include "etnaviv_state.h" @@ -329,7 +330,8 @@ static void etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv) { struct etna_context *ctx = priv; - struct etna_resource *rsc, *rsc_tmp; + struct etna_screen *screen = ctx->screen; + struct set_entry *entry; etna_set_state(stream, VIVS_GL_API_MODE, VIVS_GL_API_MODE_OPENGL); etna_set_state(stream, VIVS_GL_VERTEX_ELEMENT_CONFIG, 0x0001); @@ -384,16 +386,13 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv) ctx->dirty = ~0L; ctx->dirty_sampler_views = ~0L; - /* go through all the used resources and clear their status flag */ - LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, >used_resources, list) - { - debug_assert(rsc->status != 0); - rsc->status = 0; - rsc->pending_ctx = NULL; - list_delinit(>list); - } + /* go through all the used context resources and clear their status flag */ + set_foreach(screen->used_resources, entry) { + struct etna_resource *rsc = (struct etna_resource *)entry->key; - assert(LIST_IS_EMPTY(>used_resources)); + _mesa_set_remove_key(rsc->pending_ctx, ctx); + _mesa_set_remove(screen->used_resources, entry); + } } static void @@ -437,8 +436,6 @@ etna_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) /* need some sane default in case state tracker doesn't set some state: */ ctx->sample_mask = 0x; - list_inithead(>used_resources); - /* Set sensible defaults for state */ etna_cmd_stream_reset_notify(ctx->stream, ctx); diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.h b/src/gallium/drivers/etnaviv/etnaviv_context.h index 584caa77080..eff0a2378c7 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.h +++ b/src/gallium/drivers/etnaviv/etnaviv_context.h @@ -136,9 +136,6 @@ struct etna_context { uint32_t prim_hwsupport; struct primconvert_context *primconvert; - /* list of resources used by currently-unsubmitted renders */ - struct list_head used_resources; - struct slab_child_pool transfer_pool; struct blitter_context *blitter; diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c index 7fd374ae23d..166f2a4f71d 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c @@ -33,6 +33,7 @@ #include "etnaviv_screen.h" #include "etnaviv_translate.h" +#include "util/hash_table.h" #include "util/u_inlines.h" #include "util/u_memory.h" @@ -275,7 +276,6 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout, rsc->halign = halign; pipe_reference_init(>base.reference, 1); - list_inithead(>list); size = setup_miptree(rsc, paddingX, paddingY, msaa_xscale, msaa_yscale); @@ -296,6 +296,11 @@ etna_resource_alloc(struct pipe_screen *pscreen, unsigned layout, memset(map, 0, size); } + rsc->pending_ctx = _mesa_set_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); + if (!rsc->pending_ctx) + goto free_rsc; + return >base; free_rsc: @@ -457,6 +462,8 @@ etna_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *prsc) { struct etna_resource *rsc = etna_resource(prsc); + _mesa_set_destroy(rsc->pending_ctx, NULL); + if (rsc->bo) etna_bo_del(rsc->bo); @@ -466,8 +473,6 @@ etna_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *prsc) if (rsc->scanout) renderonly_scanout_destroy(rsc->scanout, etna_screen(pscreen)->ro); - list_delinit(>list); - pipe_resource_reference(>texture, NULL); pipe_resource_reference(>external, NULL); @@ -501,7 +506,6 @@ etna_resource_from_handle(struct pipe_screen *pscreen, *prsc = *tmpl; pipe_reference_init(>reference, 1); - list_inithead(>list); prsc->screen = pscreen; rsc->bo = etna_screen_bo_from_handle(pscreen,