Change SYSV SHM to allow more than 2GB of memory allocation.
* Basically this means a change from int to size_t in
the appropriate places.
* Tested on X86_64 using PostgreSQL configured with
2GB of shared_buffers and kern.ipc.shmmax set to 3GB.
In-Colloboration-With (libc stuff):
Sascha Wildner <saw@online.de>
/*
* $FreeBSD: src/lib/libc/gen/shmat.c,v 1.4 1999/08/27 23:58:56 peter Exp $
- * $DragonFly: src/lib/libc/gen/shmat.c,v 1.4 2005/11/19 22:32:53 swildner Exp $
*/
#include <sys/types.h>
#include <sys/shm.h>
void *
-shmat(int shmid, void *shmaddr, int shmflg)
+shmat(int shmid, const void *shmaddr, int shmflg)
{
return ((void *)shmsys(0, shmid, shmaddr, shmflg));
}
/*
* $FreeBSD: src/lib/libc/gen/shmdt.c,v 1.4 1999/08/27 23:58:57 peter Exp $
- * $DragonFly: src/lib/libc/gen/shmdt.c,v 1.3 2005/11/13 00:07:42 swildner Exp $
*/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
-int shmdt(void *shmaddr)
+int shmdt(const void *shmaddr)
{
return (shmsys(2, shmaddr));
}
/*
* $FreeBSD: src/lib/libc/gen/shmget.c,v 1.4 1999/08/27 23:58:57 peter Exp $
- * $DragonFly: src/lib/libc/gen/shmget.c,v 1.3 2005/11/13 00:07:42 swildner Exp $
*/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
-int shmget(key_t key, int size, int shmflg)
+int shmget(key_t key, size_t size, int shmflg)
{
return (shmsys(3, key, size, shmflg));
}
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD: src/lib/libc/sys/shmat.2,v 1.8.2.6 2001/12/14 18:34:01 ru Exp $
-.\" $DragonFly: src/lib/libc/sys/shmat.2,v 1.2 2003/06/17 04:26:47 dillon Exp $
.\"
-.Dd August 2, 1995
+.Dd January 17, 2010
.Dt SHMAT 2
.Os
.Sh NAME
.In sys/ipc.h
.In sys/shm.h
.Ft void *
-.Fn shmat "int shmid" "void *addr" "int flag"
+.Fn shmat "int shmid" "const void *addr" "int flag"
.Ft int
-.Fn shmdt "void *addr"
+.Fn shmdt "const void *addr"
.Sh DESCRIPTION
.Fn Shmat
attaches the shared memory segment identified by
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD: src/lib/libc/sys/shmctl.2,v 1.9.2.4 2001/12/14 18:34:01 ru Exp $
-.\" $DragonFly: src/lib/libc/sys/shmctl.2,v 1.2 2003/06/17 04:26:47 dillon Exp $
.\"
-.Dd July 17, 1995
+.Dd January 17, 2010
.Dt SHMCTL 2
.Os
.Sh NAME
.\" with nroff, but otherwise it's straight from sys/shm.h
.\"
.Bd -literal
+typedef unsigned int shmatt_t;
+
struct shmid_ds {
struct ipc_perm shm_perm; /* operation permission structure */
- int shm_segsz; /* size of segment in bytes */
- pid_t shm_lpid; /* process ID of last shared memory op */
+ size_t shm_segsz; /* size of segment in bytes */
+ pid_t shm_lpid; /* process ID of last shm operation */
pid_t shm_cpid; /* process ID of creator */
- short shm_nattch; /* number of current attaches */
+ shmatt_t shm_nattch; /* number of current attaches */
time_t shm_atime; /* time of last shmat() */
time_t shm_dtime; /* time of last shmdt() */
time_t shm_ctime; /* time of last change by shmctl() */
.\" $FreeBSD: src/lib/libc/sys/shmget.2,v 1.8.2.6 2001/12/14 18:34:01 ru Exp $
.\" $DragonFly: src/lib/libc/sys/shmget.2,v 1.2 2003/06/17 04:26:47 dillon Exp $
.\"
-.Dd July 3, 1995
+.Dd January 17, 2010
.Dt SHMGET 2
.Os
.Sh NAME
.In sys/ipc.h
.In sys/shm.h
.Ft int
-.Fn shmget "key_t key" "int size" "int flag"
+.Fn shmget "key_t key" "size_t size" "int flag"
.Sh DESCRIPTION
Based on the values of
.Fa key
int msgflg); }
227 STD BSD { int msgrcv(int msqid, void *msgp, size_t msgsz, \
long msgtyp, int msgflg); }
-228 STD BSD { caddr_t shmat(int shmid, void *shmaddr, int shmflg); }
+228 STD BSD { caddr_t shmat(int shmid, const void *shmaddr, \
+ int shmflg); }
229 STD BSD { int shmctl(int shmid, int cmd, \
struct shmid_ds *buf); }
-230 STD BSD { int shmdt(void *shmaddr); }
-231 STD BSD { int shmget(key_t key, int size, int shmflg); }
+230 STD BSD { int shmdt(const void *shmaddr); }
+231 STD BSD { int shmget(key_t key, size_t size, int shmflg); }
;
232 STD POSIX { int clock_gettime(clockid_t clock_id, \
struct timespec *tp); }
#define SHMSEG_ALLOCATED 0x0800
#define SHMSEG_WANTED 0x1000
-static int shm_last_free, shm_committed, shmalloced;
+static int shm_last_free, shmalloced;
+size_t shm_committed;
int shm_nused;
static struct shmid_ds *shmsegs;
static int shm_use_phys;
-TUNABLE_INT("kern.ipc.shmmin", &shminfo.shmmin);
-TUNABLE_INT("kern.ipc.shmmni", &shminfo.shmmni);
-TUNABLE_INT("kern.ipc.shmseg", &shminfo.shmseg);
-TUNABLE_INT("kern.ipc.shmmaxpgs", &shminfo.shmall);
+TUNABLE_ULONG("kern.ipc.shmmin", &shminfo.shmmin);
+TUNABLE_ULONG("kern.ipc.shmmni", &shminfo.shmmni);
+TUNABLE_ULONG("kern.ipc.shmseg", &shminfo.shmseg);
+TUNABLE_ULONG("kern.ipc.shmmaxpgs", &shminfo.shmall);
TUNABLE_INT("kern.ipc.shm_use_phys", &shm_use_phys);
-SYSCTL_INT(_kern_ipc, OID_AUTO, shmmax, CTLFLAG_RW, &shminfo.shmmax, 0,
+SYSCTL_ULONG(_kern_ipc, OID_AUTO, shmmax, CTLFLAG_RW, &shminfo.shmmax, 0,
"Max shared memory segment size");
-SYSCTL_INT(_kern_ipc, OID_AUTO, shmmin, CTLFLAG_RW, &shminfo.shmmin, 0,
+SYSCTL_ULONG(_kern_ipc, OID_AUTO, shmmin, CTLFLAG_RW, &shminfo.shmmin, 0,
"Min shared memory segment size");
-SYSCTL_INT(_kern_ipc, OID_AUTO, shmmni, CTLFLAG_RD, &shminfo.shmmni, 0,
+SYSCTL_ULONG(_kern_ipc, OID_AUTO, shmmni, CTLFLAG_RD, &shminfo.shmmni, 0,
"Max number of shared memory identifiers");
SYSCTL_INT(_kern_ipc, OID_AUTO, shmseg, CTLFLAG_RW, &shminfo.shmseg, 0,
"Max shared memory segments per process");
-SYSCTL_INT(_kern_ipc, OID_AUTO, shmall, CTLFLAG_RW, &shminfo.shmall, 0,
+SYSCTL_ULONG(_kern_ipc, OID_AUTO, shmall, CTLFLAG_RW, &shminfo.shmall, 0,
"Max pages of shared memory");
SYSCTL_INT(_kern_ipc, OID_AUTO, shm_use_phys, CTLFLAG_RW, &shm_use_phys, 0,
"Use phys pager allocation instead of swap pager allocation");
static int
shmget_allocate_segment(struct proc *p, struct shmget_args *uap, int mode)
{
- int i, segnum, shmid, size;
+ int i, segnum, shmid;
+ size_t size;
struct ucred *cred = p->p_ucred;
struct shmid_ds *shmseg;
struct shm_handle *shm_handle;
/* $FreeBSD: src/sys/sys/shm.h,v 1.14 1999/12/29 04:24:46 peter Exp $ */
-/* $DragonFly: src/sys/sys/shm.h,v 1.6 2006/09/30 20:03:44 swildner Exp $ */
/* $NetBSD: shm.h,v 1.15 1994/06/29 06:45:17 cgd Exp $ */
/*
#define SHM_R (IPC_R)
#define SHM_W (IPC_W)
+typedef unsigned int shmatt_t;
struct shmid_ds {
struct ipc_perm shm_perm; /* operation permission structure */
- int shm_segsz; /* size of segment in bytes */
- pid_t shm_lpid; /* process ID of last shared memory op */
+ size_t shm_segsz; /* size of segment in bytes */
+ pid_t shm_lpid; /* process ID of last shm operation */
pid_t shm_cpid; /* process ID of creator */
- short shm_nattch; /* number of current attaches */
+ shmatt_t shm_nattch; /* number of current attaches */
time_t shm_atime; /* time of last shmat() */
time_t shm_dtime; /* time of last shmdt() */
time_t shm_ctime; /* time of last change by shmctl() */
* might be of interest to user programs. Do we really want/need this?
*/
struct shminfo {
- int shmmax, /* max shared memory segment size (bytes) */
+ u_long shmmax, /* max shared memory segment size (bytes) */
shmmin, /* min shared memory segment size (bytes) */
shmmni, /* max number of shared memory identifiers */
shmseg, /* max shared memory segments per process */
__BEGIN_DECLS
int shmsys (int, ...);
-void *shmat (int, void *, int);
-int shmget (key_t, int, int);
+void *shmat (int, const void *, int);
+int shmget (key_t, size_t, int);
int shmctl (int, int, struct shmid_ds *);
-int shmdt (void *);
+int shmdt (const void *);
__END_DECLS
#endif /* !_KERNEL */
struct sysmsg sysmsg;
#endif
int shmid; char shmid_[PAD_(int)];
- void * shmaddr; char shmaddr_[PAD_(void *)];
+ const void * shmaddr; char shmaddr_[PAD_(const void *)];
int shmflg; char shmflg_[PAD_(int)];
};
struct shmctl_args {
#ifdef _KERNEL
struct sysmsg sysmsg;
#endif
- void * shmaddr; char shmaddr_[PAD_(void *)];
+ const void * shmaddr; char shmaddr_[PAD_(const void *)];
};
struct shmget_args {
#ifdef _KERNEL
struct sysmsg sysmsg;
#endif
key_t key; char key_[PAD_(key_t)];
- int size; char size_[PAD_(int)];
+ size_t size; char size_[PAD_(size_t)];
int shmflg; char shmflg_[PAD_(int)];
};
struct clock_gettime_args {