<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Oct 27, 2016 at 2:47 PM, Timothy Arceri <span dir="ltr"><<a href="mailto:timothy.arceri@collabora.com" target="_blank">timothy.arceri@collabora.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Thu, 2016-10-27 at 13:57 -0700, Jason Ekstrand wrote:<br>
> On Thu, Oct 27, 2016 at 1:30 PM, Eric Anholt <<a href="mailto:eric@anholt.net">eric@anholt.net</a>> wrote:<br>
> > Fixes use-after-free-caused segfaults in the tgsi_to_nir() path.<br>
> > ---<br>
> ><br>
> > I don't like the boolean I added here, any better plans, though?  I<br>
> > haven't fully piglited this, but it's enough to get gears to not<br>
> > crash<br>
> > on master (it at least touches the GLSL to NIR and TGSI to NIR<br>
> > paths.)<br>
><br>
> I don't either. Let's consider the options...<br>
><br>
> Would it be better to simply make nir_shader_create() always allocate<br>
> a shader_info and just memcpy old one if provided or zero it out if<br>
> no shader info is provided?  Having a pointer which may or may not be<br>
> parented to the nir_shader is a disaster waiting to happen.  Since<br>
> the one provided to nir_shader_create() isn't required to be<br>
> ralloc'd, we can't even use ralloc_parent() to check.<br>
><br>
> Another option would be to say that the NIR shader doesn't own the<br>
> info ever. Maybe even get rid of the shader_info pointer in<br>
> nir_shader.  It would probably mean manually passing the shader_info<br>
> around a few more places, but it would work.<br>
><br>
> Tim, thoughts?<br>
<br>
</span>Hi guys,<br>
<br>
Options:<br>
<br>
1) Make nir_shader_create() always allocate a shader_info and just<br>
<span class="">memcpy old one if provided or zero it out if no shader info is<br>
</span>provided.<br>
<br>
2) Detach shader_info from nir_shader. Downside we need to pass both<br>
around. This looks like it will be most painful in Vulkan were<br>
nir_shader seems to be the highest level stucture we pass around and we<br>
don't have something like gl_program in GLSL where we can get access to<br>
them both.<br></blockquote><div><br></div><div>I don't think it's all that difficult in Vulkan.  We just need to make anv_shader_compile_to_nir and anv_pipeline_compile take a shader_info.  We already do this for prog_data so it's really not a big deal.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
3) Allocate the info to attach to the shader being produced, and then<br>
assert that nir_shader_create() always gets an info.<br>
<br>
4) Switch the order. Have shader_info (we could rename it if that would<br>
help make more sense) contain a pointer to nir_shader. This is how we<br>
do things in GLSL IR, gl_program already contains a pointer to nir.<br>
This way the shader_info is created and managed by the implementation<br>
rather than nir.<br>
<br>
Personally I think I like option 4. I suggested this originally but<br>
Jason wasn't sold at the time. However looking at the problem again<br>
this make the most sense to me.<br>
<br>
What do you guys think?</blockquote><div><br></div><div>Without knowing for 100% sure what the code would look like, I think my preference would be (2).  It would let us keep the shader_info struct in gl_program on GL and do whatever we want in Vulkan/blorp.  One of the things I don't like today is that we have this shader_info in the shader which may or may not be correct depending on where it came from and whether or not we've run nir_gather_info.  If, instead, nir_gather_info is simply a pass that takes a nir_shader and a shader_info and fills out the shader_info, the data flow is a bit more clear.<br><br></div><div>(1) or (3) are fairly simple but they seem fairly fragile to me and I don't think I like them long-term.  I'm still not sold on (4) because I don't think that having a struct which just wraps up two other structs really gains us anything beyond having them separate.  I think I could be ok with it, but I'm still not sold.  Unfortunately, both (3) and (4) are going to require a decent bit of typing.<br><br></div><div>Anholt?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <br><div class="HOEnZb"><div class="h5">
>  <br>
> >  src/compiler/nir/nir.c       |  2 ++<br>
> >  src/compiler/nir/nir.h       |  2 ++<br>
> >  src/compiler/nir/nir_clone.c | 14 +++++++++++++-<br>
> >  src/compiler/nir/nir_sweep.c |  3 +++<br>
> >  4 files changed, 20 insertions(+), 1 deletion(-)<br>
> ><br>
> > diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c<br>
> > index 09aad57e87f8..1448837d8fd1 100644<br>
> > --- a/src/compiler/nir/nir.c<br>
> > +++ b/src/compiler/nir/nir.c<br>
> > @@ -45,6 +45,8 @@ nir_shader_create(void *mem_ctx,<br>
> >     shader->options = options;<br>
> ><br>
> >     shader->info = si ? si : rzalloc(shader, shader_info);<br>
> > +   if (!si)<br>
> > +      shader->shader_owns_info = true;<br>
> ><br>
> >     exec_list_make_empty(&shader-><wbr>functions);<br>
> >     exec_list_make_empty(&shader-><wbr>registers);<br>
> > diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h<br>
> > index 92647632462b..7dde8bd4ebd6 100644<br>
> > --- a/src/compiler/nir/nir.h<br>
> > +++ b/src/compiler/nir/nir.h<br>
> > @@ -1807,6 +1807,8 @@ typedef struct nir_shader {<br>
> >     /** Various bits of compile-time information about a given<br>
> > shader */<br>
> >     struct shader_info *info;<br>
> ><br>
> > +   bool shader_owns_info;<br>
> > +<br>
> >     /** list of global variables in the shader (nir_variable) */<br>
> >     struct exec_list globals;<br>
> ><br>
> > diff --git a/src/compiler/nir/nir_clone.c<br>
> > b/src/compiler/nir/nir_clone.c<br>
> > index 9f3bd7ff6baa..cd6063325274 100644<br>
> > --- a/src/compiler/nir/nir_clone.c<br>
> > +++ b/src/compiler/nir/nir_clone.c<br>
> > @@ -710,7 +710,19 @@ nir_shader_clone(void *mem_ctx, const<br>
> > nir_shader *s)<br>
> >     clone_reg_list(&state, &ns->registers, &s->registers);<br>
> >     ns->reg_alloc = s->reg_alloc;<br>
> ><br>
> > -   ns->info = s->info;<br>
> > +   if (s->shader_owns_info) {<br>
> > +      ns->info = ralloc(ns, struct shader_info);<br>
> > +      *ns->info = *s->info;<br>
> > +      ns->shader_owns_info = true;<br>
> > +   } else {<br>
> > +      ns->info = s->info;<br>
> > +   }<br>
> > +<br>
> > +   /* XXX: Note that for !shader_owns_info, we're making the info<br>
> > pointed to<br>
> > +    * by s have data owned by ns, so if ns is freed before s then<br>
> > we might<br>
> > +    * use-after-free the name/label.  We should probably have<br>
> > name/label be<br>
> > +    * owned by the info.<br>
> > +    */<br>
> >     ns->info->name = ralloc_strdup(ns, ns->info->name);<br>
> >     if (ns->info->label)<br>
> >        ns->info->label = ralloc_strdup(ns, ns->info->label);<br>
> > diff --git a/src/compiler/nir/nir_sweep.c<br>
> > b/src/compiler/nir/nir_sweep.c<br>
> > index faf696d6decd..43664d4d5b96 100644<br>
> > --- a/src/compiler/nir/nir_sweep.c<br>
> > +++ b/src/compiler/nir/nir_sweep.c<br>
> > @@ -153,6 +153,9 @@ nir_sweep(nir_shader *nir)<br>
> >     /* First, move ownership of all the memory to a temporary<br>
> > context; assume dead. */<br>
> >     ralloc_adopt(rubbish, nir);<br>
> ><br>
> > +   if (nir->shader_owns_info)<br>
> > +      ralloc_steal(nir, nir->info);<br>
> > +<br>
> >     ralloc_steal(nir, (char *)nir->info->name);<br>
> >     if (nir->info->label)<br>
> >        ralloc_steal(nir, (char *)nir->info->label);<br>
> > --<br>
> > 2.10.1<br>
> ><br>
> > ______________________________<wbr>_________________<br>
> > mesa-dev mailing list<br>
> > <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> > <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
> ><br>
><br>
> ______________________________<wbr>_________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</div></div></blockquote></div><br></div></div>