Hello list, I'm introducing hashfree, a counterpart to hashinit in order to pass the size to free(9) while hiding the implementation details. Most of the api users are converted in the patch below, those not included just simply do not free the memory (pid hash table etc). All, except for one case, the input hashtbl in in_pcb, because at free time the size is really not known, so it needs more moving of things around and is out the scope of this patch.
Manpage diff courtesy of natano@ on an old version of the diff! Anyway here is the patch. Index: share/man/man9/hashinit.9 =================================================================== RCS file: /cvs/src/share/man/man9/hashinit.9,v retrieving revision 1.5 diff -u -p -r1.5 hashinit.9 --- share/man/man9/hashinit.9 4 Jun 2013 19:27:07 -0000 1.5 +++ share/man/man9/hashinit.9 31 Aug 2016 10:30:13 -0000 @@ -29,14 +29,15 @@ .Dt HASHINIT 9 .Os .Sh NAME -.Nm hashinit -.\" This should be ported from netbsd as well... -.\" .Nm hashdone +.Nm hashinit , +.Nm hashfree .Nd kernel hashtable functions .Sh SYNOPSIS .In sys/systm.h .Ft void * .Fn hashinit "int num" "int type" "int flags" "u_long *mask" +.Ft void +.Fn hashfree "void *hash" "int num" "int type" .Sh DESCRIPTION The .Fn hashinit @@ -60,6 +61,17 @@ argument is used to pass back the mask f hashing table. For an example of its use, see .Xr hash 9 . +.Pp +The +.Fn hashfree +function causes memory allocated by the +.Fn hashinit +function to be released. +The +.Fa num +and +.Fa type +arguments of related calls must match. .Sh RETURN VALUES The .Fn hashinit Index: sys/isofs/udf/udf_vfsops.c =================================================================== RCS file: /cvs/src/sys/isofs/udf/udf_vfsops.c,v retrieving revision 1.54 diff -u -p -r1.54 udf_vfsops.c --- sys/isofs/udf/udf_vfsops.c 25 Aug 2016 00:06:44 -0000 1.54 +++ sys/isofs/udf/udf_vfsops.c 31 Aug 2016 10:30:22 -0000 @@ -444,8 +444,7 @@ udf_mountfs(struct vnode *devvp, struct return (0); bail: - if (ump->um_hashtbl != NULL) - free(ump->um_hashtbl, M_UDFMOUNT, 0); + hashfree(ump->um_hashtbl, UDF_HASHTBLSIZE, M_UDFMOUNT); if (ump != NULL) { free(ump, M_UDFMOUNT, 0); @@ -494,9 +493,7 @@ udf_unmount(struct mount *mp, int mntfla if (ump->um_stbl != NULL) free(ump->um_stbl, M_UDFMOUNT, 0); - if (ump->um_hashtbl != NULL) - free(ump->um_hashtbl, M_UDFMOUNT, 0); - + hashfree(ump->um_hashtbl, UDF_HASHTBLSIZE, M_UDFMOUNT); free(ump, M_UDFMOUNT, 0); mp->mnt_data = NULL; Index: sys/kern/kern_descrip.c =================================================================== RCS file: /cvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.134 diff -u -p -r1.134 kern_descrip.c --- sys/kern/kern_descrip.c 25 Aug 2016 00:00:02 -0000 1.134 +++ sys/kern/kern_descrip.c 31 Aug 2016 10:30:22 -0000 @@ -1098,7 +1098,7 @@ fdfree(struct proc *p) if (fdp->fd_rdir) vrele(fdp->fd_rdir); free(fdp->fd_knlist, M_TEMP, fdp->fd_knlistsize * sizeof(struct klist)); - free(fdp->fd_knhash, M_TEMP, 0); + hashfree(fdp->fd_knhash, KN_HASHSIZE, M_TEMP); pool_put(&fdesc_pool, fdp); } Index: sys/kern/kern_event.c =================================================================== RCS file: /cvs/src/sys/kern/kern_event.c,v retrieving revision 1.75 diff -u -p -r1.75 kern_event.c --- sys/kern/kern_event.c 25 Aug 2016 00:00:02 -0000 1.75 +++ sys/kern/kern_event.c 31 Aug 2016 10:30:23 -0000 @@ -119,7 +119,6 @@ int kq_timeoutmax = (4 * 1024); knote_enqueue(kn); \ } while(0) -#define KN_HASHSIZE 64 /* XXX should be tunable */ #define KN_HASH(val, mask) (((val) ^ (val >> 8)) & (mask)) extern struct filterops sig_filtops; Index: sys/kern/kern_subr.c =================================================================== RCS file: /cvs/src/sys/kern/kern_subr.c,v retrieving revision 1.47 diff -u -p -r1.47 kern_subr.c --- sys/kern/kern_subr.c 15 Mar 2016 04:19:26 -0000 1.47 +++ sys/kern/kern_subr.c 31 Aug 2016 10:30:23 -0000 @@ -176,6 +176,20 @@ hashinit(int elements, int type, int fla return (hashtbl); } +void +hashfree(void *hash, int elements, int type) +{ + u_long hashsize; + LIST_HEAD(generic, generic) *hashtbl = hash; + + if (elements <= 0) + panic("hashfree: bad cnt"); + for (hashsize = 1; hashsize < elements; hashsize <<= 1) + continue; + + free(hashtbl, type, sizeof(*hashtbl) * hashsize); +} + /* * "startup hook" types, functions, and variables. */ Index: sys/netinet/ip_mroute.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_mroute.c,v retrieving revision 1.90 diff -u -p -r1.90 ip_mroute.c --- sys/netinet/ip_mroute.c 7 Mar 2016 18:44:00 -0000 1.90 +++ sys/netinet/ip_mroute.c 31 Aug 2016 10:30:25 -0000 @@ -611,7 +611,7 @@ ip_mrouter_done(void) } memset(nexpire, 0, sizeof(nexpire)); - free(mfchashtbl, M_MRTABLE, 0); + hashfree(mfchashtbl, MFCTBLSIZ, M_MRTABLE); mfchashtbl = NULL; ip_mrouter = NULL; Index: sys/ntfs/ntfs_ihash.c =================================================================== RCS file: /cvs/src/sys/ntfs/ntfs_ihash.c,v retrieving revision 1.19 diff -u -p -r1.19 ntfs_ihash.c --- sys/ntfs/ntfs_ihash.c 14 Mar 2015 03:38:52 -0000 1.19 +++ sys/ntfs/ntfs_ihash.c 31 Aug 2016 10:30:25 -0000 @@ -70,7 +70,7 @@ ntfs_nthashinit(void) nthashtbl = hashinit(initialvnodes, M_NTFSNTHASH, M_WAITOK, &nthash); if (ntfs_nthashtbl) { - free(nthashtbl, M_NTFSNTHASH, 0); + hashfree(nthashtbl, initialvnodes, M_NTFSNTHASH); return; } ntfs_nthashtbl = nthashtbl; Index: sys/sys/event.h =================================================================== RCS file: /cvs/src/sys/sys/event.h,v retrieving revision 1.22 diff -u -p -r1.22 event.h --- sys/sys/event.h 13 Aug 2016 17:05:02 -0000 1.22 +++ sys/sys/event.h 31 Aug 2016 10:30:25 -0000 @@ -123,6 +123,8 @@ SLIST_HEAD(klist, knote); knote((list), (hint)); \ } while (0) +#define KN_HASHSIZE 64 /* XXX should be tunable */ + /* * Flag indicating hint is a signal. Used by EVFILT_SIGNAL, and also * shared by EVFILT_PROC (all knotes attached to p->p_klist) Index: sys/sys/systm.h =================================================================== RCS file: /cvs/src/sys/sys/systm.h,v retrieving revision 1.113 diff -u -p -r1.113 systm.h --- sys/sys/systm.h 17 May 2016 23:28:03 -0000 1.113 +++ sys/sys/systm.h 31 Aug 2016 10:30:26 -0000 @@ -151,6 +151,7 @@ void vfs_op_init(void); int seltrue(dev_t dev, int which, struct proc *); int selfalse(dev_t dev, int which, struct proc *); void *hashinit(int, int, int, u_long *); +void hashfree(void *, int, int); int sys_nosys(struct proc *, void *, register_t *); void panic(const char *, ...) Index: sys/uvm/uvm_aobj.c =================================================================== RCS file: /cvs/src/sys/uvm/uvm_aobj.c,v retrieving revision 1.81 diff -u -p -r1.81 uvm_aobj.c --- sys/uvm/uvm_aobj.c 17 Jun 2016 10:48:25 -0000 1.81 +++ sys/uvm/uvm_aobj.c 31 Aug 2016 10:30:27 -0000 @@ -388,7 +388,8 @@ uao_free(struct uvm_aobj *aobj) pool_put(&uao_swhash_elt_pool, elt); } } - free(aobj->u_swhash, M_UVMAOBJ, 0); + + hashfree(aobj->u_swhash, UAO_SWHASH_BUCKETS(aobj->u_pages), M_UVMAOBJ); } else { int i; @@ -470,7 +471,7 @@ uao_shrink_hash(struct uvm_object *uobj, } } - free(aobj->u_swhash, M_UVMAOBJ, 0); + hashfree(aobj->u_swhash, UAO_SWHASH_BUCKETS(aobj->u_pages), M_UVMAOBJ); aobj->u_swhash = new_swhash; aobj->u_pages = pages; @@ -507,7 +508,7 @@ uao_shrink_convert(struct uvm_object *uo } } - free(aobj->u_swhash, M_UVMAOBJ, 0); + hashfree(aobj->u_swhash, UAO_SWHASH_BUCKETS(aobj->u_pages), M_UVMAOBJ); aobj->u_swslots = new_swslots; aobj->u_pages = pages; @@ -627,7 +628,7 @@ uao_grow_hash(struct uvm_object *uobj, i } } - free(aobj->u_swhash, M_UVMAOBJ, 0); + hashfree(aobj->u_swhash, UAO_SWHASH_BUCKETS(aobj->u_pages), M_UVMAOBJ); aobj->u_swhash = new_swhash; aobj->u_pages = pages;