Commit 960d4b34 authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds

[PATCH] shm_destroy lock hang

Martin Schwidefsky <schwidefsky@de.ibm.com> reported "Bug with shared
memory" to LKML 14 May: hang due to schedule in truncate_list_pages
called from .... shm_destroy holding shm_lock spinlock.  shm_destroy
needs that lock for shm_rmid, but it can be safely unlocked once link
from id to shp has been removed.
parent 7e9b34ab
......@@ -105,12 +105,14 @@ static void shm_open (struct vm_area_struct *shmd)
*
* @shp: struct to free
*
* It has to be called with shp and shm_ids.sem locked
* It has to be called with shp and shm_ids.sem locked,
* but returns with shp unlocked and freed.
*/
static void shm_destroy (struct shmid_kernel *shp)
{
shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
shm_rmid (shp->id);
shm_unlock(shp->id);
shmem_lock(shp->shm_file, 0);
fput (shp->shm_file);
kfree (shp);
......@@ -138,7 +140,7 @@ static void shm_close (struct vm_area_struct *shmd)
if(shp->shm_nattch == 0 &&
shp->shm_flags & SHM_DEST)
shm_destroy (shp);
else
shm_unlock(id);
up (&shm_ids.sem);
}
......@@ -502,11 +504,9 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf)
shp->shm_flags |= SHM_DEST;
/* Do not find it any more */
shp->shm_perm.key = IPC_PRIVATE;
shm_unlock(shmid);
} else
shm_destroy (shp);
/* Unlock */
shm_unlock(shmid);
up(&shm_ids.sem);
return err;
}
......@@ -644,6 +644,7 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
if(shp->shm_nattch == 0 &&
shp->shm_flags & SHM_DEST)
shm_destroy (shp);
else
shm_unlock(shmid);
up (&shm_ids.sem);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment