<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 1, 2016 at 5:43 PM, Francisco Jerez <span dir="ltr"><<a href="mailto:currojerez@riseup.net" target="_blank">currojerez@riseup.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> writes:<br>
<br>
> 3 and 4 are<br>
><br>
> Cc: "12.0 11.1 11.2" <<a href="mailto:mesa-stable@lists.freedesktop.org">mesa-stable@lists.freedesktop.org</a>><br>
<br>
</span>Hmm, I'll cc PATCH 2 to mesa-stable too since technically it also fixes<br>
a bug.  PATCH 1 shouldn't make much of a difference though.<br>
<span class=""><br>
> Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br>
><br>
> I did look over 3 fairly carefully.<br>
><br>
</span>Thanks.<br>
<span class=""><br>
> It's worth noting that I think we have some double-pipe-controls that could<br>
> probably be put together now.  Not sure that we actually want to do that<br>
> though.<br>
<br>
</span>I don't think it matters much, usually it's nearly the same amount of<br>
lines of code to do it as one call to brw_emit_pipe_control_flush() or<br>
as two, both approaches are functionally equivalent, and doing it<br>
explicitly as two brw_emit_pipe_control_flush() calls makes it clear to<br>
the reader that the read cache invalidations are supposed to happen<br>
after the write caches are flushed.  In some places though it's really<br>
convenient to be able to put all cache bits for which coherency is<br>
required into a single bitfield and have brw_emit_pipe_control_flush()<br>
figure out whether the command needs to be split (e.g.<br>
brw_memory_barrier()).<br></blockquote><div><br></div><div>That sounds reasonable.  I wasn't even really sure about it myself but thought it would be worth a few words of discussion.  Sounds like we're on the same page.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">
> --Jason<br>
><br>
> On Thu, Jun 30, 2016 at 10:07 PM, Francisco Jerez <<a href="mailto:currojerez@riseup.net">currojerez@riseup.net</a>><br>
> wrote:<br>
><br>
>> This hardware race condition has caused problems several times already<br>
>> (see "i965: Fix cache pollution race during L3 partitioning set-up.",<br>
>> "i965: Fix brw_render_cache_set_check_flush's PIPE_CONTROLs." and<br>
>> "i965: intel_texture_barrier reimplemented").  The problem is that<br>
>> whenever we attempt to both flush and invalidate multiple caches with<br>
>> a single pipe control command the flush and invalidation happen in<br>
>> reverse order, so the contents flushed from the R/W caches aren't<br>
>> guaranteed to become visible from the invalidated caches after the<br>
>> PIPE_CONTROL command completes execution if some concurrent rendering<br>
>> workload happened to pollute any of the invalidated R/O caches in the<br>
>> short window of time between the invalidation and flush.<br>
>><br>
>> This makes sure that brw_emit_pipe_control_flush() has the effect<br>
>> expected by most callers of making the contents flushed from any R/W<br>
>> caches visible from the invalidated R/O caches.<br>
>> ---<br>
>>  src/mesa/drivers/dri/i965/brw_pipe_control.c | 18 ++++++++++++++++++<br>
>>  src/mesa/drivers/dri/i965/intel_reg.h        |  9 +++++++++<br>
>>  2 files changed, 27 insertions(+)<br>
>><br>
>> diff --git a/src/mesa/drivers/dri/i965/brw_pipe_control.c<br>
>> b/src/mesa/drivers/dri/i965/brw_pipe_control.c<br>
>> index 14a8f7c..05e8c05 100644<br>
>> --- a/src/mesa/drivers/dri/i965/brw_pipe_control.c<br>
>> +++ b/src/mesa/drivers/dri/i965/brw_pipe_control.c<br>
>> @@ -96,6 +96,24 @@ gen7_cs_stall_every_four_pipe_controls(struct<br>
>> brw_context *brw, uint32_t flags)<br>
>>  void<br>
>>  brw_emit_pipe_control_flush(struct brw_context *brw, uint32_t flags)<br>
>>  {<br>
>> +   if (brw->gen >= 6 &&<br>
>> +       (flags & PIPE_CONTROL_CACHE_FLUSH_BITS) &&<br>
>> +       (flags & PIPE_CONTROL_CACHE_INVALIDATE_BITS)) {<br>
>> +      /* A pipe control command with flush and invalidate bits set<br>
>> +       * simultaneously is an inherently racy operation on Gen6+ if the<br>
>> +       * contents of the flushed caches were intended to become visible<br>
>> from<br>
>> +       * any of the invalidated caches.  Split it in two PIPE_CONTROLs,<br>
>> the<br>
>> +       * first one should stall the pipeline to make sure that the<br>
>> flushed R/W<br>
>> +       * caches are coherent with memory once the specified R/O caches are<br>
>> +       * invalidated.  On pre-Gen6 hardware the (implicit) R/O cache<br>
>> +       * invalidation seems to happen at the bottom of the pipeline<br>
>> together<br>
>> +       * with any write cache flush, so this shouldn't be a concern.<br>
>> +       */<br>
>> +      brw_emit_pipe_control_flush(brw, (flags &<br>
>> PIPE_CONTROL_CACHE_FLUSH_BITS) |<br>
>> +                                       PIPE_CONTROL_CS_STALL);<br>
>> +      flags &= ~(PIPE_CONTROL_CACHE_FLUSH_BITS | PIPE_CONTROL_CS_STALL);<br>
>> +   }<br>
>> +<br>
>>     if (brw->gen >= 8) {<br>
>>        if (brw->gen == 8)<br>
>>           gen8_add_cs_stall_workaround_bits(&flags);<br>
>> diff --git a/src/mesa/drivers/dri/i965/intel_reg.h<br>
>> b/src/mesa/drivers/dri/i965/intel_reg.h<br>
>> index 95365fe..7a82be4 100644<br>
>> --- a/src/mesa/drivers/dri/i965/intel_reg.h<br>
>> +++ b/src/mesa/drivers/dri/i965/intel_reg.h<br>
>> @@ -134,6 +134,15 @@<br>
>>  #define PIPE_CONTROL_PPGTT_WRITE       (0 << 2)<br>
>>  #define PIPE_CONTROL_GLOBAL_GTT_WRITE  (1 << 2)<br>
>><br>
>> +#define PIPE_CONTROL_CACHE_FLUSH_BITS \<br>
>> +   (PIPE_CONTROL_DEPTH_CACHE_FLUSH | PIPE_CONTROL_DATA_CACHE_FLUSH | \<br>
>> +    PIPE_CONTROL_RENDER_TARGET_FLUSH)<br>
>> +<br>
>> +#define PIPE_CONTROL_CACHE_INVALIDATE_BITS \<br>
>> +   (PIPE_CONTROL_STATE_CACHE_INVALIDATE |<br>
>> PIPE_CONTROL_CONST_CACHE_INVALIDATE | \<br>
>> +    PIPE_CONTROL_VF_CACHE_INVALIDATE |<br>
>> PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | \<br>
>> +    PIPE_CONTROL_INSTRUCTION_INVALIDATE)<br>
>> +<br>
>>  /** @} */<br>
>><br>
>>  #define XY_SETUP_BLT_CMD               (CMD_2D | (0x01 << 22))<br>
>> --<br>
>> 2.9.0<br>
>><br>
>><br>
</div></div></blockquote></div><br></div></div>