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++) {
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to