SHMLBA and compat tasks
The current Linux implementation of shmat() insists on SHMLBA alignment even when shmflg & SHM_RND == 0. This is not consistent with the man pages and the single UNIX spec, which require only a page-aligned address.
man page:
Quoted 4 lines
If shmaddr isn’t NULL and
SHM_RNDis asserted in shmflg, the attach occurs at the address equal to shmaddr rounded down to the nearest mul- tiple of SHMLBA. Otherwise shmaddr must be a page-aligned address at which the attach occurs.
This is not a problem for many platforms because SHMLBA == PAGE_SIZE. It's also not a problem for 64 bit programs running on 64 bit platforms, because arch_get_unmapped_area() typically guarantees SHMLBA alignment, even when SHM_RND is not asserted.
However, for 32 bit compatiblity programs, an innocuous sequence such as:
p = shmat(id, 0, shmflg) /* shmflag & SHM_RND == 0 */ /* p is page-aligned, but may not be SHMLBA aligned */ shmdt(p)shmat(id, p, shmflg) == -EINVAL ??
can fail. The attached patch fixes the problem for ia64. Can other arch maintainers confirm that it doesn't break anything for you ?
-Arun
ipc/shm.c renamed from ipc/shm.c.orig +1 -1
@@ -600,7 +600,7 @@if (addr & (SHMLBA -1 )) {if (shmflg &SHM_RND ) addr &= ~(SHMLBA -1 );/* round down */ -else +else if (addr & ~PAGE_MASK )return -EINVAL ; } flags =MAP_SHARED |MAP_FIXED ;
Quoted 6 lines · On Fri, 27 Feb 2004 17:41:28 -0800 Arun Sharma <[email protected]> wrote:
man page:
Quoted 4 lines
If shmaddr isn’t NULL and
SHM_RNDis asserted in shmflg, the attach occurs at the address equal to shmaddr rounded down to the nearest mul- tiple of SHMLBA. Otherwise shmaddr must be a page-aligned address at which the attach occurs.
When the user specifies a specific address, things get real interesting because of cache aliasing issues.
Platforms with virtually indexed caches use SHMLBA of a size such that it is the largest cache virtual aliasing factor. In this way, processes with different SHM mappings of the shared writable memory will immediately see writes done by other processes and aliases cannot enter the cache due to virtual addresses being "just right".
Otherwise we'll need to special case now this SHM_RND thing and mark PTE's as non-cacheable and other horrible things like this, and in fact this particular scheme is not even possible on some architectures.
So your proposal is going to break things for some people, sparc64, mips, parisc, and probably a slew of others.
Quoted 6 lines · David S. Miller
Platforms with virtually indexed caches use SHMLBA of a size such that it is the largest cache virtual aliasing factor. In this way, processes with different SHM mappings of the shared writable memory will immediately see writes done by other processes and aliases cannot enter the cache due to virtual addresses being "just right".
I read that to mean that there is a correctness problem, apart from performance issues on some platforms.
How about something like:
else
#ifndef ARCH_HAS_VCACHE
if (addr & ~PAGE_MASK)
#endif
return -EINVAL;
So that platforms with virtually indexed caches are not affected ?
-Arun
Quoted 5 lines · On Sat, 28 Feb 2004 18:11:06 -0800 Arun Sharma <[email protected]> wrote:
I read that to mean that there is a correctness problem, apart from performance issues on some platforms.
How about something like:
Quoted 7 lines
else
#ifndefARCH_HAS_VCACHE
if (addr & ~PAGE_MASK)
#endif
return-EINVAL;So that platforms with virtually indexed caches are not affected ?
By your own admittance this will break the conformance in question on such architectures, and it's also bad to have different rules like this in general.
Why don't we declare that SHM_LBA must be abided by on all platforms? POSIX is not a high and mighty law which we must follow blindly, to me this restriction is nonsensicle and supporting it fully will cause more grief than just declaring that we don't support it.
Quoted 2 lines · David S. Miller
Why don't we declare that
SHM_LBAmust be abided by on all platforms?
I assume you're proposing changing the man page to say that SHMLBA will be forced, in all cases (even though SHM_RND is not specified). Yes, that would make the implementation consistent with the man page, so it'd be an improvement over the current situation.
But ia32 on ia64 doesn't match this declaration today.
shmat(id, 0, ...)
can return an address that's PAGE_SIZE aligned, but not SHMLBA aligned.
David, are you ok with changing this code to force SHMLBA alignment for both 32 and 64 bit tasks ?
-Arun
arch/ia64/kernel/sys_ia64.c:
arch_get_unmapped_area(...)
{
...
if (map_shared && (TASK_SIZE > 0xfffffffful))
/*
* For 64-bit tasks, align shared segments to 1MB to avoid potential
* performance penalty due to virtual aliasing (see ASDM). For 32-bit
* tasks, we prefer to avoid exhausting the address space too quickly by
* limiting alignment to a single page.
*/
align_mask = SHMLBA - 1;
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · Arun Sharma
Arun> David, are you ok with changing this code to force SHMLBA Arun> alignment for both 32 and 64 bit tasks ?
I assume you're asking me here (too many David's!). The answer is that it's NOT OK to force 1MB alignment for IA-32 tasks. It'll eat up address space like there is no tomorrow. In fact, the reason the code is there is because some versions of the open-office installer used to crash due to address-space exhaustion. Probably a bug in open-office, but the point is that for ia32-emulation purposes, we want/need to be bug-for-bug compatible with x86.
--david
Quoted 2 lines · On Mon, 1 Mar 2004 11:41:01 -0800 David Mosberger <[email protected]>…
I assume you're asking me here (too many David's!). The answer is that it's NOT OK to force 1MB alignment for IA-32 tasks.
Why exactly is SHMLBA 1MB, something to do with the ia64 address space segments or something?
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · David S. Miller
DaveM> On Mon, 1 Mar 2004 11:41:01 -0800
Quoted 2 lines · DaveM> David Mosberger <[email protected]> wrote:
Quoted 2 lines
I assume you're asking me here (too many David's!). The answer is that it's NOT OK to force 1MB alignment for IA-32 tasks.
DaveM> Why exactly is SHMLBA 1MB, something to do with the ia64 address DaveM> space segments or something?
The architecture reserves the right to impose a performance penalty for aliases which are not congruent modulo 1MB. None of the current CPUs do that but future CPUs _could_ do that (well, I hope they never will, but we do want to be compliant with the architecture, just in case).
--david
Quoted 2 lines · David Mosberger
I assume you're asking me here (too many David's!).
Virtual name cache aliasing ? :)
Quoted 6 lines
The answer is that it's NOT OK to force 1MB alignment for IA-32 tasks. It'll eat up address space like there is no tomorrow. In fact, the reason the code is there is because some versions of the open-office installer used to crash due to address-space exhaustion. Probably a bug in open-office, but the point is that for ia32-emulation purposes, we want/need to be bug-for-bug compatible with x86.
Sounds like we have sufficient grounds for using different alignment rules for different architectures ?
-Arun
Quoted 2 lines · Arun Sharma
Sounds like we have sufficient grounds for using different alignment rules for different architectures ?
#ifndef COMPAT_SHMLBA
#define COMPAT_SHMLBA SHMLBA
#endif
should be enough, no?
Signature · 6 lines
"Next the statesmen will invent cheap lies, putting the blame upon the nation that is attacked, and every man will be glad of those conscience-soothing falsities, and will diligently study them, and refuse to examine any refutations of them; and thus he will by and by convince himself that the war is just, and will thank God for the better sleep he enjoys after this process of grotesque self-deception." -- Mark Twain
Quoted 9 lines · Matthew Wilcox
Quoted 2 lines · Arun Sharma
Sounds like we have sufficient grounds for using different alignment rules for different architectures ?
#ifndef
COMPAT_SHMLBA
#defineCOMPAT_SHMLBASHMLBA
#endifshould be enough, no?
I'm concerned that we'll have to duplicate/inline much of sys_shmat() in ipc/compat.c and it might become a maintenance problem. Perhaps there is a way to do it in a better way, but I don't see it.
An ifdef in sys_shmat() that distinugishes between architectures that enforce SHMLBA in all cases and the ones which don't would be ideal for my purposes.
-Arun
Quoted 8 lines · Arun Sharma
I'm concerned that we'll have to duplicate/inline much of
sys_shmat()inipc/compat.cand it might become a maintenance problem. Perhaps there is a way to do it in a better way, but I don't see it.An ifdef in
sys_shmat()that distinugishes between architectures that enforce SHMLBA in all cases and the ones which don't would be ideal for my purposes.
Since nobody objected to this approach, I'd like to propose this patch.
-Arun
Index: linux-2.6-cvs/include/asm-mips/shmparam.h
===================================================================
RCS file: /home/adsharma/disk2/cvs/linux-2.5/include/asm-mips/shmparam.h,v retrieving revision 1.3
include/asm-mips/shmparam.h +2 -0
@@ -6,6 +6,8 @@#ifndef _ASM_SHMPARAM_H#define _ASM_SHMPARAM_H +#define __ARCH_FORCE_SHMLBA 1 +#define SHMLBA 0x40000/* attach addr a multiple of this */ #endif /* _ASM_SHMPARAM_H */
Index: linux-2.6-cvs/include/asm-parisc/shmparam.h
===================================================================
RCS file: /home/adsharma/disk2/cvs/linux-2.5/include/asm-parisc/shmparam.h,v retrieving revision 1.3
include/asm-parisc/shmparam.h +2 -0
@@ -1,6 +1,8 @@#ifndef _ASMPARISC_SHMPARAM_H#define _ASMPARISC_SHMPARAM_H +#define __ARCH_FORCE_SHMLBA 1 +#define SHMLBA 0x00400000/* attach addr needs to be 4 Mb aligned */ #endif /* _ASMPARISC_SHMPARAM_H */
Index: linux-2.6-cvs/include/asm-sparc/shmparam.h
===================================================================
RCS file: /home/adsharma/disk2/cvs/linux-2.5/include/asm-sparc/shmparam.h,v retrieving revision 1.2
include/asm-sparc/shmparam.h +2 -0
@@ -2,6 +2,8 @@#ifndef _ASMSPARC_SHMPARAM_H#define _ASMSPARC_SHMPARAM_H +#define __ARCH_FORCE_SHMLBA 1 +extern int vac_cache_size;#define SHMLBA (vac_cache_size ? vac_cache_size : \ (sparc_cpu_model == sun4c ? (64 * 1024) : \
Index: linux-2.6-cvs/include/asm-sparc64/shmparam.h
===================================================================
RCS file: /home/adsharma/disk2/cvs/linux-2.5/include/asm-sparc64/shmparam.h,v retrieving revision 1.3
include/asm-sparc64/shmparam.h +1 -0
@@ -4,6 +4,7 @@#include <asm/spitfire.h> +#define __ARCH_FORCE_SHMLBA 1/* attach addr a multiple of this */ #define SHMLBA ((PAGE_SIZE > L1DCACHE_SIZE) ? PAGE_SIZE : L1DCACHE_SIZE)
Index: linux-2.6-cvs/ipc/shm.c
===================================================================
RCS file: /home/adsharma/disk2/cvs/linux-2.5/ipc/shm.c,v retrieving revision 1.32
ipc/shm.c +5 -2
@@ -655,8 +655,11 @@if (addr & (SHMLBA -1 )) {if (shmflg &SHM_RND ) addr &= ~(SHMLBA -1 );/* round down */ -else -return -EINVAL ; + else +#ifndef __ARCH_FORCE_SHMLBA + if (addr & ~PAGE_MASK) +#endif +return -EINVAL ; } flags =MAP_SHARED |MAP_FIXED ; }else {
Quoted 1 line · On Fri, 5 Mar 2004 18:37:40 -0800 Arun Sharma <[email protected]> wrote:
Since nobody objected to this approach, I'd like to propose this patch.
I'm not going to object to this patch, although I dearly wished all platforms would behave consistently.