svn commit: r278963 - head/sys/kern

Konstantin Belousov kib at FreeBSD.org
Wed Feb 18 18:12:08 UTC 2015


Author: kib
Date: Wed Feb 18 18:12:06 2015
New Revision: 278963
URL: https://svnweb.freebsd.org/changeset/base/278963

Log:
  If malloc() sleeps, Giant is dropped.  Recheck for another thread
  doing our work.
  
  Remove unneeded check for failed M_WAITOK allocation.
  
  Reviewed by:	alc
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/kern/sysv_shm.c

Modified: head/sys/kern/sysv_shm.c
==============================================================================
--- head/sys/kern/sysv_shm.c	Wed Feb 18 17:28:55 2015	(r278962)
+++ head/sys/kern/sysv_shm.c	Wed Feb 18 18:12:06 2015	(r278963)
@@ -358,9 +358,22 @@ kern_shmat(td, shmid, shmaddr, shmflg)
 	if (shmmap_s == NULL) {
 		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;
+
+		/*
+		 * If malloc() above sleeps, the Giant lock is
+		 * temporarily dropped, which allows another thread to
+		 * allocate shmmap_state and set vm_shm.  Recheck
+		 * vm_shm and free the new shmmap_state if another one
+		 * is already allocated.
+		 */
+		if (p->p_vmspace->vm_shm != NULL) {
+			free(shmmap_s, M_SHM);
+			shmmap_s = p->p_vmspace->vm_shm;
+		} else {
+			for (i = 0; i < shminfo.shmseg; i++)
+				shmmap_s[i].shmid = -1;
+			p->p_vmspace->vm_shm = shmmap_s;
+		}
 	}
 	shmseg = shm_find_segment_by_shmid(shmid);
 	if (shmseg == NULL) {
@@ -826,8 +839,6 @@ shmrealloc(void)
 		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++) {


More information about the svn-src-head mailing list