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;

Reply via email to