svn commit: r279274 - stable/9/sys/kern

Konstantin Belousov kib at FreeBSD.org
Wed Feb 25 09:22:00 UTC 2015


Author: kib
Date: Wed Feb 25 09:21:59 2015
New Revision: 279274
URL: https://svnweb.freebsd.org/changeset/base/279274

Log:
  MFC r278963:
  If malloc() sleeps, Giant is dropped.  Recheck for another thread
  doing our work.
  
  Remove unneeded check for failed M_WAITOK allocation.

Modified:
  stable/9/sys/kern/sysv_shm.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/sysv_shm.c
==============================================================================
--- stable/9/sys/kern/sysv_shm.c	Wed Feb 25 09:21:04 2015	(r279273)
+++ stable/9/sys/kern/sysv_shm.c	Wed Feb 25 09:21:59 2015	(r279274)
@@ -357,9 +357,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-stable-9 mailing list