mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-17 15:27:36 +00:00
Correct types of variables used to track amount of allocated SysV shared
memory from int to size_t. Implement a workaround for current ABI not allowing to properly save size for and report more then 2Gb sized segment of shared memory. This makes it possible to use > 2 Gb shared memory segments on 64bit architectures. Please note the new BUGS section in shmctl(2) and UPDATING note for limitations of this temporal solution. Reviewed by: csjp Tested by: Nikolay Dzham <i levsha org ua> MFC after: 2 weeks
This commit is contained in:
parent
2883703e00
commit
65067cc8b0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=189283
8
UPDATING
8
UPDATING
@ -22,6 +22,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
|
||||
to maximize performance. (To disable malloc debugging, run
|
||||
ln -s aj /etc/malloc.conf.)
|
||||
|
||||
20090302:
|
||||
The workaround is committed to allow to create System V shared
|
||||
memory segment of size > 2 Gb on the 64-bit architectures.
|
||||
Due to limitation of the existing ABI, the shm_segsz member
|
||||
of the struct shmid_ds, returned by shmctl(IPC_STAT) call is
|
||||
wrong for large segments. Note that limits shall be explicitely
|
||||
raised to allow such segments to be created.
|
||||
|
||||
20090301:
|
||||
The layout of struct ifnet has changed, requiring a rebuild of all
|
||||
network device driver modules.
|
||||
|
@ -133,6 +133,15 @@ the shared memory segment's owner or creator.
|
||||
Permission denied due to mismatch between operation and mode of
|
||||
shared memory segment.
|
||||
.El
|
||||
.Sh "BUGS"
|
||||
The shm_segsz member of the
|
||||
.Vt shmid_ds
|
||||
structure has int type, that is too short to represent full range
|
||||
of the values for segment size, which is allowed to be size_t.
|
||||
If shared memory limits are raised to allow segments with size > 2 Gb
|
||||
to be created, be aware that IPC_STAT call may return truncated value
|
||||
for shm_segsz.
|
||||
.El
|
||||
.Sh "SEE ALSO"
|
||||
.Xr shmat 2 ,
|
||||
.Xr shmdt 2 ,
|
||||
|
@ -121,7 +121,8 @@ static sy_call_t *shmcalls[] = {
|
||||
#define SHMSEG_ALLOCATED 0x0800
|
||||
#define SHMSEG_WANTED 0x1000
|
||||
|
||||
static int shm_last_free, shm_nused, shm_committed, shmalloced;
|
||||
static int shm_last_free, shm_nused, shmalloced;
|
||||
size_t shm_committed;
|
||||
static struct shmid_kernel *shmsegs;
|
||||
|
||||
struct shmmap_state {
|
||||
@ -250,7 +251,7 @@ shm_deallocate_segment(shmseg)
|
||||
|
||||
vm_object_deallocate(shmseg->u.shm_internal);
|
||||
shmseg->u.shm_internal = NULL;
|
||||
size = round_page(shmseg->u.shm_segsz);
|
||||
size = round_page(shmseg->shm_bsegsz);
|
||||
shm_committed -= btoc(size);
|
||||
shm_nused--;
|
||||
shmseg->u.shm_perm.mode = SHMSEG_FREE;
|
||||
@ -270,7 +271,7 @@ shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s)
|
||||
|
||||
segnum = IPCID_TO_IX(shmmap_s->shmid);
|
||||
shmseg = &shmsegs[segnum];
|
||||
size = round_page(shmseg->u.shm_segsz);
|
||||
size = round_page(shmseg->shm_bsegsz);
|
||||
result = vm_map_remove(&vm->vm_map, shmmap_s->va, shmmap_s->va + size);
|
||||
if (result != KERN_SUCCESS)
|
||||
return (EINVAL);
|
||||
@ -390,7 +391,7 @@ kern_shmat(td, shmid, shmaddr, shmflg)
|
||||
error = EMFILE;
|
||||
goto done2;
|
||||
}
|
||||
size = round_page(shmseg->u.shm_segsz);
|
||||
size = round_page(shmseg->shm_bsegsz);
|
||||
#ifdef VM_PROT_READ_IS_EXEC
|
||||
prot = VM_PROT_READ | VM_PROT_EXECUTE;
|
||||
#else
|
||||
@ -422,7 +423,8 @@ kern_shmat(td, shmid, shmaddr, shmflg)
|
||||
|
||||
vm_object_reference(shmseg->u.shm_internal);
|
||||
rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->u.shm_internal,
|
||||
0, &attach_va, size, (flags & MAP_FIXED)?0:1, prot, prot, 0);
|
||||
0, &attach_va, size, (flags & MAP_FIXED) ? VMFS_NO_SPACE :
|
||||
VMFS_ANY_SPACE, prot, prot, 0);
|
||||
if (rv != KERN_SUCCESS) {
|
||||
vm_object_deallocate(shmseg->u.shm_internal);
|
||||
error = ENOMEM;
|
||||
@ -720,7 +722,7 @@ shmget_existing(td, uap, mode, segnum)
|
||||
if (error != 0)
|
||||
return (error);
|
||||
#endif
|
||||
if (uap->size && uap->size > shmseg->u.shm_segsz)
|
||||
if (uap->size && uap->size > shmseg->shm_bsegsz)
|
||||
return (EINVAL);
|
||||
td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm);
|
||||
return (0);
|
||||
@ -732,7 +734,8 @@ shmget_allocate_segment(td, uap, mode)
|
||||
struct shmget_args *uap;
|
||||
int mode;
|
||||
{
|
||||
int i, segnum, shmid, size;
|
||||
int i, segnum, shmid;
|
||||
size_t size;
|
||||
struct ucred *cred = td->td_ucred;
|
||||
struct shmid_kernel *shmseg;
|
||||
vm_object_t shm_object;
|
||||
@ -790,6 +793,7 @@ shmget_allocate_segment(td, uap, mode)
|
||||
shmseg->u.shm_perm.mode = (shmseg->u.shm_perm.mode & SHMSEG_WANTED) |
|
||||
(mode & ACCESSPERMS) | SHMSEG_ALLOCATED;
|
||||
shmseg->u.shm_segsz = uap->size;
|
||||
shmseg->shm_bsegsz = uap->size;
|
||||
shmseg->u.shm_cpid = td->td_proc->p_pid;
|
||||
shmseg->u.shm_lpid = shmseg->u.shm_nattch = 0;
|
||||
shmseg->u.shm_atime = shmseg->u.shm_dtime = 0;
|
||||
|
@ -108,6 +108,7 @@ struct shminfo {
|
||||
struct shmid_kernel {
|
||||
struct shmid_ds u;
|
||||
struct label *label; /* MAC label */
|
||||
size_t shm_bsegsz;
|
||||
};
|
||||
|
||||
extern struct shminfo shminfo;
|
||||
|
@ -452,8 +452,8 @@ print_kshmptr(int i, int option, struct shmid_kernel *kshmptr)
|
||||
kshmptr->u.shm_nattch);
|
||||
|
||||
if (option & BIGGEST)
|
||||
printf(" %12d",
|
||||
kshmptr->u.shm_segsz);
|
||||
printf(" %12zu",
|
||||
kshmptr->shm_bsegsz);
|
||||
|
||||
if (option & PID)
|
||||
printf(" %12d %12d",
|
||||
|
Loading…
Reference in New Issue
Block a user