Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-11 Thread Radim Krčmář
2017-04-08 15:32-0400, Paolo Bonzini:
> > > Makes sense.  My pitch at the documentation after dropping READ_ONCE():
> > 
> > I'm confused again, I thought you wanted to keep READ_ONCE().
> > 
> > > 
> > >   /*
> > >*  The return value of kvm_request_pending() is implicitly volatile
> > 
> > why is that, actually?

"that" is the return value?
  kvm_request_pending() is 'inline static' so the compiler can prove that
  the function only returns vcpu->requests and that the surrounding code
  doesn't change it, so various optimizations are possible.

Or the implicitly volatile bit?
  We know that vcpu->requests can change at any time without action of the
  execution thread, which makes it volatile, but we don't tell that to the
  compiler, hence implicit.
  
  READ_ONCE(vcpu->requests) is
  
*(volatile unsigned long *)&vcpu->requests
  
  and makes it explicitly volatile.

> > >*  and must be protected from reordering by the caller.
> > >*/
> > 
> > Can we be specific about what that means?  (e.g. must be preceded by a
> > full smp_mb() - or whatever the case is).
> 
> You can play devil's advocate both ways and argue that READ_ONCE is
> better, or that it is unnecessary hence worse.  You can write good
> comments in either case.  That's how I read Radim's message.  But
> I think we all agree on keeping it in the end.

Exactly, I am in favor of READ_ONCE() as I don't like to keep the
compiler informed, just wanted to cover all options, because they are
not that different ... minute details are the hardest to decide. :)
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-08 Thread Paolo Bonzini

> > Makes sense.  My pitch at the documentation after dropping READ_ONCE():
> 
> I'm confused again, I thought you wanted to keep READ_ONCE().
> 
> > 
> >   /*
> >*  The return value of kvm_request_pending() is implicitly volatile
> 
> why is that, actually?
> 
> >*  and must be protected from reordering by the caller.
> >*/
> 
> Can we be specific about what that means?  (e.g. must be preceded by a
> full smp_mb() - or whatever the case is).

You can play devil's advocate both ways and argue that READ_ONCE is
better, or that it is unnecessary hence worse.  You can write good
comments in either case.  That's how I read Radim's message.  But
I think we all agree on keeping it in the end.

> Perhaps we should just let Drew respin at this point, in case he's
> confident about the right path, and then pick up from there?

I agree.

In any case, the memory barrier is the important part, but
adding READ_ONCE is self-documenting and I prefer to have it.

Paolo
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-08 Thread Christoffer Dall
On Fri, Apr 07, 2017 at 03:15:37PM +0200, Radim Krčmář wrote:
> 2017-04-06 16:25+0200, Christoffer Dall:
> > On Wed, Apr 05, 2017 at 10:20:17PM +0200, Radim Krčmář wrote:
> >> 2017-04-05 19:39+0200, Christoffer Dall:
> >> > On Wed, Apr 05, 2017 at 03:10:50PM +0200, Radim Krčmář wrote:
> >> x86 uses KVM_REQ_MCLOCK_INPROGRESS for synchronization between cores and
> >> the use in this series looked very similar.
> >> 
> >> >>   * memory barriers are necessary for correct behavior, see
> >> >>   * Documentation/virtual/kvm/vcpu-requests.rst.
> >> >>   *
> >> >>   * READ_ONCE() is not necessary for correctness, but simplifies
> >> >>   * reasoning by constricting the generated code.
> >> >>   */
> >> >> 
> >> >> I considered READ_ONCE() to be self-documenting. :)
> >> > 
> >> > I realize that I'm probably unusually slow in this whole area, but using
> >> > READ_ONCE() where unnecessary doesn't help my reasoning, but makes me
> >> > wonder which part of this I didn't understand, so I don't seem to agree
> >> > with the statement that it simplifies reasoning.
> >> 
> >> No, I think it is a matter of approach.  When I see a READ_ONCE()
> >> without a comment, I think that the programmer was aware that this
> >> memory can change at any time and was defensive about it.
> > 
> > I think it means that you have to read it exactly once at the exact flow
> > in the code where it's placed.
> 
> The compiler can still reorder surrounding non-volatile code, but
> reading exactly once is the subset of meaning that READ_ONCE() should
> have.  Not assigning it any more meaning sounds good.
> 
> >> I consider this use to simplify future development:
> >> We think now that READ_ONCE() is not needed, but vcpu->requests is still
> >> volatile and future changes in code might make READ_ONCE() necessary.
> >> Preemptively putting READ_ONCE() there saves us thinking or hard-to-find
> >> bugs.
> >> 
> > 
> > I'm always a bit sceptical about such reasoning as I think without a
> > complete understanding of what needs to change when doing changes, we're
> > likely to get it wrong anyway.
> 
> I think we cannot achieve and maintain a complete understanding, so
> getting things wrong is just a matter of time.
> 
> It is almost impossible to break ordering of vcpu->requests, though.
> 
> >> > To me, READ_ONCE() indicates that there's some flow in the code where
> >> > it's essential that the compiler doesn't generate multiple loads, but
> >> > that we only see a momentary single-read snapshot of the value, and this
> >> > doesn't seem to be the case.
> >> 
> >> The compiler can also squash multiple reads together, which is more
> >> dangerous in this case as we would not notice a new requests.  Avoiding
> >> READ_ONCE() requires a better knowledge of the compiler algorithms that
> >> prove which variable can be optimized.
> > 
> > Isn't that covered by the memory barriers that imply compiler barriers
> > that we (will) have between checking the mode and the requests variable?
> 
> It is, asm volatile ("" ::: "memory") is enough.
> 
> The minimal conditions that would require explicit barrier:
>  1) not having vcpu->mode(), because it cannot work without memory
> barriers
>  2) the instruction that disables interrupts doesn't have "memory"
> constraint  (the smp_rmb in between is not necessary here)
> 
> And of course, there would have to be no functions that would contain a
> compiler barrier or their bodies remained unknown in between disabling
> interrupts and checking requests ...
> 
> >> The difference is really minor and I agree that the comment is bad.
> >> The only comment I'm happy with is nothing, though ... even "READ_ONCE()
> >> is not necessary" is wrong as that might change without us noticing.
> > 
> > "READ_ONCE() is not necessary" while actually using READ_ONCE() is a
> > terrible comment because it makes readers just doubt the correctness of
> > the code.
> > 
> > Regardless of whether or not we end up using READ_ONCE(), I think we
> > should document exactly what the requirements are for accessing this
> > variable at this time, i.e. any assumption about preceding barriers or
> > other flows of events that we rely on.
> 
> Makes sense.  My pitch at the documentation after dropping READ_ONCE():

I'm confused again, I thought you wanted to keep READ_ONCE().

> 
>   /*
>*  The return value of kvm_request_pending() is implicitly volatile

why is that, actually?

>*  and must be protected from reordering by the caller.
>*/

Can we be specific about what that means?  (e.g. must be preceded by a
full smp_mb() - or whatever the case is).

Perhaps we should just let Drew respin at this point, in case he's
confident about the right path, and then pick up from there?

Thanks,
-Christoffer
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-08 Thread Christoffer Dall
On Fri, Apr 07, 2017 at 11:33:33PM +0800, Paolo Bonzini wrote:
> 
> 
> On 06/04/2017 23:08, Andrew Jones wrote:
> > My own made-up lingo to state that each time the variable is accessed it
> > must be loaded anew, taken care of by the volatile use in READ_ONCE.  As
> > vcpu->requests can be written by other threads, then I prefer READ_ONCE
> > being used to read it, as it allows me to avoid spending energy convincing
> > myself that the compiler would have emitted a load at that point anyway.
> 
> Also, READ_ONCE without a barrier is really fishy unless it's
> 
>   while (READ_ONCE(x) != 2) {
>   ...
>   }
> 
> or similar, and WRITE_ONCE doesn't even have this exception.  So
> annotating variables accessed by multiple threads with
> READ_ONCE/WRITE_ONCE is generally a good idea.
> 

I'm sorry, I'm confused.  You're saying that it's fishy to use
READ_ONCE() without also having a barrier, but does that imply that if
you have a barrier, you should also have READ_ONCE() ?

In any case, as I hope I've made clear, I'm perfectly fine with having
READ_ONCE(), as long as we make a best effort attempt at describing why
we added it, so even I can understand that later - in the code directly
or in the commit message.

Thanks,
-Christoffer
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-07 Thread Paolo Bonzini


On 06/04/2017 23:08, Andrew Jones wrote:
> My own made-up lingo to state that each time the variable is accessed it
> must be loaded anew, taken care of by the volatile use in READ_ONCE.  As
> vcpu->requests can be written by other threads, then I prefer READ_ONCE
> being used to read it, as it allows me to avoid spending energy convincing
> myself that the compiler would have emitted a load at that point anyway.

Also, READ_ONCE without a barrier is really fishy unless it's

  while (READ_ONCE(x) != 2) {
  ...
  }

or similar, and WRITE_ONCE doesn't even have this exception.  So
annotating variables accessed by multiple threads with
READ_ONCE/WRITE_ONCE is generally a good idea.

Paolo
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-07 Thread Radim Krčmář
2017-04-06 16:25+0200, Christoffer Dall:
> On Wed, Apr 05, 2017 at 10:20:17PM +0200, Radim Krčmář wrote:
>> 2017-04-05 19:39+0200, Christoffer Dall:
>> > On Wed, Apr 05, 2017 at 03:10:50PM +0200, Radim Krčmář wrote:
>> x86 uses KVM_REQ_MCLOCK_INPROGRESS for synchronization between cores and
>> the use in this series looked very similar.
>> 
>> >>   * memory barriers are necessary for correct behavior, see
>> >>   * Documentation/virtual/kvm/vcpu-requests.rst.
>> >>   *
>> >>   * READ_ONCE() is not necessary for correctness, but simplifies
>> >>   * reasoning by constricting the generated code.
>> >>   */
>> >> 
>> >> I considered READ_ONCE() to be self-documenting. :)
>> > 
>> > I realize that I'm probably unusually slow in this whole area, but using
>> > READ_ONCE() where unnecessary doesn't help my reasoning, but makes me
>> > wonder which part of this I didn't understand, so I don't seem to agree
>> > with the statement that it simplifies reasoning.
>> 
>> No, I think it is a matter of approach.  When I see a READ_ONCE()
>> without a comment, I think that the programmer was aware that this
>> memory can change at any time and was defensive about it.
> 
> I think it means that you have to read it exactly once at the exact flow
> in the code where it's placed.

The compiler can still reorder surrounding non-volatile code, but
reading exactly once is the subset of meaning that READ_ONCE() should
have.  Not assigning it any more meaning sounds good.

