Re: [PATCH 2/2] Remove unnecessary memory fence

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

 



Hi Paul,

Thanks a LOT for the references. They are pretty much helpful :-). I
need a deeper look into it (and of course think about it) and will
submit new patches by tomorrow.


Thanks,
--Jason


On Tue, May 9, 2017 at 11:40 PM, Paul E. McKenney
<paulmck@xxxxxxxxxxxxxxxxxx> wrote:
> On Tue, May 09, 2017 at 11:20:01PM +0800, Junchang Wang wrote:
>> Hi Paul,
>>
>> Thanks a lot for the correction. Thanks's right; we need to care about
>> other achitectures :-)
>>
>> So barrier() is basically empty: define barrier() __asm__
>> __volatile__("": : :"memory") . I'm curious about what on the earth it
>> does? We do really use it in counttorture.h. Any reference to
>> resources is welcome!
>>
>> Even if we agree with smp_mb(), count_stat_eventual.c seems not 100%
>> correct for me. Please check the following patch. It seems to me the
>> barrier instruction (smp_mb) in function count_cleanup is to make RAW
>> correct. So it should be inserted between the write and read
>> instructions. Is that right?
>
> Well, part of your change is in the right direction.  Either stopflag
> needs to be volatile or the accesses to stopflag need to use READ_ONCE()
> or WRITE_ONCE(), with the latter preferred.
>
> I suggest looking at this Linux Weekly News (LWN) series:
>
>         https://lwn.net/Articles/718628/
>         https://lwn.net/Articles/720550/
>
> This LWN article talks about use of ACCESS_ONCE(), which is the
> predecessor to READ_ONCE() and WRITE_ONCE():
>
>         http://lwn.net/Articles/508991/
>
> So I would welcome a patch that applied READ_ONCE() and WRITE_ONCE()
> to the stopflag variable.  Given that some of this code was written
> before ACCESS_ONCE(), let alone READ_ONCE() and WRITE_ONCE(), there
> might be more code needing this change, so please feel free to take
> a look around.
>
>                                                         Thanx, Paul
>
>> index 75a0ca9..32f7e80 100644
>> --- a/CodeSamples/count/count_stat_eventual.c
>> +++ b/CodeSamples/count/count_stat_eventual.c
>> @@ -67,9 +67,9 @@ void count_init(void)
>>  void count_cleanup(void)
>>  {
>>         stopflag = 1;
>> +       smp_mb();
>>         while (stopflag < 3)
>>                 poll(NULL, 0, 1);
>> -       smp_mb();
>>  }
>>
>>  #include "counttorture.h"
>> --
>> 2.7.4
>>
>>
>> Thanks,
>> --Jason
>>
>> On Tue, May 9, 2017 at 10:47 PM, Paul E. McKenney
>> <paulmck@xxxxxxxxxxxxxxxxxx> wrote:
>> > On Tue, May 09, 2017 at 01:08:31PM +0800, Junchang Wang wrote:
>> >> count_stat_eventual.c uses a single global variable (stopflag) to synchronize
>> >> two separate threads (main and eventual) probably running on two different CPU
>> >> cores. My understanding is that for this model, memory fence instruction
>> >> (mfence) which typically are expensive can be avoided, only if we make sure (1)
>> >> that compiler neither reorder the code around nor cache the variable, and (2)
>> >> that the CPU core running code precedes in program order.
>> >>
>> >> We use keyword ``volatile'' to prevent compilers from reordering the code and
>> >> caching the variable, and instruction barrier() to force CPU core running the
>> >> code to obey program order.
>> >
>> > Please take another look at the barrier() macro.  It does not emit any
>> > instructions, so cannot force the CPU to do much of anything.  Keep in
>> > mind that this code needs to run on weakly ordered systems, not just x86.
>> >
>> >                                                         Thanx, Paul
>> >
>> >> Signed-off-by: Junchang Wang <junchangwang@xxxxxxxxx>
>> >> ---
>> >>  CodeSamples/count/count_stat_eventual.c | 6 +++---
>> >>  1 file changed, 3 insertions(+), 3 deletions(-)
>> >>
>> >> diff --git a/CodeSamples/count/count_stat_eventual.c b/CodeSamples/count/count_stat_eventual.c
>> >> index 059ab8b..5ffc4aa 100644
>> >> --- a/CodeSamples/count/count_stat_eventual.c
>> >> +++ b/CodeSamples/count/count_stat_eventual.c
>> >> @@ -23,7 +23,7 @@
>> >>
>> >>  DEFINE_PER_THREAD(unsigned long, counter);
>> >>  unsigned long global_count;
>> >> -int stopflag;
>> >> +volatile int stopflag;
>> >>
>> >>  void inc_count(void)
>> >>  {
>> >> @@ -47,7 +47,7 @@ void *eventual(void *arg)
>> >>               ACCESS_ONCE(global_count) = sum;
>> >>               poll(NULL, 0, 1);
>> >>               if (stopflag) {
>> >> -                     smp_mb();
>> >> +                     barrier();
>> >>                       stopflag++;
>> >>               }
>> >>       }
>> >> @@ -67,9 +67,9 @@ void count_init(void)
>> >>  void count_cleanup(void)
>> >>  {
>> >>       stopflag = 1;
>> >> +     barrier();
>> >>       while (stopflag < 3)
>> >>               poll(NULL, 0, 1);
>> >> -     smp_mb();
>> >>  }
>> >>
>> >>  #include "counttorture.h"
>> >> --
>> >> 2.7.4
>> >>
>> >> --
>> >> To unsubscribe from this list: send the line "unsubscribe perfbook" in
>> >> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> >>
>> >
>>
>
--
To unsubscribe from this list: send the line "unsubscribe perfbook" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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