Hi all, please review the attached patch to remove the two remaining MI uses of random(9). Neither should be in a performance critical code path and both may actually benefit from the better distribution. The vfs_bio.c change is a bit more involved as I am trying to replace a 32bit division with a long multiplication, which should be cheaper pretty much anywhere.
Joerg
Index: ufs/ffs/ffs_alloc.c =================================================================== RCS file: /home/joerg/repo/netbsd/src/sys/ufs/ffs/ffs_alloc.c,v retrieving revision 1.146 diff -u -p -r1.146 ffs_alloc.c --- ufs/ffs/ffs_alloc.c 25 Jul 2014 08:24:31 -0000 1.146 +++ ufs/ffs/ffs_alloc.c 8 Sep 2014 13:03:50 -0000 @@ -90,6 +90,7 @@ __KERNEL_RCSID(0, "$NetBSD: ffs_alloc.c, #include <sys/syslog.h> #include <sys/vnode.h> #include <sys/wapbl.h> +#include <sys/cprng.h> #include <miscfs/specfs/specdev.h> #include <ufs/ufs/quota.h> @@ -697,7 +698,7 @@ ffs_dirpref(struct inode *pip) * Force allocation in another cg if creating a first level dir. */ if (ITOV(pip)->v_vflag & VV_ROOT) { - prefcg = random() % fs->fs_ncg; + prefcg = cprng_fast32() % fs->fs_ncg; mincg = prefcg; minndir = fs->fs_ipg; for (cg = prefcg; cg < fs->fs_ncg; cg++) Index: kern/vfs_bio.c =================================================================== RCS file: /home/joerg/repo/netbsd/src/sys/kern/vfs_bio.c,v retrieving revision 1.251 diff -u -p -r1.251 vfs_bio.c --- kern/vfs_bio.c 5 Sep 2014 05:57:21 -0000 1.251 +++ kern/vfs_bio.c 8 Sep 2014 18:00:47 -0000 @@ -143,6 +143,7 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_bio.c,v #include <sys/cpu.h> #include <sys/wapbl.h> #include <sys/bitops.h> +#include <sys/cprng.h> #include <uvm/uvm.h> /* extern struct uvm uvm */ @@ -532,7 +533,7 @@ bufinit2(void) static int buf_lotsfree(void) { - int guess, thresh; + u_long guess; /* Always allocate if less than the low water mark. */ if (bufmem < bufmem_lowater) @@ -548,16 +549,13 @@ buf_lotsfree(void) /* * The probabily of getting a new allocation is inversely - * proportional to the current size of the cache, using - * a granularity of 16 steps. + * proportional to the current size of the cache above the low + * water mark. Divide into 16 steps to avoid overflows. */ - guess = random() & 0x0000000fL; + guess = cprng_fast32() % 16; - /* Don't use "16 * bufmem" here to avoid a 32-bit overflow. */ - thresh = (bufmem - bufmem_lowater) / - ((bufmem_hiwater - bufmem_lowater) / 16); - - if (guess >= thresh) + if ((bufmem_hiwater - bufmem_lowater) / 16 * guess >= + (bufmem - bufmem_lowater)) return 1; /* Otherwise don't allocate. */