>> I consider this use to simplify future development:
>> We think now that READ_ONCE() is not needed, but vcpu->requests is still
>> volatile and future changes in code might make READ_ONCE() necessary.
>> Preemptively putting READ_ONCE() there saves us thinking or hard-to-find
>> bugs.
>> 
> 
> I'm always a bit sceptical about such reasoning as I think without a
> complete understanding of what needs to change when doing changes, we're
> likely to get it wrong anyway.

I think we cannot achieve and maintain a complete understanding, so
getting things wrong is just a matter of time.

It is almost impossible to break ordering of vcpu->requests, though.

>> > To me, READ_ONCE() indicates that there's some flow in the code where
>> > it's essential that the compiler doesn't generate multiple loads, but
>> > that we only see a momentary single-read snapshot of the value, and this
>> > doesn't seem to be the case.
>> 
>> The compiler can also squash multiple reads together, which is more
>> dangerous in this case as we would not notice a new requests.  Avoiding
>> READ_ONCE() requires a better knowledge of the compiler algorithms that
>> prove which variable can be optimized.
> 
> Isn't that covered by the memory barriers that imply compiler barriers
> that we (will) have between checking the mode and the requests variable?

It is, asm volatile ("" ::: "memory") is enough.

The minimal conditions that would require explicit barrier:
 1) not having vcpu->mode(), because it cannot work without memory
barriers
 2) the instruction that disables interrupts doesn't have "memory"
constraint  (the smp_rmb in between is not necessary here)

And of course, there would have to be no functions that would contain a
compiler barrier or their bodies remained unknown in between disabling
interrupts and checking requests ...

>> The difference is really minor and I agree that the comment is bad.
>> The only comment I'm happy with is nothing, though ... even "READ_ONCE()
>> is not necessary" is wrong as that might change without us noticing.
> 
> "READ_ONCE() is not necessary" while actually using READ_ONCE() is a
> terrible comment because it makes readers just doubt the correctness of
> the code.
> 
> Regardless of whether or not we end up using READ_ONCE(), I think we
> should document exactly what the requirements are for accessing this
> variable at this time, i.e. any assumption about preceding barriers or
> other flows of events that we rely on.

Makes sense.  My pitch at the documentation after dropping READ_ONCE():

  /*
   *  The return value of kvm_request_pending() is implicitly volatile
   *  and must be protected from reordering by the caller.
   */
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-06 Thread Andrew Jones
On Thu, Apr 06, 2017 at 04:37:51PM +0200, Christoffer Dall wrote:
> > FWIW, I first suggested using READ_ONCE() for the freshness argument,
> 
> What is the 'freshness argument' ?

My own made-up lingo to state that each time the variable is accessed it
must be loaded anew, taken care of by the volatile use in READ_ONCE.  As
vcpu->requests can be written by other threads, then I prefer READ_ONCE
being used to read it, as it allows me to avoid spending energy convincing
myself that the compiler would have emitted a load at that point anyway.

The writes to vcpu->requests always go through bitops, so they're already
also emitting fresh loads before doing their stores.

Thanks,
drew
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-06 Thread Christoffer Dall
Hi Drew,

