diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index 04a5e46698a6..906889ed4582 100644 --- a/sys/alpha/alpha/machdep.c +++ b/sys/alpha/alpha/machdep.c @@ -140,10 +140,6 @@ #include #include -#ifdef SYSVSHM -#include -#endif - #ifdef SYSVMSG #include #endif @@ -331,9 +327,6 @@ cpu_startup(dummy) valloc(callout, struct callout, ncallout); valloc(callwheel, struct callout_tailq, callwheelsize); -#ifdef SYSVSHM - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif #ifdef SYSVSEM valloc(sema, struct semid_ds, seminfo.semmni); valloc(sem, struct sem, seminfo.semmns); diff --git a/sys/alpha/include/vmparam.h b/sys/alpha/include/vmparam.h index b055549c3ab8..bd085539ad93 100644 --- a/sys/alpha/include/vmparam.h +++ b/sys/alpha/include/vmparam.h @@ -94,14 +94,6 @@ #define USRIOSIZE 64 #endif -/* - * PTEs for system V style shared memory. - * This is basically slop for kmempt which we actually allocate (malloc) from. - */ -#ifndef SHMMAXPGS -#define SHMMAXPGS 1024 /* 8mb */ -#endif - /* * Boundary at which to place first MAPMEM segment if not explicitly * specified. Should be a power of two. This allows some slop for diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index b1fd32ad985c..f46d9ec385f1 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -73,10 +73,6 @@ #include #include -#ifdef SYSVSHM -#include -#endif - #ifdef SYSVMSG #include #endif @@ -329,9 +325,6 @@ cpu_startup(dummy) valloc(callout, struct callout, ncallout); valloc(callwheel, struct callout_tailq, callwheelsize); -#ifdef SYSVSHM - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif #ifdef SYSVSEM valloc(sema, struct semid_ds, seminfo.semmni); valloc(sem, struct sem, seminfo.semmns); diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h index 0a5847dd5ff6..b1081245ec4b 100644 --- a/sys/amd64/include/vmparam.h +++ b/sys/amd64/include/vmparam.h @@ -71,13 +71,6 @@ #define USRTEXT (1*PAGE_SIZE) /* base of user text XXX bogus */ -/* - * Size of the Shared Memory Pages page table. - */ -#ifndef SHMMAXPGS -#define SHMMAXPGS 1024 /* XXX until we have more kmap space */ -#endif - /* * The time for a process to be blocked before being very swappable. * This is a number of seconds which the system takes as being a non-trivial diff --git a/sys/conf/options b/sys/conf/options index 607e39e28561..d7c0090f12a0 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -67,6 +67,12 @@ SUIDDIR opt_suiddir.h SYSVMSG opt_sysvipc.h SYSVSEM opt_sysvipc.h SYSVSHM opt_sysvipc.h +SHMALL opt_sysvipc.h +SHMMAX opt_sysvipc.h +SHMMAXPGS opt_sysvipc.h +SHMMIN opt_sysvipc.h +SHMMNI opt_sysvipc.h +SHMSEG opt_sysvipc.h UCONSOLE ICMP_BANDLIM VFS_AIO @@ -142,12 +148,6 @@ SEMMNU opt_param.h SEMMSL opt_param.h SEMOPM opt_param.h SEMUME opt_param.h -SHMALL opt_param.h -SHMMAX opt_param.h -SHMMAXPGS opt_param.h -SHMMIN opt_param.h -SHMMNI opt_param.h -SHMSEG opt_param.h # Generic SCSI options. CAM_MAX_HIGHPOWER opt_cam.h diff --git a/sys/conf/param.c b/sys/conf/param.c index 7ae2ade9bdca..f26c3ba25870 100644 --- a/sys/conf/param.c +++ b/sys/conf/param.c @@ -46,10 +46,6 @@ #include -#ifdef SYSVSHM -#include -#include -#endif #ifdef SYSVSEM #include #endif @@ -90,35 +86,6 @@ int mbuf_wait = 32; /* mbuf sleep time in ticks */ #endif int nsfbufs = NSFBUFS; -/* - * Values in support of System V compatible shared memory. XXX - */ -#ifdef SYSVSHM -#ifndef SHMMAX -#define SHMMAX (SHMMAXPGS*PAGE_SIZE) -#endif -#ifndef SHMMIN -#define SHMMIN 1 -#endif -#ifndef SHMMNI -#define SHMMNI 32 /* <= SHMMMNI in shm.h */ -#endif -#ifndef SHMSEG -#define SHMSEG 8 -#endif -#ifndef SHMALL -#define SHMALL (SHMMAXPGS) -#endif - -struct shminfo shminfo = { - SHMMAX, - SHMMIN, - SHMMNI, - SHMSEG, - SHMALL -}; -#endif - /* * Values in support of System V compatible semaphores. */ diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index b1fd32ad985c..f46d9ec385f1 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -73,10 +73,6 @@ #include #include -#ifdef SYSVSHM -#include -#endif - #ifdef SYSVMSG #include #endif @@ -329,9 +325,6 @@ cpu_startup(dummy) valloc(callout, struct callout, ncallout); valloc(callwheel, struct callout_tailq, callwheelsize); -#ifdef SYSVSHM - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif #ifdef SYSVSEM valloc(sema, struct semid_ds, seminfo.semmni); valloc(sem, struct sem, seminfo.semmns); diff --git a/sys/i386/include/vmparam.h b/sys/i386/include/vmparam.h index 0a5847dd5ff6..b1081245ec4b 100644 --- a/sys/i386/include/vmparam.h +++ b/sys/i386/include/vmparam.h @@ -71,13 +71,6 @@ #define USRTEXT (1*PAGE_SIZE) /* base of user text XXX bogus */ -/* - * Size of the Shared Memory Pages page table. - */ -#ifndef SHMMAXPGS -#define SHMMAXPGS 1024 /* XXX until we have more kmap space */ -#endif - /* * The time for a process to be blocked before being very swappable. * This is a number of seconds which the system takes as being a non-trivial diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c index 7ae2ade9bdca..f26c3ba25870 100644 --- a/sys/kern/subr_param.c +++ b/sys/kern/subr_param.c @@ -46,10 +46,6 @@ #include -#ifdef SYSVSHM -#include -#include -#endif #ifdef SYSVSEM #include #endif @@ -90,35 +86,6 @@ int mbuf_wait = 32; /* mbuf sleep time in ticks */ #endif int nsfbufs = NSFBUFS; -/* - * Values in support of System V compatible shared memory. XXX - */ -#ifdef SYSVSHM -#ifndef SHMMAX -#define SHMMAX (SHMMAXPGS*PAGE_SIZE) -#endif -#ifndef SHMMIN -#define SHMMIN 1 -#endif -#ifndef SHMMNI -#define SHMMNI 32 /* <= SHMMMNI in shm.h */ -#endif -#ifndef SHMSEG -#define SHMSEG 8 -#endif -#ifndef SHMALL -#define SHMALL (SHMMAXPGS) -#endif - -struct shminfo shminfo = { - SHMMAX, - SHMMIN, - SHMMNI, - SHMSEG, - SHMALL -}; -#endif - /* * Values in support of System V compatible semaphores. */ diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 866a6ce6505c..83311b005e50 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -33,11 +33,13 @@ #include "opt_compat.h" #include "opt_rlimit.h" +#include "opt_sysvipc.h" #include #include #include #include +#include #include #include #include @@ -54,24 +56,11 @@ #include #include -#ifndef _SYS_SYSPROTO_H_ -struct shmat_args; -extern int shmat __P((struct proc *p, struct shmat_args *uap)); -struct shmctl_args; -extern int shmctl __P((struct proc *p, struct shmctl_args *uap)); -struct shmdt_args; -extern int shmdt __P((struct proc *p, struct shmdt_args *uap)); -struct shmget_args; -extern int shmget __P((struct proc *p, struct shmget_args *uap)); -#endif - static MALLOC_DEFINE(M_SHM, "shm", "SVID compatible shared memory segments"); -static void shminit __P((void *)); -SYSINIT(sysv_shm, SI_SUB_SYSV_SHM, SI_ORDER_FIRST, shminit, NULL) - struct oshmctl_args; static int oshmctl __P((struct proc *p, struct oshmctl_args *uap)); + static int shmget_allocate_segment __P((struct proc *p, struct shmget_args *uap, int mode)); static int shmget_existing __P((struct proc *p, struct shmget_args *uap, int mode, int segnum)); @@ -87,8 +76,8 @@ static sy_call_t *shmcalls[] = { #define SHMSEG_ALLOCATED 0x0800 #define SHMSEG_WANTED 0x1000 -static int shm_last_free, shm_nused, shm_committed; -struct shmid_ds *shmsegs; +static int shm_last_free, shm_nused, shm_committed, shmalloced; +static struct shmid_ds *shmsegs; struct shm_handle { /* vm_offset_t kva; */ @@ -104,6 +93,45 @@ static void shm_deallocate_segment __P((struct shmid_ds *)); static int shm_find_segment_by_key __P((key_t)); static struct shmid_ds *shm_find_segment_by_shmid __P((int)); static int shm_delete_mapping __P((struct proc *, struct shmmap_state *)); +static void shmrealloc __P((void)); +static void shminit __P((void *)); + +/* + * Tuneable values + */ +#ifndef SHMMAXPGS +#define SHMMAXPGS 1024 /* XXX increase this, it's not in kva! */ +#endif +#ifndef SHMMAX +#define SHMMAX (SHMMAXPGS*PAGE_SIZE) +#endif +#ifndef SHMMIN +#define SHMMIN 1 +#endif +#ifndef SHMMNI +#define SHMMNI 96 +#endif +#ifndef SHMSEG +#define SHMSEG 64 +#endif +#ifndef SHMALL +#define SHMALL (SHMMAXPGS) +#endif + +struct shminfo shminfo = { + SHMMAX, + SHMMIN, + SHMMNI, + SHMSEG, + SHMALL +}; + +SYSCTL_DECL(_kern_ipc); +SYSCTL_INT(_kern_ipc, OID_AUTO, shmmax, CTLFLAG_RW, &shminfo.shmmax, 0, ""); +SYSCTL_INT(_kern_ipc, OID_AUTO, shmmin, CTLFLAG_RW, &shminfo.shmmin, 0, ""); +SYSCTL_INT(_kern_ipc, OID_AUTO, shmmni, CTLFLAG_RD, &shminfo.shmmni, 0, ""); +SYSCTL_INT(_kern_ipc, OID_AUTO, shmseg, CTLFLAG_RW, &shminfo.shmseg, 0, ""); +SYSCTL_INT(_kern_ipc, OID_AUTO, shmall, CTLFLAG_RW, &shminfo.shmall, 0, ""); static int shm_find_segment_by_key(key) @@ -111,7 +139,7 @@ shm_find_segment_by_key(key) { int i; - for (i = 0; i < shminfo.shmmni; i++) + for (i = 0; i < shmalloced; i++) if ((shmsegs[i].shm_perm.mode & SHMSEG_ALLOCATED) && shmsegs[i].shm_perm.key == key) return i; @@ -126,7 +154,7 @@ shm_find_segment_by_shmid(shmid) struct shmid_ds *shmseg; segnum = IPCID_TO_IX(shmid); - if (segnum < 0 || segnum >= shminfo.shmmni) + if (segnum < 0 || segnum >= shmalloced) return NULL; shmseg = &shmsegs[segnum]; if ((shmseg->shm_perm.mode & (SHMSEG_ALLOCATED | SHMSEG_REMOVED)) @@ -473,11 +501,12 @@ shmget_allocate_segment(p, uap, mode) if (shm_committed + btoc(size) > shminfo.shmall) return ENOMEM; if (shm_last_free < 0) { - for (i = 0; i < shminfo.shmmni; i++) + shmrealloc(); /* maybe expand the shmsegs[] array */ + for (i = 0; i < shmalloced; i++) if (shmsegs[i].shm_perm.mode & SHMSEG_FREE) break; - if (i == shminfo.shmmni) - panic("shmseg free count inconsistent"); + if (i == shmalloced) + return ENOSPC; segnum = i; } else { segnum = shm_last_free; @@ -600,12 +629,40 @@ shmexit(p) p->p_vmspace->vm_shm = NULL; } -void +static void +shmrealloc(void) +{ + int i; + struct shmid_ds *newsegs; + + if (shmalloced >= shminfo.shmmni) + return; + + newsegs = malloc(shminfo.shmmni * sizeof(*newsegs), M_SHM, M_WAITOK); + if (newsegs == NULL) + return; + for (i = 0; i < shmalloced; i++) + bcopy(&shmsegs[i], &newsegs[i], sizeof(newsegs[0])); + for (; i < shminfo.shmmni; i++) { + shmsegs[i].shm_perm.mode = SHMSEG_FREE; + shmsegs[i].shm_perm.seq = 0; + } + free(shmsegs, M_SHM); + shmsegs = newsegs; + shmalloced = shminfo.shmmni; +} + +static void shminit(dummy) void *dummy; { int i; - for (i = 0; i < shminfo.shmmni; i++) { + + shmalloced = shminfo.shmmni; + shmsegs = malloc(shmalloced * sizeof(shmsegs[0]), M_SHM, M_WAITOK); + if (shmsegs == NULL) + panic("cannot allocate initial memory for sysvshm"); + for (i = 0; i < shmalloced; i++) { shmsegs[i].shm_perm.mode = SHMSEG_FREE; shmsegs[i].shm_perm.seq = 0; } @@ -613,3 +670,4 @@ shminit(dummy) shm_nused = 0; shm_committed = 0; } +SYSINIT(sysv_shm, SI_SUB_SYSV_SHM, SI_ORDER_FIRST, shminit, NULL); diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c index 38a976ece2be..d6d3691b4a63 100644 --- a/sys/pc98/i386/machdep.c +++ b/sys/pc98/i386/machdep.c @@ -73,10 +73,6 @@ #include #include -#ifdef SYSVSHM -#include -#endif - #ifdef SYSVMSG #include #endif @@ -342,9 +338,6 @@ cpu_startup(dummy) valloc(callout, struct callout, ncallout); valloc(callwheel, struct callout_tailq, callwheelsize); -#ifdef SYSVSHM - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif #ifdef SYSVSEM valloc(sema, struct semid_ds, seminfo.semmni); valloc(sem, struct sem, seminfo.semmns); diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c index 38a976ece2be..d6d3691b4a63 100644 --- a/sys/pc98/pc98/machdep.c +++ b/sys/pc98/pc98/machdep.c @@ -73,10 +73,6 @@ #include #include -#ifdef SYSVSHM -#include -#endif - #ifdef SYSVMSG #include #endif @@ -342,9 +338,6 @@ cpu_startup(dummy) valloc(callout, struct callout, ncallout); valloc(callwheel, struct callout_tailq, callwheelsize); -#ifdef SYSVSHM - valloc(shmsegs, struct shmid_ds, shminfo.shmmni); -#endif #ifdef SYSVSEM valloc(sema, struct semid_ds, seminfo.semmni); valloc(sem, struct sem, seminfo.semmns);