Module Name:    src
Committed By:   pgoyette
Date:           Thu Nov  5 00:10:48 UTC 2015

Modified Files:
        src/sys/kern: sysv_shm.c
        src/sys/sys: shm.h
        src/sys/uvm: uvm_map.c

Log Message:
Now that SYSVSHM is modularized, reattach the linkages from uvm so that
we can correctly clean up on process exit or fork.

Without this, firefox attaches to a shared memory segment but doesn't
detach before exit.  Thus once firefox causes an autoload for sysv_ipc
it cannot be unloaded since the segment still retains references.


To generate a diff of this commit:
cvs rdiff -u -r1.128 -r1.129 src/sys/kern/sysv_shm.c
cvs rdiff -u -r1.49 -r1.50 src/sys/sys/shm.h
cvs rdiff -u -r1.335 -r1.336 src/sys/uvm/uvm_map.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/sysv_shm.c
diff -u src/sys/kern/sysv_shm.c:1.128 src/sys/kern/sysv_shm.c:1.129
--- src/sys/kern/sysv_shm.c:1.128	Wed May 13 01:16:15 2015
+++ src/sys/kern/sysv_shm.c	Thu Nov  5 00:10:47 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysv_shm.c,v 1.128 2015/05/13 01:16:15 pgoyette Exp $	*/
+/*	$NetBSD: sysv_shm.c,v 1.129 2015/11/05 00:10:47 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysv_shm.c,v 1.128 2015/05/13 01:16:15 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysv_shm.c,v 1.129 2015/11/05 00:10:47 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sysv.h"
@@ -990,6 +990,10 @@ shminit(void)
 
 	kern_has_sysvshm = 1;
 
+	/* Load the callback function pointers for the uvm subsystem */
+	uvm_shmexit = shmexit;
+	uvm_shmfork = shmfork;
+
 	sysvipcinit();
 }
 
@@ -1006,6 +1010,10 @@ shmfini(void)
 		return 1;
 	}
 
+	/* Clear the callback function pointers for the uvm subsystem */
+	uvm_shmexit = NULL;
+	uvm_shmfork = NULL;
+
 	/* Destroy all condvars */
 	for (i = 0; i < shminfo.shmmni; i++)
 		cv_destroy(&shm_cv[i]);

Index: src/sys/sys/shm.h
diff -u src/sys/sys/shm.h:1.49 src/sys/sys/shm.h:1.50
--- src/sys/sys/shm.h:1.49	Wed May 13 01:16:15 2015
+++ src/sys/sys/shm.h	Thu Nov  5 00:10:48 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: shm.h,v 1.49 2015/05/13 01:16:15 pgoyette Exp $	*/
+/*	$NetBSD: shm.h,v 1.50 2015/11/05 00:10:48 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -178,6 +178,9 @@ void	shmfork(struct vmspace *, struct vm
 void	shmexit(struct vmspace *);
 int	shmctl1(struct lwp *, int, int, struct shmid_ds *);
 
+extern void (*uvm_shmexit)(struct vmspace *);
+extern void (*uvm_shmfork)(struct vmspace *, struct vmspace *);
+
 #define SYSCTL_FILL_SHM(src, dst) do { \
 	SYSCTL_FILL_PERM((src).shm_perm, (dst).shm_perm); \
 	(dst).shm_segsz = (src).shm_segsz; \

Index: src/sys/uvm/uvm_map.c
diff -u src/sys/uvm/uvm_map.c:1.335 src/sys/uvm/uvm_map.c:1.336
--- src/sys/uvm/uvm_map.c:1.335	Thu Sep 24 14:35:15 2015
+++ src/sys/uvm/uvm_map.c	Thu Nov  5 00:10:48 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_map.c,v 1.335 2015/09/24 14:35:15 christos Exp $	*/
+/*	$NetBSD: uvm_map.c,v 1.336 2015/11/05 00:10:48 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.335 2015/09/24 14:35:15 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.336 2015/11/05 00:10:48 pgoyette Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvmhist.h"
@@ -90,9 +90,7 @@ __KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 
 #include "opt_user_va0_disable_default.h"
 #endif
 
-#ifdef SYSVSHM
 #include <sys/shm.h>
-#endif
 
 #include <uvm/uvm.h>
 #include <uvm/uvm_readahead.h>
@@ -299,6 +297,15 @@ static vsize_t uvm_rb_maxgap(const struc
 	(ROOT_ENTRY(map) == (entry) \
 	    ? NULL : (struct vm_map_entry *)RB_FATHER(&(entry)->rb_node))
 
+/*
+ * These get filled in if/when SYSVSHM shared memory code is loaded
+ *
+ * We do this with function pointers rather the #ifdef SYSVSHM so the
+ * SYSVSHM code can be loaded and unloaded
+ */
+void (*uvm_shmexit)(struct vmspace *) = NULL;
+void (*uvm_shmfork)(struct vmspace *, struct vmspace *) = NULL;
+
 static int
 uvm_map_compare_nodes(void *ctx, const void *nparent, const void *nkey)
 {
@@ -4071,14 +4078,11 @@ uvmspace_exec(struct lwp *l, vaddr_t sta
 		 * vm space!
 		 */
 
-#ifdef SYSVSHM
 		/*
 		 * SYSV SHM semantics require us to kill all segments on an exec
 		 */
-
-		if (ovm->vm_shm)
-			shmexit(ovm);
-#endif
+		if (uvm_shmexit && ovm->vm_shm)
+			(*uvm_shmexit)(ovm);
 
 		/*
 		 * POSIX 1003.1b -- "lock future mappings" is revoked
@@ -4170,11 +4174,10 @@ uvmspace_free(struct vmspace *vm)
 
 	map->flags |= VM_MAP_DYING;
 	pmap_remove_all(map->pmap);
-#ifdef SYSVSHM
+
 	/* Get rid of any SYSV shared memory segments. */
-	if (vm->vm_shm != NULL)
-		shmexit(vm);
-#endif
+	if (uvm_shmexit && vm->vm_shm != NULL)
+		(*uvm_shmexit)(vm);
 
 	if (map->nentries) {
 		uvm_unmap_remove(map, vm_map_min(map), vm_map_max(map),
@@ -4456,10 +4459,8 @@ uvmspace_fork(struct vmspace *vm1)
 	pmap_update(old_map->pmap);
 	vm_map_unlock(old_map);
 
-#ifdef SYSVSHM
-	if (vm1->vm_shm)
-		shmfork(vm1, vm2);
-#endif
+	if (uvm_shmfork && vm1->vm_shm)
+		(*uvm_shmfork)(vm1, vm2);
 
 #ifdef PMAP_FORK
 	pmap_fork(vm1->vm_map.pmap, vm2->vm_map.pmap);

Reply via email to