On Thu, Apr 06, 2017 at 02:02:12PM +0200, Andrew Jones wrote:
> On Wed, Apr 05, 2017 at 10:20:17PM +0200, Radim Krčmář wrote:
> > 2017-04-05 19:39+0200, Christoffer Dall:
> > > On Wed, Apr 05, 2017 at 03:10:50PM +0200, Radim Krčmář wrote:
> > >> 2017-04-04 18:41+0200, Andrew Jones:
> > >> > On Tue, Apr 04, 2017 at 05:30:14PM +0200, Christoffer Dall wrote:
> > >> >> On Fri, Mar 31, 2017 at 06:06:50PM +0200, Andrew Jones wrote:
> > >> >> > From: Radim Krčmář 
> > >> >> > 
> > >> >> > A first step in vcpu->requests encapsulation.
> > >> >> 
> > >> >> Could we have a note here on why we need to access vcpu->requests 
> > >> >> using
> > >> >> READ_ONCE now?
> > >> > 
> > >> > Sure, maybe we should put the note as a comment above the read in
> > >> > kvm_request_pending().  Something like
> > >> > 
> > >> >  /*
> > >> >   * vcpu->requests reads may appear in sequences that have strict
> > >> >   * data or control dependencies.  Use READ_ONCE() to ensure the
> > >> >   * compiler does not do anything that breaks the required ordering.
> > >> >   */
> > >> > 
> > >> > Radim?
> > >> 
> > >> Uses of vcpu->requests should already have barriers that take care of
> > >> the ordering.  I think the main reason for READ_ONCE() is to tell
> > >> programmers that requests are special, but predictable.
> > > 
> > > I don't know what to do with "special, but predictable", unfortunately.
> > > In fact, I don't even think I know what you mean.
> > 
> > With "special" to stand for the idea that vcpu->requests can change
> > outside of the current execution thread.  Letting the programmer assume
> > additional guarantees makes the generated code and resulting behavior
> > more predictable.
> > 
> > >> READ_ONCE() is not necessary in any use I'm aware of, but there is no
> > >> harm in telling the compiler that vcpu->requests are what we think they
> > >> are ...
> > > 
> > > Hmmm, I'm equally lost.
> > 
> > vcpu->requests are volatile, so we need to assume that they can change
> > at any moment when using them.
> > 
> > I would prefer if vcpu->requests were of an atomic type and READ_ONCE()
> > is about as close we can get without a major overhaul.
> > 
> > >> 
> > >>  /*
> > >>   * vcpu->requests are a lockless synchronization mechanism, where
> > > 
> > > is the requests a synchronization mechanism?  I think of it more as a
> > > cross-thread communication protocol.
> > 
> > Partly, synchronization is too restrictive and communication seems too
> > generic, but probably still better.  No idea how to shortly describe the
> > part of vcpu->requests that prevents VM entry and that setting a request
> > kicks VM out of guest mode.
> > 
> > x86 uses KVM_REQ_MCLOCK_INPROGRESS for synchronization between cores and
> > the use in this series looked very similar.
> > 
> > >>   * memory barriers are necessary for correct behavior, see
> > >>   * Documentation/virtual/kvm/vcpu-requests.rst.
> > >>   *
> > >>   * READ_ONCE() is not necessary for correctness, but simplifies
> > >>   * reasoning by constricting the generated code.
> > >>   */
> > >> 
> > >> I considered READ_ONCE() to be self-documenting. :)
> > > 
> > > I realize that I'm probably unusually slow in this whole area, but using
> > > READ_ONCE() where unnecessary doesn't help my reasoning, but makes me
> > > wonder which part of this I didn't understand, so I don't seem to agree
> > > with the statement that it simplifies reasoning.
> > 
> > No, I think it is a matter of approach.  When I see a READ_ONCE()
> > without a comment, I think that the programmer was aware that this
> > memory can change at any time and was defensive about it.
> > 
> > I consider this use to simplify future development:
> > We think now that READ_ONCE() is not needed, but vcpu->requests is still
> > volatile and future changes in code might make READ_ONCE() necessary.
> > Preemptively putting READ_ONCE() there saves us thinking or hard-to-find
> > bugs.
> > 
> > > Really, if there is no reason to use it, I don't think we should use it.
> > 
> > I am leaning towards READ_ONCE() as the default for implicitly volatile
> > memory, but commenting why we didn't have to use READ_ONCE() sounds good
> > too.
> > 
> > > To me, READ_ONCE() indicates that there's some flow in the code where
> > > it's essential that the compiler doesn't generate multiple loads, but
> > > that we only see a momentary single-read snapshot of the value, and this
> > > doesn't seem to be the case.
> > 
> > The compiler can also squash multiple reads together, which is more
> > dangerous in this case as we would not notice a new requests.  Avoiding
> > READ_ONCE() requires a better knowledge of the compiler algorithms that
> > prove which variable can be optimized.
> > 
> > The difference is really minor and I agree that the comment is bad.
> > The only comment I'm happy with is nothing, though ... even "READ_ONCE()
> > is not necessary" is wrong as that might change without us noticing.
> 
> FWIW, I first suggested using 

Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-06 Thread Christoffer Dall
On Wed, Apr 05, 2017 at 10:20:17PM +0200, Radim Krčmář wrote:
> 2017-04-05 19:39+0200, Christoffer Dall:
> > On Wed, Apr 05, 2017 at 03:10:50PM +0200, Radim Krčmář wrote:
> >> 2017-04-04 18:41+0200, Andrew Jones:
> >> > On Tue, Apr 04, 2017 at 05:30:14PM +0200, Christoffer Dall wrote:
> >> >> On Fri, Mar 31, 2017 at 06:06:50PM +0200, Andrew Jones wrote:
> >> >> > From: Radim Krčmář 
> >> >> > 
> >> >> > A first step in vcpu->requests encapsulation.
> >> >> 
> >> >> Could we have a note here on why we need to access vcpu->requests using
> >> >> READ_ONCE now?
> >> > 
> >> > Sure, maybe we should put the note as a comment above the read in
> >> > kvm_request_pending().  Something like
> >> > 
> >> >  /*
> >> >   * vcpu->requests reads may appear in sequences that have strict
> >> >   * data or control dependencies.  Use READ_ONCE() to ensure the
> >> >   * compiler does not do anything that breaks the required ordering.
> >> >   */
> >> > 
> >> > Radim?
> >> 
> >> Uses of vcpu->requests should already have barriers that take care of
> >> the ordering.  I think the main reason for READ_ONCE() is to tell
> >> programmers that requests are special, but predictable.
> > 
> > I don't know what to do with "special, but predictable", unfortunately.
> > In fact, I don't even think I know what you mean.
> 
> With "special" to stand for the idea that vcpu->requests can change
> outside of the current execution thread.  Letting the programmer assume
> additional guarantees makes the generated code and resulting behavior
> more predictable.
> 
> >> READ_ONCE() is not necessary in any use I'm aware of, but there is no
> >> harm in telling the compiler that vcpu->requests are what we think they
> >> are ...
> > 
> > Hmmm, I'm equally lost.
> 
> vcpu->requests are volatile, so we need to assume that they can change
> at any moment when using them.
> 
> I would prefer if vcpu->requests were of an atomic type and READ_ONCE()
> is about as close we can get without a major overhaul.
> 

I finally see your point of conveying how things work using READ_ONCE().

If there's really no harm in letting the compiler read this as it wishes
(within the boundaries already placed by our use of compiler and memory
barriers), then I think we should just document that instead of relying
on how people would interpret READ_ONCE, but it's up to you - I think
I'm beginning to understand regardless.

> >> 
> >>  /*
> >>   * vcpu->requests are a lockless synchronization mechanism, where
> > 
> > is the requests a synchronization mechanism?  I think of it more as a
> > cross-thread communication protocol.
> 
> Partly, synchronization is too restrictive and communication seems too
> generic, but probably still better.  No idea how to shortly describe the
> part of vcpu->requests that prevents VM entry and that setting a request
> kicks VM out of guest mode.

heh, neither do I.

> 
> x86 uses KVM_REQ_MCLOCK_INPROGRESS for synchronization between cores and
> the use in this series looked very similar.
> 
> >>   * memory barriers are necessary for correct behavior, see
> >>   * Documentation/virtual/kvm/vcpu-requests.rst.
> >>   *
> >>   * READ_ONCE() is not necessary for correctness, but simplifies
> >>   * reasoning by constricting the generated code.
> >>   */
> >> 
> >> I considered READ_ONCE() to be self-documenting. :)
> > 
> > I realize that I'm probably unusually slow in this whole area, but using
> > READ_ONCE() where unnecessary doesn't help my reasoning, but makes me
> > wonder which part of this I didn't understand, so I don't seem to agree
> > with the statement that it simplifies reasoning.
> 
> No, I think it is a matter of approach.  When I see a READ_ONCE()
> without a comment, I think that the programmer was aware that this
> memory can change at any time and was defensive about it.

I think it means that you have to read it exactly once at the exact flow
in the code where it's placed.

> 
> I consider this use to simplify future development:
> We think now that READ_ONCE() is not needed, but vcpu->requests is still
> volatile and future changes in code might make READ_ONCE() necessary.
> Preemptively putting READ_ONCE() there saves us thinking or hard-to-find
> bugs.
> 

I'm always a bit sceptical about such reasoning as I think without a
complete understanding of what needs to change when doing changes, we're
likely to get it wrong anyway.

> > Really, if there is no reason to use it, I don't think we should use it.
> 
> I am leaning towards READ_ONCE() as the default for implicitly volatile
> memory, but commenting why we didn't have to use READ_ONCE() sounds good
> too.
> 

Sure, I can live with both solutions :)

> > To me, READ_ONCE() indicates that there's some flow in the code where
> > it's essential that the compiler doesn't generate multiple loads, but
> > that we only see a momentary single-read snapshot of the value, and this
> > doesn't seem to be the case.
> 
> The compiler can also squash multiple reads together, which

Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-06 Thread Andrew Jones
On Wed, Apr 05, 2017 at 10:20:17PM +0200, Radim Krčmář wrote:
> 2017-04-05 19:39+0200, Christoffer Dall:
> > On Wed, Apr 05, 2017 at 03:10:50PM +0200, Radim Krčmář wrote:
> >> 2017-04-04 18:41+0200, Andrew Jones:
> >> > On Tue, Apr 04, 2017 at 05:30:14PM +0200, Christoffer Dall wrote:
> >> >> On Fri, Mar 31, 2017 at 06:06:50PM +0200, Andrew Jones wrote:
> >> >> > From: Radim Krčmář 
> >> >> > 
> >> >> > A first step in vcpu->requests encapsulation.
> >> >> 
> >> >> Could we have a note here on why we need to access vcpu->requests using
> >> >> READ_ONCE now?
> >> > 
> >> > Sure, maybe we should put the note as a comment above the read in
> >> > kvm_request_pending().  Something like
> >> > 
> >> >  /*
> >> >   * vcpu->requests reads may appear in sequences that have strict
> >> >   * data or control dependencies.  Use READ_ONCE() to ensure the
> >> >   * compiler does not do anything that breaks the required ordering.
> >> >   */
> >> > 
> >> > Radim?
> >> 
> >> Uses of vcpu->requests should already have barriers that take care of
> >> the ordering.  I think the main reason for READ_ONCE() is to tell
> >> programmers that requests are special, but predictable.
> > 
> > I don't know what to do with "special, but predictable", unfortunately.
> > In fact, I don't even think I know what you mean.
> 
> With "special" to stand for the idea that vcpu->requests can change
> outside of the current execution thread.  Letting the programmer assume
> additional guarantees makes the generated code and resulting behavior
> more predictable.
> 
> >> READ_ONCE() is not necessary in any use I'm aware of, but there is no
> >> harm in telling the compiler that vcpu->requests are what we think they
> >> are ...
> > 
> > Hmmm, I'm equally lost.
> 
> vcpu->requests are volatile, so we need to assume that they can change
> at any moment when using them.
> 
> I would prefer if vcpu->requests were of an atomic type and READ_ONCE()
> is about as close we can get without a major overhaul.
> 
> >> 
> >>  /*
> >>   * vcpu->requests are a lockless synchronization mechanism, where
> > 
> > is the requests a synchronization mechanism?  I think of it more as a
> > cross-thread communication protocol.
> 
> Partly, synchronization is too restrictive and communication seems too
> generic, but probably still better.  No idea how to shortly describe the
> part of vcpu->requests that prevents VM entry and that setting a request
> kicks VM out of guest mode.
> 
> x86 uses KVM_REQ_MCLOCK_INPROGRESS for synchronization between cores and
> the use in this series looked very similar.
> 
> >>   * memory barriers are necessary for correct behavior, see
> >>   * Documentation/virtual/kvm/vcpu-requests.rst.
> >>   *
> >>   * READ_ONCE() is not necessary for correctness, but simplifies
> >>   * reasoning by constricting the generated code.
> >>   */
> >> 
> >> I considered READ_ONCE() to be self-documenting. :)
> > 
> > I realize that I'm probably unusually slow in this whole area, but using
> > READ_ONCE() where unnecessary doesn't help my reasoning, but makes me
> > wonder which part of this I didn't understand, so I don't seem to agree
> > with the statement that it simplifies reasoning.
> 
> No, I think it is a matter of approach.  When I see a READ_ONCE()
> without a comment, I think that the programmer was aware that this
> memory can change at any time and was defensive about it.
> 
> I consider this use to simplify future development:
> We think now that READ_ONCE() is not needed, but vcpu->requests is still
> volatile and future changes in code might make READ_ONCE() necessary.
> Preemptively putting READ_ONCE() there saves us thinking or hard-to-find
> bugs.
> 
> > Really, if there is no reason to use it, I don't think we should use it.
> 
> I am leaning towards READ_ONCE() as the default for implicitly volatile
> memory, but commenting why we didn't have to use READ_ONCE() sounds good
> too.
> 
> > To me, READ_ONCE() indicates that there's some flow in the code where
> > it's essential that the compiler doesn't generate multiple loads, but
> > that we only see a momentary single-read snapshot of the value, and this
> > doesn't seem to be the case.
> 
> The compiler can also squash multiple reads together, which is more
> dangerous in this case as we would not notice a new requests.  Avoiding
> READ_ONCE() requires a better knowledge of the compiler algorithms that
> prove which variable can be optimized.
> 
> The difference is really minor and I agree that the comment is bad.
> The only comment I'm happy with is nothing, though ... even "READ_ONCE()
> is not necessary" is wrong as that might change without us noticing.

