Hello list,
Another day another set of sizes for free(9). This time it's around the
hashinit function. I introduce a hashfree counterpart to hide the
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.
The patch touches many areas of the code, I pondered splitting it into
several diff (for each parts of the tree) but decided against it.. if
it's wanted I can redo it splitted.
Anyway here is the patch.
Index: isofs/udf/udf_vfsops.c
===================================================================
RCS file: /cvs/src/sys/isofs/udf/udf_vfsops.c,v
retrieving revision 1.46
diff -u -p -r1.46 udf_vfsops.c
--- isofs/udf/udf_vfsops.c 31 Aug 2015 06:56:25 -0000 1.46
+++ isofs/udf/udf_vfsops.c 21 Dec 2015 16:48:52 -0000
@@ -440,8 +440,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);
@@ -490,9 +489,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 = (qaddr_t)0;
Index: kern/kern_descrip.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_descrip.c,v
retrieving revision 1.127
diff -u -p -r1.127 kern_descrip.c
--- kern/kern_descrip.c 17 Dec 2015 16:59:26 -0000 1.127
+++ kern/kern_descrip.c 21 Dec 2015 16:48:52 -0000
@@ -1093,7 +1093,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: kern/kern_event.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_event.c,v
retrieving revision 1.70
diff -u -p -r1.70 kern_event.c
--- kern/kern_event.c 20 Dec 2015 17:56:18 -0000 1.70
+++ kern/kern_event.c 21 Dec 2015 16:48:52 -0000
@@ -118,7 +118,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: kern/kern_subr.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_subr.c,v
retrieving revision 1.45
diff -u -p -r1.45 kern_subr.c
--- kern/kern_subr.c 11 Dec 2015 16:07:02 -0000 1.45
+++ kern/kern_subr.c 21 Dec 2015 16:48:52 -0000
@@ -183,6 +183,18 @@ 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;
+
+ for (hashsize = 1; hashsize < elements; hashsize <<= 1)
+ continue;
+
+ free(hashtbl, type, sizeof(*hashtbl) * hashsize);
+}
+
/*
* "startup hook" types, functions, and variables.
*/
Index: netinet/ip_mroute.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_mroute.c,v
retrieving revision 1.89
diff -u -p -r1.89 ip_mroute.c
--- netinet/ip_mroute.c 14 Nov 2015 15:54:27 -0000 1.89
+++ netinet/ip_mroute.c 21 Dec 2015 16:48:53 -0000
@@ -611,7 +611,7 @@ ip_mrouter_done()
}
memset(nexpire, 0, sizeof(nexpire));
- free(mfchashtbl, M_MRTABLE, 0);
+ hashfree(mfchashtbl, MFCTBLSIZ, M_MRTABLE);
mfchashtbl = NULL;
ip_mrouter = NULL;
Index: 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
--- ntfs/ntfs_ihash.c 14 Mar 2015 03:38:52 -0000 1.19
+++ ntfs/ntfs_ihash.c 21 Dec 2015 16:48:53 -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/event.h
===================================================================
RCS file: /cvs/src/sys/sys/event.h,v
retrieving revision 1.21
diff -u -p -r1.21 event.h
--- sys/event.h 6 Oct 2015 03:29:35 -0000 1.21
+++ sys/event.h 21 Dec 2015 16:48:54 -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/systm.h
===================================================================
RCS file: /cvs/src/sys/sys/systm.h,v
retrieving revision 1.109
diff -u -p -r1.109 systm.h
--- sys/systm.h 11 Dec 2015 16:07:02 -0000 1.109
+++ sys/systm.h 21 Dec 2015 16:48:54 -0000
@@ -158,6 +158,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: uvm/uvm_aobj.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_aobj.c,v
retrieving revision 1.80
diff -u -p -r1.80 uvm_aobj.c
--- uvm/uvm_aobj.c 21 Aug 2015 16:04:35 -0000 1.80
+++ uvm/uvm_aobj.c 21 Dec 2015 16:48:54 -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;