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