Re: Section 9.5: Nobody expects the Spanish Acquisition!

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> The tag is the address, the pointer is just a variable that holds that tag.
Sorry, I re-read what I wrote and it's not accurate. The tag *is* the
pointer variable, the address it holds is the version.

--Elad

On Mon, 3 Jan 2022 at 19:49, Elad Lahav <e2lahav@xxxxxxxxx> wrote:
>
> Hi Paul,
>
> On 2022-01-03 7:05 p.m., Paul E. McKenney wrote:
> > First, apologies for the delay.  And happy new year!
> No problem! I did not expect you to spend time on this during the
> holidays. Hope you had a good hike on Christmas eve. I would have liked
> to go hiking as well, but the combination of -20C and a raging pandemic
> restrict me to the treadmill.
>
> Your response makes me think that I need to explain better what I am
> trying to do here. Reading section 9.5 it is not always clear to me what
> constitutes a description of RCU and what a description of "RCU in the
> Linux kernel". I decided to try and come up with a more abstract
> description using the code I attached. It may be just a straw man, but
> at least it gives us something to point at while discussing (which I
> guess is a redundant definition of a "straw man"...).
>
> > You lost me here.  How is the address of a data structure different
> > than a pointer?  Conceptually, from a high-level-language viewpoint,
> > sure, I can see it (not that I always like it, pointer zap being a prime
> > offender), but at the machine level I do not.
> I'm just trying to correlate the "tag" nomenclature with the way the
> Linux kernel RCU implementation works. I believe that this
> implementation fits within the abstract code I wrote, relying on the
> heap to provide versioned data by doing its job, i.e., never return a
> version (address) that has not been released (freed). The tag is the
> address, the pointer is just a variable that holds that tag.
>
> > I agree that there is no need for acquire semantics in the common
> > case.  But care really is required.
> >
> > First, compiler optimizations can sometimes break the dependency,
> > first by value-substitution optimizations:
> >
> >       struct foo *gfp; // Assume non-NULL after initialization
> >       struct foo default_foo;
> >
> >       int do_a_foo(struct foo *fp)
> >       {
> >               return munge_it(fp->a);
> >       }
> >
> > The compiler (presumably in conjunction with feedback from a profiled
> > run) might convert this to:
> >
> >       int do_a_foo(struct foo *fp)
> >       {
> >               if (fp == &default_foo)
> >                       return munge_it(default_foo.a);
> >               else
> >                       return munge_it(fp->a);
> >       }
> >
> > This would break the dependency because control dependencies do not
> > order loads.  However, I would not expect compilers to do this in the
> > absence of feedback-directed optimization.
> >
> > Second, and more concerning, things can get even more dicey when one
> > is trying to carry dependencies through integers:
> >
> >       struct foo foo_array[N_FOOS];
> >
> >       int do_a_foo(int i)
> >       {
> >               return munge_it(fp[i].a);
> >       }
> >
> > This actually works well, at least until someone builds with N_FOOS=1,
> > which causes foo_array[] to reference a single element.  At that point,
> > the compiler is within its rights to transform to this:
> >
> >       int do_a_foo(int i)
> >       {
> >               return munge_it(fp[0].a);
> >       }
> >
> > This again breaks the dependency by substituting a constant.  (Note that
> > any non-zero index invokes undefined behavior, legalizing the otherwise
> > inexplicable substitution of the constant zero.)
>
> Excellent, that's what I was looking for! If I understand you correctly,
> in principle acquire semantics *are* required for the reader. It just so
> happens that most implementations can get away without explicit acquire
> semantics due to data or address dependencies, but these need to be
> justified.
>
> > Why is this needed?  What is provided by this that is not covered by
> > rcu_reader_exit(), AKA rcu_read_unlock()?
>
> Just for verbosity's sake. I first wrote it as
> "rcu_reader_exit(latest)", but I felt it wasn't clear what are the
> semantics of such a call. I guess something like
> "rcu_reader_release_and_exit(latest)" could work.
>
> --Elad



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux