Date: Sat, 20 Feb 1999 12:17:40 -0500 (EST) From: Brian Feldman <green@unixhelp.org> To: current@freebsd.org Subject: More kernel threading ;) Message-ID: <Pine.BSF.4.05.9902201202140.23323-100000@janus.syracuse.net>
next in thread | raw e-mail | index | archive | help
This time I've got a problem with LinuxThreads (again), but really any kernel threads. Anyway, for those who say to put your patches where your mouth is, this is a pretty annoying problem which I have solved, and I've provided a fix. So here goes: With RFMEM, a shared address space is created and p->p_vmspace->vm_refcnt is incremented. With shared memory, p->p_vmspace->vm_shm is allocated and used. Now when processes exit (in the code before this patch), if vm_refcnt is not 1, shared memory is not taken care of at all. Instead, I changed it so that shared memory's shm_nattch is decreased, and if < 1, freed. This solves the problem of: p1: fork1(RFMEM) p[12]: shm create/attach kill -9 p2 (no chance for the process to catch the signal and delete the shared memory correctly) exit1(p2)-> vm_refcnt--, shm not deleted/unreferenced p1: no child! *SPLAT* exit1(p1)-> vm_refcnt-- == 1, vm deleted and shm tried to be deleted: shmexit-> shm all tried to be freed, but refcnt > 0, so it's not really deleted and refcnt is dec'd once You end up with (ipcs -a) a shared memory segment with a refcnt of 1, being SET deleted but still there, and undeleteable because its' refcnt is 1 (refcnt being shm_nattch...). And the patch follows :) --- src/sys/kern/sysv_shm.c.old Sat Feb 20 11:36:15 1999 +++ src/sys/kern/sysv_shm.c Sat Feb 20 11:46:19 1999 @@ -596,10 +596,13 @@ shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm; for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) - if (shmmap_s->shmid != -1) + if (shmmap_s->shmid != -1 && + --shmsegs[IPCID_TO_IX(shmmap_s->shmid)].shm_nattch < 1) shm_delete_mapping(p, shmmap_s); - free((caddr_t)p->p_vmspace->vm_shm, M_SHM); - p->p_vmspace->vm_shm = NULL; + if (p->p_vmspace->vm_refcnt == 1) { + free((caddr_t)p->p_vmspace->vm_shm, M_SHM); + p->p_vmspace->vm_shm = NULL; + } } void --- src/sys/kern/kern_exit.c.old Sat Feb 20 11:36:02 1999 +++ src/sys/kern/kern_exit.c Sat Feb 20 11:46:22 1999 @@ -206,6 +206,10 @@ /* The next two chunks should probably be moved to vmspace_exit. */ vm = p->p_vmspace; + + if (vm->vm_shm) + shmexit(p); + /* * Release user portion of address space. * This releases references to vnodes, @@ -215,8 +219,6 @@ * may be mapped within that space also. */ if (vm->vm_refcnt == 1) { - if (vm->vm_shm) - shmexit(p); pmap_remove_pages(vmspace_pmap(vm), VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS); (void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS, Brian Feldman _ __ ___ ___ ___ green@unixhelp.org _ __ ___ | _ ) __| \ http://www.freebsd.org/ _ __ ___ ____ | _ \__ \ |) | FreeBSD: The Power to Serve! _ __ ___ ____ _____ |___/___/___/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.05.9902201202140.23323-100000>