| Message ID | .stgit@ubuntu-yegoshin |
|---|---|
| State | New |
| Headers | show |
Hi Leonid, On Mon, Jun 01, 2015 at 05:09:34PM -0700, Leonid Yegoshin wrote: > This instructions were specifically designed to work for smp_*() sort of > memory barriers in MIPS R2/R3/R5 and R6. > > Unfortunately, it's description is very cryptic and is done in HW engineering > style which prevents use of it by SW. FYI this reads to me like "I couldn't figure it out from the manuals" which you might want to leave out. > This instructions are not mandatory but > there is a mandatory requirement - if not implemented, then a regular MIPS > SYNC 0 must be used instead. > > The reason for this change is - SYNC 0 is a heavvy-weighted in many CPUs, it may > disrupt other cores pipelines etc. > > Due to concern about verification of old MIPS R2 compatible cores of other > vendors it is enforced only for MIPS R6 and other MIPS32/64 R2/R5 processors > have it configurable. > > Signed-off-by: Leonid Yegoshin <> > --- > arch/mips/Kconfig | 22 ++++++++++++++++++++++ > arch/mips/include/asm/barrier.h | 6 ++++++ > 2 files changed, 28 insertions(+) > > diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig > index be384d6a58bb..c7d0cacece3d 100644 > --- a/arch/mips/Kconfig > +++ b/arch/mips/Kconfig > @@ -1347,6 +1347,7 @@ config CPU_MIPS32_R2 > select CPU_SUPPORTS_32BIT_KERNEL > select CPU_SUPPORTS_HIGHMEM > select CPU_SUPPORTS_MSA > + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC > select HAVE_KVM > help > Choose this option to build a kernel for release 2 or later of the > @@ -1365,6 +1366,8 @@ config CPU_MIPS32_R6 > select GENERIC_CSUM > select HAVE_KVM > select MIPS_O32_FP64_SUPPORT > + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC > + select WEAK_REORDERING_BEYOND_LLSC This WEAK_REORDERING_BEYOND_LLSC change should probably be split out into a separate patch, since it has nothing to do with the smp_* barriers and is just left as a sync 0 (__WEAK_LLSC_MB) as of this patch. > help > Choose this option to build a kernel for release 6 or later of the > MIPS32 architecture. New MIPS processors, starting with the Warrior > @@ -1399,6 +1402,7 @@ config CPU_MIPS64_R2 > select CPU_SUPPORTS_HIGHMEM > select CPU_SUPPORTS_HUGEPAGES > select CPU_SUPPORTS_MSA > + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC > help > Choose this option to build a kernel for release 2 or later of the > MIPS64 architecture. Many modern embedded systems with a 64-bit > @@ -1415,6 +1419,8 @@ config CPU_MIPS64_R6 > select CPU_SUPPORTS_HIGHMEM > select CPU_SUPPORTS_MSA > select GENERIC_CSUM > + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC > + select WEAK_REORDERING_BEYOND_LLSC Ditto. > help > Choose this option to build a kernel for release 6 or later of the > MIPS64 architecture. New MIPS processors, starting with the Warrior > @@ -1876,6 +1882,20 @@ config WEAK_ORDERING > # > config WEAK_REORDERING_BEYOND_LLSC > bool > + > +config MIPS_LIGHTWEIGHT_SYNC > + bool "CPU lightweight SYNC instruction for weak reordering" > + depends on CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC && WEAK_ORDERING > + default y if CPU_MIPSR6 > + help > + This option enforces a use of "lightweight sync" instructions > + for SMP (multi-CPU) memory barriers. This instructions are much > + more faster than a traditional "SYNC 0". "enforces a use" would probably read better as "makes use", and "much more faster" should just be "much faster". Personally I'd not make the SYNC so shouty - sync is perfectly valid & generally the way the instruction is named even in the kernel. > + > + If that instructions are not implemented in processor then it is > + converted to generic "SYNC 0". I think this would read better as something like: If a processor does not implement the lightweight sync operations then the architecture requires that they interpret the corresponding sync instructions as the typical heavyweight "sync 0". Therefore this should be safe to enable on all CPUs implementing release 2 or later of the MIPS architecture. > + > + If you unsure, say N here, it may slightly decrease your performance > endmenu > > # > @@ -1928,6 +1948,8 @@ config CPU_SUPPORTS_HUGEPAGES > bool > config CPU_SUPPORTS_UNCACHED_ACCELERATED > bool > +config CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC > + bool I'm not sure putting MIPS_ in the name of this makes sense either BTW. Other things around it don't bother (eg. UNCACHED_ACCELERATED right above) and it's already under arch/mips/Kconfig. > config MIPS_PGD_C0_CONTEXT > bool > default y if 64BIT && CPU_MIPSR2 && !CPU_XLP > diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h > index 2b8bbbcb9be0..d2a63abfc7c6 100644 > --- a/arch/mips/include/asm/barrier.h > +++ b/arch/mips/include/asm/barrier.h > @@ -96,9 +96,15 @@ > # define smp_rmb() barrier() > # define smp_wmb() __syncw() > # else > +# ifdef CONFIG_MIPS_LIGHTWEIGHT_SYNC > +# define smp_mb() __asm__ __volatile__("sync 0x10" : : :"memory") > +# define smp_rmb() __asm__ __volatile__("sync 0x13" : : :"memory") > +# define smp_wmb() __asm__ __volatile__("sync 0x4" : : :"memory") Tabs please. Thanks, Paul > +# else > # define smp_mb() __asm__ __volatile__("sync" : : :"memory") > # define smp_rmb() __asm__ __volatile__("sync" : : :"memory") > # define smp_wmb() __asm__ __volatile__("sync" : : :"memory") > +# endif > # endif > #else > #define smp_mb() barrier() > >
Hi Leonid, On 02/06/15 01:09, Leonid Yegoshin wrote: > This instructions were specifically designed to work for smp_*() sort of > memory barriers in MIPS R2/R3/R5 and R6. > > Unfortunately, it's description is very cryptic and is done in HW engineering > style which prevents use of it by SW. This instructions are not mandatory but > there is a mandatory requirement - if not implemented, then a regular MIPS > SYNC 0 must be used instead. > > The reason for this change is - SYNC 0 is a heavvy-weighted in many CPUs, it may heavy > disrupt other cores pipelines etc. > > Due to concern about verification of old MIPS R2 compatible cores of other > vendors it is enforced only for MIPS R6 and other MIPS32/64 R2/R5 processors > have it configurable. Is it worth inverting the logic to exclude the platforms you're concerned about (which also makes it explicit what hardware needs verifying). For new platforms we don't need to worry about kernel regressions so much, so it probably makes sense to have them used by default. > > Signed-off-by: Leonid Yegoshin <> > --- > arch/mips/Kconfig | 22 ++++++++++++++++++++++ > arch/mips/include/asm/barrier.h | 6 ++++++ > 2 files changed, 28 insertions(+) > > diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig > index be384d6a58bb..c7d0cacece3d 100644 > --- a/arch/mips/Kconfig > +++ b/arch/mips/Kconfig > @@ -1347,6 +1347,7 @@ config CPU_MIPS32_R2 > select CPU_SUPPORTS_32BIT_KERNEL > select CPU_SUPPORTS_HIGHMEM > select CPU_SUPPORTS_MSA > + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC > select HAVE_KVM > help > Choose this option to build a kernel for release 2 or later of the > @@ -1365,6 +1366,8 @@ config CPU_MIPS32_R6 > select GENERIC_CSUM > select HAVE_KVM > select MIPS_O32_FP64_SUPPORT > + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC > + select WEAK_REORDERING_BEYOND_LLSC > help > Choose this option to build a kernel for release 6 or later of the > MIPS32 architecture. New MIPS processors, starting with the Warrior > @@ -1399,6 +1402,7 @@ config CPU_MIPS64_R2 > select CPU_SUPPORTS_HIGHMEM > select CPU_SUPPORTS_HUGEPAGES > select CPU_SUPPORTS_MSA > + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC > help > Choose this option to build a kernel for release 2 or later of the > MIPS64 architecture. Many modern embedded systems with a 64-bit > @@ -1415,6 +1419,8 @@ config CPU_MIPS64_R6 > select CPU_SUPPORTS_HIGHMEM > select CPU_SUPPORTS_MSA > select GENERIC_CSUM > + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC > + select WEAK_REORDERING_BEYOND_LLSC > help > Choose this option to build a kernel for release 6 or later of the > MIPS64 architecture. New MIPS processors, starting with the Warrior > @@ -1876,6 +1882,20 @@ config WEAK_ORDERING > # > config WEAK_REORDERING_BEYOND_LLSC > bool > + > +config MIPS_LIGHTWEIGHT_SYNC > + bool "CPU lightweight SYNC instruction for weak reordering" > + depends on CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC && WEAK_ORDERING Worth depending on SMP, so as not to give the user more options than they need? > + default y if CPU_MIPSR6 > + help > + This option enforces a use of "lightweight sync" instructions > + for SMP (multi-CPU) memory barriers. This instructions are much > + more faster than a traditional "SYNC 0". > + > + If that instructions are not implemented in processor then it is > + converted to generic "SYNC 0". > + > + If you unsure, say N here, it may slightly decrease your performance "it" is ambiguous. "Saying N" or "this option"? (I guess "saying N", but its not obvious to an uninformed kernel configurer). > endmenu > > # > @@ -1928,6 +1948,8 @@ config CPU_SUPPORTS_HUGEPAGES > bool > config CPU_SUPPORTS_UNCACHED_ACCELERATED > bool > +config CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC > + bool > config MIPS_PGD_C0_CONTEXT > bool > default y if 64BIT && CPU_MIPSR2 && !CPU_XLP > diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h > index 2b8bbbcb9be0..d2a63abfc7c6 100644 > --- a/arch/mips/include/asm/barrier.h > +++ b/arch/mips/include/asm/barrier.h > @@ -96,9 +96,15 @@ > # define smp_rmb() barrier() > # define smp_wmb() __syncw() > # else > +# ifdef CONFIG_MIPS_LIGHTWEIGHT_SYNC > +# define smp_mb() __asm__ __volatile__("sync 0x10" : : :"memory") > +# define smp_rmb() __asm__ __volatile__("sync 0x13" : : :"memory") > +# define smp_wmb() __asm__ __volatile__("sync 0x4" : : :"memory") binutils appears to support the sync_mb, sync_rmb, sync_wmb aliases since version 2.21. Can we safely use them? Cheers James > +# else > # define smp_mb() __asm__ __volatile__("sync" : : :"memory") > # define smp_rmb() __asm__ __volatile__("sync" : : :"memory") > # define smp_wmb() __asm__ __volatile__("sync" : : :"memory") > +# endif > # endif > #else > #define smp_mb() barrier() > >
On Tue, Jun 02, 2015 at 11:08:35AM +0100, Paul Burton wrote: > Hi Leonid, > <snip> > > + > > + If that instructions are not implemented in processor then it is > > + converted to generic "SYNC 0". > > I think this would read better as something like: > > If a processor does not implement the lightweight sync operations then > the architecture requires that they interpret the corresponding sync > instructions as the typical heavyweight "sync 0". Therefore this > should be safe to enable on all CPUs implementing release 2 or > later of the MIPS architecture. > Is it really the case for release 2? I'm asking because recently I needed to do something similar and I couldn't find this garantee in the revision 2.00 of the manual. May it's just poorly formulated but here is what I find in it: - "The stype values 1-31 are reserved for future extensions to the architecture." (ok) - "A value of zero will always be defined such that it performs all defined synchronization operations." (ok) - "Non-zero values may be defined to remove some synchronization operations." (ok, certainly if we understand the word "weaker" instead of "remove") - "As such, software should never use a non-zero value of the stype field, as this may inadvertently cause future failures if non-zero values remove synchronization operations." (Mmmm, ok but ...) Nowhere is there something close to what is found in the revision 5.0 or later: "If an implementation does not use one of these non-zero values to define a different synchronization behavior, then that non-zero value of stype must act the same as stype zero completion barrier." The wording may have changed since revision 2.8 but I don't have access to the corresponding manual. Luc Van Oostenryck
On Tue, Jun 02, 2015 at 02:12:29PM +0200, Luc Van Oostenryck wrote: > Date: Tue, 2 Jun 2015 14:12:29 +0200 > From: Luc Van Oostenryck <> > To: Paul Burton <> > Cc: Leonid Yegoshin <>, > , , , > , , > , , , > , > Subject: Re: [PATCH 1/3] MIPS: R6: Use lightweight SYNC instruction in > smp_* memory barriers > Content-Type: text/plain; charset=us-ascii > > On Tue, Jun 02, 2015 at 11:08:35AM +0100, Paul Burton wrote: > > Hi Leonid, > > > > <snip> > > > > + > > > + If that instructions are not implemented in processor then it is > > > + converted to generic "SYNC 0". > > > > I think this would read better as something like: > > > > If a processor does not implement the lightweight sync operations then > > the architecture requires that they interpret the corresponding sync > > instructions as the typical heavyweight "sync 0". Therefore this > > should be safe to enable on all CPUs implementing release 2 or > > later of the MIPS architecture. > > > > Is it really the case for release 2? > > I'm asking because recently I needed to do something similar and I couldn't > find this garantee in the revision 2.00 of the manual. > May it's just poorly formulated but here is what I find in it: > - "The stype values 1-31 are reserved for future extensions to the architecture." > (ok) > - "A value of zero will always be defined such that it performs all defined > synchronization operations." (ok) > - "Non-zero values may be defined to remove some synchronization operations." > (ok, certainly if we understand the word "weaker" instead of "remove") Yes, "weaker" is what was meant here. > - "As such, software should never use a non-zero value of the stype field, as > this may inadvertently cause future failures if non-zero values remove > synchronization operations." (Mmmm, ok but ...) > Nowhere is there something close to what is found in the revision 5.0 or later: I think that's just a very convoluted way to say non-zero values are reserved and the CPU may bite you and your kittens if you dare to use such values. > "If an implementation does not use one of these non-zero values to define a > different synchronization behavior, then that non-zero value of stype must > act the same as stype zero completion barrier." "We try to be nice to bad code but ... you've been warned!" :-) > The wording may have changed since revision 2.8 but I don't have access to the > corresponding manual. The page about the SYNC instruction has changed significantly over time - the SYNC instruction's documentation manual has grown from one page for the R4000 to four pages for MIPS32 R1 and R2.5 to five pages for MIPS64 R3.02 and newer. R3 added read, write, rw, acquire and release sync types. But the sentence in question exists unchanged even in the R6 manual. Ralf
On Tue, 2 Jun 2015, James Hogan wrote: > > diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h > > index 2b8bbbcb9be0..d2a63abfc7c6 100644 > > --- a/arch/mips/include/asm/barrier.h > > +++ b/arch/mips/include/asm/barrier.h > > @@ -96,9 +96,15 @@ > > # define smp_rmb() barrier() > > # define smp_wmb() __syncw() > > # else > > +# ifdef CONFIG_MIPS_LIGHTWEIGHT_SYNC > > +# define smp_mb() __asm__ __volatile__("sync 0x10" : : :"memory") > > +# define smp_rmb() __asm__ __volatile__("sync 0x13" : : :"memory") > > +# define smp_wmb() __asm__ __volatile__("sync 0x4" : : :"memory") > > binutils appears to support the sync_mb, sync_rmb, sync_wmb aliases > since version 2.21. Can we safely use them? I suggest that we don't -- we still officially support binutils 2.12 and have other places where we even use `.word' to insert instructions current versions of binutils properly handle. It may be worth noting in a comment though that these encodings correspond to these operations that you named. Maciej
On 06/02/2015 05:12 AM, Luc Van Oostenryck wrote: > On Tue, Jun 02, 2015 at 11:08:35AM +0100, Paul Burton wrote: > >> I think this would read better as something like: >> >> If a processor does not implement the lightweight sync operations then >> the architecture requires that they interpret the corresponding sync >> instructions as the typical heavyweight "sync 0". Therefore this >> should be safe to enable on all CPUs implementing release 2 or >> later of the MIPS architecture. >> > Is it really the case for release 2? > > I'm asking because recently I needed to do something similar and I couldn't > find this garantee in the revision 2.00 of the manual. Yes. MD00086/MD00084/MD00087 Rev 2.60 are technically MIPS R2. And this revision explicitly lists optional codes and it has a clear statement: > Implementations that do not use any of the non-zero values of stype to > define different barriers, such as ordering bar- > riers, must make those stype values act the same as stype zero. (don't blame me that Rev 2.60 is 5 years after initial 2.00, it is still MIPS R2). - Leonid.
On 06/02/2015 09:15 AM, Maciej W. Rozycki wrote: > On Tue, 2 Jun 2015, James Hogan wrote: > >>> diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h >>> index 2b8bbbcb9be0..d2a63abfc7c6 100644 >>> --- a/arch/mips/include/asm/barrier.h >>> +++ b/arch/mips/include/asm/barrier.h >>> @@ -96,9 +96,15 @@ >>> # define smp_rmb() barrier() >>> # define smp_wmb() __syncw() >>> # else >>> +# ifdef CONFIG_MIPS_LIGHTWEIGHT_SYNC >>> +# define smp_mb() __asm__ __volatile__("sync 0x10" : : :"memory") >>> +# define smp_rmb() __asm__ __volatile__("sync 0x13" : : :"memory") >>> +# define smp_wmb() __asm__ __volatile__("sync 0x4" : : :"memory") >> >> binutils appears to support the sync_mb, sync_rmb, sync_wmb aliases >> since version 2.21. Can we safely use them? > > I suggest that we don't -- we still officially support binutils 2.12 and > have other places where we even use `.word' to insert instructions current > versions of binutils properly handle. It may be worth noting in a comment > though that these encodings correspond to these operations that you named. > Surely the other MIPSr6 instructions are not supported in binutils 2.12 either. So if it is for r6, why not require modern tools, and put something user readable in here? David Daney
On 06/02/2015 04:56 PM, David Daney wrote: > On 06/02/2015 09:15 AM, Maciej W. Rozycki wrote: >> On Tue, 2 Jun 2015, James Hogan wrote: >> >>> >>> binutils appears to support the sync_mb, sync_rmb, sync_wmb aliases >>> since version 2.21. Can we safely use them? >> >> I suggest that we don't -- we still officially support binutils >> 2.12 and >> have other places where we even use `.word' to insert instructions >> current >> versions of binutils properly handle. It may be worth noting in a >> comment >> though that these encodings correspond to these operations that you >> named. >> > > Surely the other MIPSr6 instructions are not supported in binutils > 2.12 either. So if it is for r6, why not require modern tools, and > put something user readable in here? > > No, it can be used for MIPS R2 also.
On Mon, Jun 01, 2015 at 05:09:34PM -0700, Leonid Yegoshin wrote:
Leonid,
to me the biggest technical problem with this patch is that the new Kconfig
option is user visible. This is the kind of deeply technical options
which exceeds the technical knowledge of most users, so it should probably
be driven by a select.
We probably also want to enquire how old CPUs from before the invention
of the stype field are behaving. If those as I hope for all treat an
stype != 0 as stype 0 we could simply drop the option. But we might
simply be out of luck - dunno.
Maciej,
do you have an R4000 / R4600 / R5000 / R7000 / SiByte system at hand to
test this? I think we don't need to test that SYNC actually works as
intended but the simpler test that SYNC <stype != 0> is not causing a
illegal instruction exception is sufficient, that is if something like
int main(int argc, charg *argv[])
{
asm(" .set mips2 \n"
" sync 0x10 \n"
" sync 0x13 \n"
" sync 0x04 \n"
" .set mips 0 \n");
return 0;
}
doesn't crash we should be ok.
The kernel's SYNC emulation should already be ok. We ignore the stype
field entirely and for a uniprocessor R2000/R3000 that should be just
the right thing.
Ralf
On Fri, 5 Jun 2015, Ralf Baechle wrote: > do you have an R4000 / R4600 / R5000 / R7000 / SiByte system at hand to > test this? I should be able to check R4400 (that is virtually the same as R4000) next week or so. As to SiByte -- not before next month I'm afraid. I don't have access to any of the other processors you named. You may want to find a better person if you want to accept this change soon. Maciej
On 06/05/2015 09:10, Ralf Baechle wrote: > On Mon, Jun 01, 2015 at 05:09:34PM -0700, Leonid Yegoshin wrote: > > Leonid, > > to me the biggest technical problem with this patch is that the new Kconfig > option is user visible. This is the kind of deeply technical options > which exceeds the technical knowledge of most users, so it should probably > be driven by a select. > > We probably also want to enquire how old CPUs from before the invention > of the stype field are behaving. If those as I hope for all treat an > stype != 0 as stype 0 we could simply drop the option. But we might > simply be out of luck - dunno. > > Maciej, > > do you have an R4000 / R4600 / R5000 / R7000 / SiByte system at hand to > test this? I think we don't need to test that SYNC actually works as > intended but the simpler test that SYNC <stype != 0> is not causing a > illegal instruction exception is sufficient, that is if something like > > int main(int argc, charg *argv[]) > { > asm(" .set mips2 \n" > " sync 0x10 \n" > " sync 0x13 \n" > " sync 0x04 \n" > " .set mips 0 \n"); > > return 0; > } > > doesn't crash we should be ok. > > The kernel's SYNC emulation should already be ok. We ignore the stype > field entirely and for a uniprocessor R2000/R3000 that should be just > the right thing. > > Ralf I tried just compiling this on my SGI O2, which has an RM7000 CPU, and it is refusing to even compile (after fixing typos): # gcc -O2 -pipe sync_test.c -o sync_test {standard input}: Assembler messages: {standard input}:19: Error: invalid operands `sync 0x10' {standard input}:20: Error: invalid operands `sync 0x13' {standard input}:21: Error: invalid operands `sync 0x04' So a bit of searching landed me here: http://stackoverflow.com/questions/3599564/gnu-assembler-for-mips-how-to-emit-sync-instructions And I recoded the sync insns like this: int main(int argc, char *argv[]) { __asm__ volatile ( \ " .set mips2 \n" " .word (0x0000000f | (0x10 << 6)) \n" " .word (0x0000000f | (0x14 << 6)) \n" " .word (0x0000000f | (0x04 << 6)) \n" " .set mips0 \n" ); return 0; } And the program compiles successfully and executes with no noticeable oddities or errors. Nothing in dmesg, no crashes, booms, or disappearance of small kittens. I did a quick disassembly to make sure all three got emitted: 004005e0 <main>: 4005e0: 27bdfff8 addiu sp,sp,-8 4005e4: afbe0004 sw s8,4(sp) 4005e8: 03a0f021 move s8,sp 4005ec: afc40008 sw a0,8(s8) 4005f0: afc5000c sw a1,12(s8) > 4005f4: 0000040f sync.p > 4005f8: 0000050f 0x50f > 4005fc: 0000010f 0x10f 400600: move v0,zero Same effect on my Octane (IP30) w/ an R14000 CPU. Tested inside a uclibc-based chroot, but no change. Executes successfully silently.
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index be384d6a58bb..c7d0cacece3d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1347,6 +1347,7 @@ config CPU_MIPS32_R2 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_HIGHMEM select CPU_SUPPORTS_MSA + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC select HAVE_KVM help Choose this option to build a kernel for release 2 or later of the @@ -1365,6 +1366,8 @@ config CPU_MIPS32_R6 select GENERIC_CSUM select HAVE_KVM select MIPS_O32_FP64_SUPPORT + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC + select WEAK_REORDERING_BEYOND_LLSC help Choose this option to build a kernel for release 6 or later of the MIPS32 architecture. New MIPS processors, starting with the Warrior @@ -1399,6 +1402,7 @@ config CPU_MIPS64_R2 select CPU_SUPPORTS_HIGHMEM select CPU_SUPPORTS_HUGEPAGES select CPU_SUPPORTS_MSA + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC help Choose this option to build a kernel for release 2 or later of the MIPS64 architecture. Many modern embedded systems with a 64-bit @@ -1415,6 +1419,8 @@ config CPU_MIPS64_R6 select CPU_SUPPORTS_HIGHMEM select CPU_SUPPORTS_MSA select GENERIC_CSUM + select CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC + select WEAK_REORDERING_BEYOND_LLSC help Choose this option to build a kernel for release 6 or later of the MIPS64 architecture. New MIPS processors, starting with the Warrior @@ -1876,6 +1882,20 @@ config WEAK_ORDERING # config WEAK_REORDERING_BEYOND_LLSC bool + +config MIPS_LIGHTWEIGHT_SYNC + bool "CPU lightweight SYNC instruction for weak reordering" + depends on CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC && WEAK_ORDERING + default y if CPU_MIPSR6 + help + This option enforces a use of "lightweight sync" instructions + for SMP (multi-CPU) memory barriers. This instructions are much + more faster than a traditional "SYNC 0". + + If that instructions are not implemented in processor then it is + converted to generic "SYNC 0". + + If you unsure, say N here, it may slightly decrease your performance endmenu # @@ -1928,6 +1948,8 @@ config CPU_SUPPORTS_HUGEPAGES bool config CPU_SUPPORTS_UNCACHED_ACCELERATED bool +config CPU_SUPPORTS_MIPS_LIGHTWEIGHT_SYNC + bool config MIPS_PGD_C0_CONTEXT bool default y if 64BIT && CPU_MIPSR2 && !CPU_XLP diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h index 2b8bbbcb9be0..d2a63abfc7c6 100644 --- a/arch/mips/include/asm/barrier.h +++ b/arch/mips/include/asm/barrier.h @@ -96,9 +96,15 @@ # define smp_rmb() barrier() # define smp_wmb() __syncw() # else +# ifdef CONFIG_MIPS_LIGHTWEIGHT_SYNC +# define smp_mb() __asm__ __volatile__("sync 0x10" : : :"memory") +# define smp_rmb() __asm__ __volatile__("sync 0x13" : : :"memory") +# define smp_wmb() __asm__ __volatile__("sync 0x4" : : :"memory") +# else # define smp_mb() __asm__ __volatile__("sync" : : :"memory") # define smp_rmb() __asm__ __volatile__("sync" : : :"memory") # define smp_wmb() __asm__ __volatile__("sync" : : :"memory") +# endif # endif #else #define smp_mb() barrier()
This instructions were specifically designed to work for smp_*() sort of memory barriers in MIPS R2/R3/R5 and R6. Unfortunately, it's description is very cryptic and is done in HW engineering style which prevents use of it by SW. This instructions are not mandatory but there is a mandatory requirement - if not implemented, then a regular MIPS SYNC 0 must be used instead. The reason for this change is - SYNC 0 is a heavvy-weighted in many CPUs, it may disrupt other cores pipelines etc. Due to concern about verification of old MIPS R2 compatible cores of other vendors it is enforced only for MIPS R6 and other MIPS32/64 R2/R5 processors have it configurable. Signed-off-by: Leonid Yegoshin <> --- arch/mips/Kconfig | 22 ++++++++++++++++++++++ arch/mips/include/asm/barrier.h | 6 ++++++ 2 files changed, 28 insertions(+)