Module Name:    src
Committed By:   pgoyette
Date:           Wed May 13 01:16:15 UTC 2015

Modified Files:
        src/sys/kern: sysv_msg.c sysv_sem.c sysv_shm.c
        src/sys/sys: msg.h sem.h shm.h

Log Message:
More prep:  add a xxxfini() routine to each subcomponent so we can
clean up after ourselves.  Mostly, this checks to make sure that
there are no active itmes, and then deallocates wired kernel virtual
memory.  For SYSVSEM, we also disestablish the exithook() so we
won't try to call it after destroying its memory pool!


To generate a diff of this commit:
cvs rdiff -u -r1.68 -r1.69 src/sys/kern/sysv_msg.c
cvs rdiff -u -r1.93 -r1.94 src/sys/kern/sysv_sem.c
cvs rdiff -u -r1.127 -r1.128 src/sys/kern/sysv_shm.c
cvs rdiff -u -r1.24 -r1.25 src/sys/sys/msg.h
cvs rdiff -u -r1.30 -r1.31 src/sys/sys/sem.h
cvs rdiff -u -r1.48 -r1.49 src/sys/sys/shm.h

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_msg.c
diff -u src/sys/kern/sysv_msg.c:1.68 src/sys/kern/sysv_msg.c:1.69
--- src/sys/kern/sysv_msg.c:1.68	Wed May 13 01:00:16 2015
+++ src/sys/kern/sysv_msg.c	Wed May 13 01:16:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysv_msg.c,v 1.68 2015/05/13 01:00:16 pgoyette Exp $	*/
+/*	$NetBSD: sysv_msg.c,v 1.69 2015/05/13 01:16:15 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2006, 2007 The NetBSD Foundation, Inc.
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysv_msg.c,v 1.68 2015/05/13 01:00:16 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysv_msg.c,v 1.69 2015/05/13 01:16:15 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sysv.h"
@@ -164,6 +164,40 @@ msginit(void)
 	sysvipcinit();
 }
 
+int
+msgfini(void)
+{
+	int i, sz;
+	vaddr_t v = (vaddr_t)msgpool;
+
+	mutex_enter(&msgmutex);
+	for (i = 0; i < msginfo.msgmni; i++) {
+		if (msqs[i].msq_u.msg_qbytes != 0) {
+			mutex_exit(&msgmutex);
+			return 1; /* queue not available, prevent unload! */
+		}
+	}
+/*
+ * Destroy all condvars and free the memory we're using
+ */
+	for (i = 0; i < msginfo.msgmni; i++) {
+		cv_destroy(&msqs[i].msq_cv);
+	}
+	sz = ALIGN(msginfo.msgmax) +
+	    ALIGN(msginfo.msgseg * sizeof(struct msgmap)) +
+	    ALIGN(msginfo.msgtql * sizeof(struct __msg)) +
+	    ALIGN(msginfo.msgmni * sizeof(kmsq_t));
+	sz = round_page(sz);
+	uvm_km_free(kernel_map, v, sz, UVM_KMF_WIRED);
+
+	mutex_exit(&msgmutex);
+	mutex_destroy(&msgmutex);
+
+	kern_has_sysvmsg = 0;
+
+	return 0;
+}
+
 static int
 msgrealloc(int newmsgmni, int newmsgseg)
 {

Index: src/sys/kern/sysv_sem.c
diff -u src/sys/kern/sysv_sem.c:1.93 src/sys/kern/sysv_sem.c:1.94
--- src/sys/kern/sysv_sem.c:1.93	Wed May 13 01:00:16 2015
+++ src/sys/kern/sysv_sem.c	Wed May 13 01:16:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysv_sem.c,v 1.93 2015/05/13 01:00:16 pgoyette Exp $	*/
+/*	$NetBSD: sysv_sem.c,v 1.94 2015/05/13 01:16:15 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc.
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sysv_sem.c,v 1.93 2015/05/13 01:00:16 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysv_sem.c,v 1.94 2015/05/13 01:16:15 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sysv.h"
@@ -134,13 +134,54 @@ seminit(void)
 		suptr->un_proc = NULL;
 	}
 	semu_list = NULL;
-	exithook_establish(semexit, NULL);
+	hook = exithook_establish(semexit, NULL);
+
+	kern_has_sysvsem = 1;
 
 	kern_has_sysvsem = 1;
 
 	sysvipcinit();
 }
 
+int
+semfini(void)
+{
+	int i, sz;
+	vaddr_t v = (vaddr_t)sema;
+
+	/* Don't allow module unload if we're busy */
+	mutex_enter(&semlock);
+	if (semtot) {
+		mutex_exit(&semlock);
+		return 1;
+	}
+
+	/* Remove the exit hook */
+	exithook_disestablish(hook);
+
+	/* Destroy all our condvars */
+	for (i = 0; i < seminfo.semmni; i++) {
+		cv_destroy(&semcv[i]);
+	}
+
+	/* Free the wired memory that we allocated */
+	sz = ALIGN(seminfo.semmni * sizeof(struct semid_ds)) +
+	    ALIGN(seminfo.semmns * sizeof(struct __sem)) +
+	    ALIGN(seminfo.semmni * sizeof(kcondvar_t)) +
+	    ALIGN(seminfo.semmnu * seminfo.semusz);
+	sz = round_page(sz);
+	uvm_km_free(kernel_map, v, sz, UVM_KMF_WIRED);
+
+	/* Destroy the last cv and mutex */
+	cv_destroy(&sem_realloc_cv);
+	mutex_exit(&semlock);
+	mutex_destroy(&semlock);
+
+	kern_has_sysvsem = 0;
+
+	return 0;
+}
+
 static int
 semrealloc(int newsemmni, int newsemmns, int newsemmnu)
 {

Index: src/sys/kern/sysv_shm.c
diff -u src/sys/kern/sysv_shm.c:1.127 src/sys/kern/sysv_shm.c:1.128
--- src/sys/kern/sysv_shm.c:1.127	Wed May 13 01:00:16 2015
+++ src/sys/kern/sysv_shm.c	Wed May 13 01:16:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysv_shm.c,v 1.127 2015/05/13 01:00:16 pgoyette Exp $	*/
+/*	$NetBSD: sysv_shm.c,v 1.128 2015/05/13 01:16:15 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.127 2015/05/13 01:00:16 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sysv_shm.c,v 1.128 2015/05/13 01:16:15 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sysv.h"
@@ -993,6 +993,39 @@ shminit(void)
 	sysvipcinit();
 }
 
+int
+shmfini(void)
+{
+	size_t sz;
+	int i;
+	vaddr_t v = (vaddr_t)shmsegs;
+
+	mutex_enter(&shm_lock);
+	if (shm_nused) {
+		mutex_exit(&shm_lock);
+		return 1;
+	}
+
+	/* Destroy all condvars */
+	for (i = 0; i < shminfo.shmmni; i++)
+		cv_destroy(&shm_cv[i]);
+	cv_destroy(&shm_realloc_cv);
+
+	/* Free the allocated/wired memory */
+	sz = ALIGN(shminfo.shmmni * sizeof(struct shmid_ds)) +
+	    ALIGN(shminfo.shmmni * sizeof(kcondvar_t));
+	sz = round_page(sz);
+	uvm_km_free(kernel_map, v, sz, UVM_KMF_WIRED);
+
+	/* Release and destroy our mutex */
+	mutex_exit(&shm_lock);
+	mutex_destroy(&shm_lock);
+
+	kern_has_sysvshm = 0;
+
+	return 0;
+}
+
 static int
 sysctl_ipc_shmmni(SYSCTLFN_ARGS)
 {

Index: src/sys/sys/msg.h
diff -u src/sys/sys/msg.h:1.24 src/sys/sys/msg.h:1.25
--- src/sys/sys/msg.h:1.24	Mon Jan 19 19:39:41 2009
+++ src/sys/sys/msg.h	Wed May 13 01:16:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.h,v 1.24 2009/01/19 19:39:41 christos Exp $	*/
+/*	$NetBSD: msg.h,v 1.25 2015/05/13 01:16:15 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc.
@@ -210,6 +210,7 @@ __END_DECLS
 struct proc;
 
 void	msginit(void);
+int	msgfini(void);
 int	msgctl1(struct lwp *, int, int, struct msqid_ds *);
 int	msgsnd1(struct lwp *, int, const char *, size_t, int, size_t,
     copyin_t);

Index: src/sys/sys/sem.h
diff -u src/sys/sys/sem.h:1.30 src/sys/sys/sem.h:1.31
--- src/sys/sys/sem.h:1.30	Fri Sep  5 05:54:48 2014
+++ src/sys/sys/sem.h	Wed May 13 01:16:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: sem.h,v 1.30 2014/09/05 05:54:48 matt Exp $	*/
+/*	$NetBSD: sem.h,v 1.31 2015/05/13 01:16:15 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -223,6 +223,7 @@ int	semconfig(int);
 __END_DECLS
 #else
 void	seminit(void);
+int	semfini(void);
 void	semexit(struct proc *, void *);
 
 int	semctl1(struct lwp *, int, int, int, void *, register_t *);

Index: src/sys/sys/shm.h
diff -u src/sys/sys/shm.h:1.48 src/sys/sys/shm.h:1.49
--- src/sys/sys/shm.h:1.48	Mon Jan 19 19:39:41 2009
+++ src/sys/sys/shm.h	Wed May 13 01:16:15 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: shm.h,v 1.48 2009/01/19 19:39:41 christos Exp $	*/
+/*	$NetBSD: shm.h,v 1.49 2015/05/13 01:16:15 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -173,6 +173,7 @@ extern int shm_nused;
 struct vmspace;
 
 void	shminit(void);
+int	shmfini(void);
 void	shmfork(struct vmspace *, struct vmspace *);
 void	shmexit(struct vmspace *);
 int	shmctl1(struct lwp *, int, int, struct shmid_ds *);

Reply via email to