FWIW, I first suggested using READ_ONCE() for the freshness argument,
but then started to believe there were even more reasons after reading
the comment above it in include/linux/compiler.h.  The last paragraph
of that comment says there are two major use cases for it.  I think the
first one maps to the freshness argument.  The

Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-05 Thread Radim Krčmář
2017-04-05 19:39+0200, Christoffer Dall:
> On Wed, Apr 05, 2017 at 03:10:50PM +0200, Radim Krčmář wrote:
>> 2017-04-04 18:41+0200, Andrew Jones:
>> > On Tue, Apr 04, 2017 at 05:30:14PM +0200, Christoffer Dall wrote:
>> >> On Fri, Mar 31, 2017 at 06:06:50PM +0200, Andrew Jones wrote:
>> >> > From: Radim Krčmář 
>> >> > 
>> >> > A first step in vcpu->requests encapsulation.
>> >> 
>> >> Could we have a note here on why we need to access vcpu->requests using
>> >> READ_ONCE now?
>> > 
>> > Sure, maybe we should put the note as a comment above the read in
>> > kvm_request_pending().  Something like
>> > 
>> >  /*
>> >   * vcpu->requests reads may appear in sequences that have strict
>> >   * data or control dependencies.  Use READ_ONCE() to ensure the
>> >   * compiler does not do anything that breaks the required ordering.
>> >   */
>> > 
>> > Radim?
>> 
>> Uses of vcpu->requests should already have barriers that take care of
>> the ordering.  I think the main reason for READ_ONCE() is to tell
>> programmers that requests are special, but predictable.
> 
> I don't know what to do with "special, but predictable", unfortunately.
> In fact, I don't even think I know what you mean.

With "special" to stand for the idea that vcpu->requests can change
outside of the current execution thread.  Letting the programmer assume
additional guarantees makes the generated code and resulting behavior
more predictable.

>> READ_ONCE() is not necessary in any use I'm aware of, but there is no
>> harm in telling the compiler that vcpu->requests are what we think they
>> are ...
> 
> Hmmm, I'm equally lost.

vcpu->requests are volatile, so we need to assume that they can change
at any moment when using them.

I would prefer if vcpu->requests were of an atomic type and READ_ONCE()
is about as close we can get without a major overhaul.

>> 
>>  /*
>>   * vcpu->requests are a lockless synchronization mechanism, where
> 
> is the requests a synchronization mechanism?  I think of it more as a
> cross-thread communication protocol.

Partly, synchronization is too restrictive and communication seems too
generic, but probably still better.  No idea how to shortly describe the
part of vcpu->requests that prevents VM entry and that setting a request
kicks VM out of guest mode.

x86 uses KVM_REQ_MCLOCK_INPROGRESS for synchronization between cores and
the use in this series looked very similar.

>>   * memory barriers are necessary for correct behavior, see
>>   * Documentation/virtual/kvm/vcpu-requests.rst.
>>   *
>>   * READ_ONCE() is not necessary for correctness, but simplifies
>>   * reasoning by constricting the generated code.
>>   */
>> 
>> I considered READ_ONCE() to be self-documenting. :)
> 
> I realize that I'm probably unusually slow in this whole area, but using
> READ_ONCE() where unnecessary doesn't help my reasoning, but makes me
> wonder which part of this I didn't understand, so I don't seem to agree
> with the statement that it simplifies reasoning.

No, I think it is a matter of approach.  When I see a READ_ONCE()
without a comment, I think that the programmer was aware that this
memory can change at any time and was defensive about it.

