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);