Re: Re: memory barrier ...

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

 



On Mon, Nov 11, 2002 at 11:16:46PM -0800, Seth Arnold wrote:
> On Tue, Nov 12, 2002 at 07:01:43AM -0000, Nishant Sharma wrote:
> 
> 
> [nishant, you may wish to fix your mail user agent or mail server; I
> received a copy of this mail sent directly to me, and the headers did
> not mention kernelnewbies, and the email sent to kernelnewbies didn't
> mention me..]
> 
> >   So in effect it is required for ordering of the I/O
> > and memory refrences across crucial pieces of code (and this is 
> > where _prefething_ etc comes into play)
> 
> Yes. :)
> 
> >   I dont xactly get u here ;). Firstly ive seen in the Linux code 
> > that i dont need to place a __volatile__ for the barrier 
> > implementation code and it is being used because of a gcc bug, so 
> > it is not supposed to be there ?? is it ??
> 
> The kernel is very specific to gcc bugs; as far as I can tell, the
> __volatile__ is required for the barrier. :)

I am not sure the bug is still there, however quite old gcc is still
used eg in redhat (egcs-2.91.66). But meaning of the __volatile__ is
something like "don't try to think here, you would get it wrong".

> >   Secondly, in IA32 a locked instruction is guarantees u a total 
> > ordering around that instruction (and CPUID inst too guarantees 
> > that). So when i need a barrier across two insts ... what code 
> > will the barrier() expand to ..
> > sth like --
> >  write A
> >  mb()             // barrier
> >  read  B

There are two things to the barrier. One is to make sure CPU does not
prefetch the old value and another is to make sure, that compiler does
not reorder the statements!

The barrier() macro is the
asm volatile ("" : "" : "" : "memory")
think. It has the first string empty, so it expands to no code at all.
But because of the memory clobber flag, gcc is forbiden to optimize
across this point. Otherwise gcc could for example conclude that "I have
A in register, I am not short of registers and I will need it few
statements later. There is no need to store it in memory." ... and
actually not store it.

The mb() thing adds a "barrier" instruction to actualy stop CPU prefetch
across the point. No such instruction is needed on IA32, but it's needed
on some other arch with agressive prefetch (eg. sparc IIRC).

(I am not absolutely sure, look it up in the code).

> > Sorry for bothering ... i might be totally wrong here ..:)
> 
> That sounds right to me.. but of course, if the read of B doesn't depend
> on the write of A, leaving out the memory barrier is the way to go. :)
> Heh heh heh.

If B does actually depend on A, the compiler can't reorder (there is the
; sequencing point in between), but it can still keep A in register...

The point in barrier is that interrupt might jump in, read A and write
B. And if the compiler decided to keep A in register, the interrupt
would get inconsistent data and crash!

So barrier should be viewed as a very lightweight synchronization
primitive where correct ordering suffices to assure consistency with SMP
and or interrupt. Note, that spinlocks are defined to act like memory
barriers so you don't need barrier when you lock. (But is eg. possible
to make list insertion and be consistent wrt. to walking the list with
only a barrier).

> As far as I can tell, the best usage is in functions like
> set_task_state, where it is required the state get updated before other

task_state is one of two (or something like that number) volatile
variables in kernel. That means it's value is never kept in register.
And since it's not read by the other CPU nor by an interrupt, it is
sufficient (it's not sufficient since preempt patch, that's why the
set_task_state was introduced).

> C statements get executed, and in unlocking critical sections of code,
> when the final changes to variables are expected to have finished. (I'm
> not sure if current versions of linux have this fixed or not. heh. :)

Locks are barriers!

-------------------------------------------------------------------------------
						 Jan 'Bulb' Hudec <bulb@ucw.cz>
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux