svn commit: r189740 - in stable/7: . lib/libc lib/libc/string lib/libc/sys sys sys/contrib/pf sys/dev/ath/ath_hal sys/dev/cxgb sys/kern sys/sys

Konstantin Belousov kib at FreeBSD.org
Thu Mar 12 06:45:57 PDT 2009


Author: kib
Date: Thu Mar 12 13:45:55 2009
New Revision: 189740
URL: http://svn.freebsd.org/changeset/base/189740

Log:
  MFC r189283:
  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.
  
  MFC r189398:
  Systematically use vm_size_t to specify the size of the segment for VM KPI.
  Do not overload the local variable size in kern_shmat() due to vm_size_t
  change.
  Fix style bug by adding explicit comparision with 0.
  
  MFC r189399:
  Improve the grammar and wording in the changes to shmctl(2) manpage.
  
  Put an UPDATING entry and bump __FreeBSD_version for the change.

Modified:
  stable/7/UPDATING
  stable/7/lib/libc/   (props changed)
  stable/7/lib/libc/string/ffsll.c   (props changed)
  stable/7/lib/libc/string/flsll.c   (props changed)
  stable/7/lib/libc/sys/shmctl.2
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/kern/sysv_shm.c
  stable/7/sys/sys/param.h
  stable/7/sys/sys/shm.h

Modified: stable/7/UPDATING
==============================================================================
--- stable/7/UPDATING	Thu Mar 12 13:17:46 2009	(r189739)
+++ stable/7/UPDATING	Thu Mar 12 13:45:55 2009	(r189740)
@@ -9,6 +9,19 @@ Items affecting the ports and packages s
 portupgrade.
 
 20090312:
+	A workaround is committed to allow the creation of System V shared
+	memory segment of size > 2 GB on the 64-bit architectures.
+	Due to a 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 must be explicitely
+	raised to allow such segments to be created.
+
+	The management interface that is used by ipcs(1) has to be changed
+	in incompatible way. Rebuild the ipcs(1) utility with the new
+	headers after the update. Buildworld/installworld takes care
+	of this issue automatically.
+
+20090312:
 	The open-source Atheros HAL has been merged from HEAD
 	to STABLE.
 	The kernel compile-time option AH_SUPPORT_AR5416 has been

Modified: stable/7/lib/libc/sys/shmctl.2
==============================================================================
--- stable/7/lib/libc/sys/shmctl.2	Thu Mar 12 13:17:46 2009	(r189739)
+++ stable/7/lib/libc/sys/shmctl.2	Thu Mar 12 13:45:55 2009	(r189740)
@@ -133,6 +133,16 @@ the shared memory segment's owner or cre
 Permission denied due to mismatch between operation and mode of
 shared memory segment.
 .El
+.Sh "BUGS"
+The segment size has size_t type.
+The shm_segsz member of the
+.Vt shmid_ds
+structure has type int, which is too short to represent the full range
+of values for a segment size.
+If shared memory limits are raised to allow segments with size > 2 GB
+to be created, be aware that IPC_STAT call may return a truncated value
+for shm_segsz.
+.El
 .Sh "SEE ALSO"
 .Xr shmat 2 ,
 .Xr shmdt 2 ,

Modified: stable/7/sys/kern/sysv_shm.c
==============================================================================
--- stable/7/sys/kern/sysv_shm.c	Thu Mar 12 13:17:46 2009	(r189739)
+++ stable/7/sys/kern/sysv_shm.c	Thu Mar 12 13:45:55 2009	(r189740)
@@ -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;
+vm_size_t shm_committed;
 static struct shmid_kernel	*shmsegs;
 
 struct shmmap_state {
@@ -244,13 +245,13 @@ static void
 shm_deallocate_segment(shmseg)
 	struct shmid_kernel *shmseg;
 {
-	size_t size;
+	vm_size_t size;
 
 	GIANT_REQUIRED;
 
 	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;
@@ -264,13 +265,13 @@ shm_delete_mapping(struct vmspace *vm, s
 {
 	struct shmid_kernel *shmseg;
 	int segnum, result;
-	size_t size;
+	vm_size_t size;
 
 	GIANT_REQUIRED;
 
 	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);
@@ -361,8 +362,8 @@ kern_shmat(td, shmid, shmaddr, shmflg)
 	mtx_lock(&Giant);
 	shmmap_s = p->p_vmspace->vm_shm;
 	if (shmmap_s == NULL) {
-		size = shminfo.shmseg * sizeof(struct shmmap_state);
-		shmmap_s = malloc(size, M_SHM, M_WAITOK);
+		shmmap_s = malloc(shminfo.shmseg * sizeof(struct shmmap_state),
+		    M_SHM, M_WAITOK);
 		for (i = 0; i < shminfo.shmseg; i++)
 			shmmap_s[i].shmid = -1;
 		p->p_vmspace->vm_shm = shmmap_s;
@@ -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;
@@ -705,7 +707,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 != 0 && uap->size > shmseg->shm_bsegsz)
 		return (EINVAL);
 	td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm);
 	return (0);
@@ -717,7 +719,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;
@@ -775,6 +778,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;

Modified: stable/7/sys/sys/param.h
==============================================================================
--- stable/7/sys/sys/param.h	Thu Mar 12 13:17:46 2009	(r189739)
+++ stable/7/sys/sys/param.h	Thu Mar 12 13:45:55 2009	(r189740)
@@ -57,7 +57,7 @@
  *		is created, otherwise 1.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 701104	/* Master, propagated to newvers */
+#define __FreeBSD_version 701105	/* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include <sys/types.h>

Modified: stable/7/sys/sys/shm.h
==============================================================================
--- stable/7/sys/sys/shm.h	Thu Mar 12 13:17:46 2009	(r189739)
+++ stable/7/sys/sys/shm.h	Thu Mar 12 13:45:55 2009	(r189740)
@@ -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;


More information about the svn-src-stable mailing list