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/