I consider this use to simplify future development:
We think now that READ_ONCE() is not needed, but vcpu->requests is still
volatile and future changes in code might make READ_ONCE() necessary.
Preemptively putting READ_ONCE() there saves us thinking or hard-to-find
bugs.

> Really, if there is no reason to use it, I don't think we should use it.

I am leaning towards READ_ONCE() as the default for implicitly volatile
memory, but commenting why we didn't have to use READ_ONCE() sounds good
too.

> To me, READ_ONCE() indicates that there's some flow in the code where
> it's essential that the compiler doesn't generate multiple loads, but
> that we only see a momentary single-read snapshot of the value, and this
> doesn't seem to be the case.

The compiler can also squash multiple reads together, which is more
dangerous in this case as we would not notice a new requests.  Avoiding
READ_ONCE() requires a better knowledge of the compiler algorithms that
prove which variable can be optimized.

The difference is really minor and I agree that the comment is bad.
The only comment I'm happy with is nothing, though ... even "READ_ONCE()
is not necessary" is wrong as that might change without us noticing.
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-05 Thread Paolo Bonzini


On 05/04/2017 19:39, Christoffer Dall wrote:
>> Uses of vcpu->requests should already have barriers that take care of
>> the ordering.  I think the main reason for READ_ONCE() is to tell
>> programmers that requests are special, but predictable.
> 
> I don't know what to do with "special, but predictable", unfortunately.
> In fact, I don't even think I know what you mean.

I don't think it's special, but predictable.  It's atomic, but with
relaxed ordering.

Paolo
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-05 Thread Christoffer Dall
On Wed, Apr 05, 2017 at 03:10:50PM +0200, Radim Krčmář wrote:
> 2017-04-04 18:41+0200, Andrew Jones:
> > On Tue, Apr 04, 2017 at 05:30:14PM +0200, Christoffer Dall wrote:
> >> On Fri, Mar 31, 2017 at 06:06:50PM +0200, Andrew Jones wrote:
> >> > From: Radim Krčmář 
> >> > 
> >> > A first step in vcpu->requests encapsulation.
> >> 
> >> Could we have a note here on why we need to access vcpu->requests using
> >> READ_ONCE now?
> > 
> > Sure, maybe we should put the note as a comment above the read in
> > kvm_request_pending().  Something like
> > 
> >  /*
> >   * vcpu->requests reads may appear in sequences that have strict
> >   * data or control dependencies.  Use READ_ONCE() to ensure the
> >   * compiler does not do anything that breaks the required ordering.
> >   */
> > 
> > Radim?
> 
> Uses of vcpu->requests should already have barriers that take care of
> the ordering.  I think the main reason for READ_ONCE() is to tell
> programmers that requests are special, but predictable.

I don't know what to do with "special, but predictable", unfortunately.
In fact, I don't even think I know what you mean.

> 
> READ_ONCE() is not necessary in any use I'm aware of, but there is no
> harm in telling the compiler that vcpu->requests are what we think they
> are ...

Hmmm, I'm equally lost.

> 
>  /*
>   * vcpu->requests are a lockless synchronization mechanism, where

is the requests a synchronization mechanism?  I think of it more as a
cross-thread communication protocol.

>   * memory barriers are necessary for correct behavior, see
>   * Documentation/virtual/kvm/vcpu-requests.rst.
>   *
>   * READ_ONCE() is not necessary for correctness, but simplifies
>   * reasoning by constricting the generated code.
>   */
> 
> I considered READ_ONCE() to be self-documenting. :)

I realize that I'm probably unusually slow in this whole area, but using
READ_ONCE() where unnecessary doesn't help my reasoning, but makes me
wonder which part of this I didn't understand, so I don't seem to agree
with the statement that it simplifies reasoning.

Really, if there is no reason to use it, I don't think we should use it.
To me, READ_ONCE() indicates that there's some flow in the code where
it's essential that the compiler doesn't generate multiple loads, but
that we only see a momentary single-read snapshot of the value, and this
doesn't seem to be the case.

Thanks,
-Christoffer
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-05 Thread Radim Krčmář
2017-04-04 18:41+0200, Andrew Jones:
> On Tue, Apr 04, 2017 at 05:30:14PM +0200, Christoffer Dall wrote:
>> On Fri, Mar 31, 2017 at 06:06:50PM +0200, Andrew Jones wrote:
>> > From: Radim Krčmář 
>> > 
>> > A first step in vcpu->requests encapsulation.
>> 
>> Could we have a note here on why we need to access vcpu->requests using
>> READ_ONCE now?
> 
> Sure, maybe we should put the note as a comment above the read in
> kvm_request_pending().  Something like
> 
>  /*
>   * vcpu->requests reads may appear in sequences that have strict
>   * data or control dependencies.  Use READ_ONCE() to ensure the
>   * compiler does not do anything that breaks the required ordering.
>   */
> 
> Radim?

Uses of vcpu->requests should already have barriers that take care of
the ordering.  I think the main reason for READ_ONCE() is to tell
programmers that requests are special, but predictable.

READ_ONCE() is not necessary in any use I'm aware of, but there is no
harm in telling the compiler that vcpu->requests are what we think they
are ...

 /*
  * vcpu->requests are a lockless synchronization mechanism, where
  * memory barriers are necessary for correct behavior, see
  * Documentation/virtual/kvm/vcpu-requests.rst.
  *
  * READ_ONCE() is not necessary for correctness, but simplifies
  * reasoning by constricting the generated code.
  */

I considered READ_ONCE() to be self-documenting. :)
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-04 Thread Andrew Jones
On Tue, Apr 04, 2017 at 05:30:14PM +0200, Christoffer Dall wrote:
> On Fri, Mar 31, 2017 at 06:06:50PM +0200, Andrew Jones wrote:
> > From: Radim Krčmář 
> > 
> > A first step in vcpu->requests encapsulation.
> 
> Could we have a note here on why we need to access vcpu->requests using
> READ_ONCE now?

Sure, maybe we should put the note as a comment above the read in
kvm_request_pending().  Something like

 /*
  * vcpu->requests reads may appear in sequences that have strict
  * data or control dependencies.  Use READ_ONCE() to ensure the
  * compiler does not do anything that breaks the required ordering.
  */

Radim?

Thanks,
drew
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v2 1/9] KVM: add kvm_request_pending

2017-04-04 Thread Christoffer Dall
On Fri, Mar 31, 2017 at 06:06:50PM +0200, Andrew Jones wrote:
> From: Radim Krčmář 
> 
> A first step in vcpu->requests encapsulation.

Could we have a note here on why we need to access vcpu->requests using
READ_ONCE now?

Thanks,
-Christoffer

> 
> Signed-off-by: Radim Krčmář 
> Signed-off-by: Andrew Jones 
> ---
>  arch/mips/kvm/trap_emul.c  | 2 +-
>  arch/powerpc/kvm/booke.c   | 2 +-
>  arch/powerpc/kvm/powerpc.c | 5 ++---
>  arch/s390/kvm/kvm-s390.c   | 2 +-
>  arch/x86/kvm/x86.c | 4 ++--
>  include/linux/kvm_host.h   | 5 +
>  6 files changed, 12 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c
> index b1fa53b252ea..9ac8b1d62643 100644
> --- a/arch/mips/kvm/trap_emul.c
> +++ b/arch/mips/kvm/trap_emul.c
> @@ -1029,7 +1029,7 @@ static void kvm_trap_emul_check_requests(struct 
> kvm_vcpu *vcpu, int cpu,
>   struct mm_struct *mm;
>   int i;
>  
> - if (likely(!vcpu->requests))
> + if (likely(!kvm_request_pending(vcpu)))
>   return;
>  
>   if (kvm_check_request(KVM_REQ_TLB_FLUSH, vcpu)) {
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index 0514cbd4e533..65ed6595c9c2 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -682,7 +682,7 @@ int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
>  
>   kvmppc_core_check_exceptions(vcpu);
>  
> - if (vcpu->requests) {
> + if (kvm_request_pending(vcpu)) {
>   /* Exception delivery raised request; start over */
>   return 1;
>   }
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index 95c91a9de351..714674ea5be6 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -52,8 +52,7 @@ EXPORT_SYMBOL_GPL(kvmppc_pr_ops);
>  
>  int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
>  {
> - return !!(v->arch.pending_exceptions) ||
> -v->requests;
> + return !!(v->arch.pending_exceptions) || kvm_request_pending(v);
>  }
>  
>  int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
> @@ -105,7 +104,7 @@ int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu)
>*/
>   smp_mb();
>  
> - if (vcpu->requests) {
> + if (kvm_request_pending(vcpu)) {
>   /* Make sure we process requests preemptable */
>   local_irq_enable();
>   trace_kvm_check_requests(vcpu);
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index fd6cd05bb6a7..40ad6c8d082f 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
> @@ -2396,7 +2396,7 @@ static int kvm_s390_handle_requests(struct kvm_vcpu 
> *vcpu)
>  {
>  retry:
>   kvm_s390_vcpu_request_handled(vcpu);
> - if (!vcpu->requests)
> + if (!kvm_request_pending(vcpu))
>   return 0;
>   /*
>* We use MMU_RELOAD just to re-arm the ipte notifier for the
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 1faf620a6fdc..9714bb230524 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -6726,7 +6726,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
>  
>   bool req_immediate_exit = false;
>  
> - if (vcpu->requests) {
> + if (kvm_request_pending(vcpu)) {
>   if (kvm_check_request(KVM_REQ_MMU_RELOAD, vcpu))
>   kvm_mmu_unload(vcpu);
>   if (kvm_check_request(KVM_REQ_MIGRATE_TIMER, vcpu))
> @@ -6890,7 +6890,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
>   kvm_x86_ops->sync_pir_to_irr(vcpu);
>   }
>  
> - if (vcpu->mode == EXITING_GUEST_MODE || vcpu->requests
> + if (vcpu->mode == EXITING_GUEST_MODE || kvm_request_pending(vcpu)
>   || need_resched() || signal_pending(current)) {
>   vcpu->mode = OUTSIDE_GUEST_MODE;
>   smp_wmb();
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 2c14ad9809da..946bf0b3c43c 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -1085,6 +1085,11 @@ static inline int kvm_ioeventfd(struct kvm *kvm, 
> struct kvm_ioeventfd *args)
>  
>  #endif /* CONFIG_HAVE_KVM_EVENTFD */
>  
> +static inline bool kvm_request_pending(struct kvm_vcpu *vcpu)
> +{
> + return READ_ONCE(vcpu->requests);
> +}
> +
>  static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu)
>  {
>   /*
> -- 
> 2.9.3
> 
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm