Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Oct 1995 10:39:39 +0200
From:      Mark Murray <mark@grondar.za>
To:        Bruce Evans <bde@zeta.org.au>
Cc:        hackers@FreeBSD.org
Subject:   Re: Creating a /dev/random 
Message-ID:  <199510160839.KAA25610@grumble.grondar.za>

next in thread | raw e-mail | index | archive | help
> >I am building devices, /dev/random and /dev/urandom that when read give
> >random noise generated in and by the kernel. So far it is going pretty
> >well, but I have some unexplained hangs. I believe these are due to
> >my complete lack of knowledge of what the uiomove() function is supposed
> >to do.
> 
> rbuf doesn't seem to be freed anywhere, so the malloc()s will eventually
> consume all of kernel memory and then (at best) everything will hang in
> malloc().  (Use ps inside db to see where things are hanging.)

AHA! thanks for that!

> To avoid this, use the existing buffer `zbuf', which is freed correctly.
> There is no need for another variable - local variables are per process.
> Perhaps `zbuf' should be renamed `buf'.
> 
> Hmm, now I know why /dev/zero is so slow.  The buffer is bzeroed for
> every call.  The buffer size is 4K, so reads of about 4K are about
> twice as slow as they could by and reads of 1 byte are very slow
> because 4K is bzeroed for each byte read.  Reserving a page for the
> zero buffer would be a bit wasteful and the copyout to move the data
> is inelegant anyway.  Perhaps there should be a zeroout() function to
> optimize this important (;-) device.
> 
> >+			poolsize = read_random(rbuf, CLBYTES);
> >+			c = min(iov->iov_len, CLBYTES);
> >+			c = min(c, poolsize);
> >+			error = uiomove(rbuf, (int)c, uio);
> 
> `c' should be calculated before calling rad_random() to avoid wasting
> randomness.

Huh? How? :-) Are you suggesting that there should be another call to
return the number of bytes in the pool _before_ read_random is called?

> The (int) cast suggests that there may be some type bogusness.  Note that
> c has type u_int, iov_len has type size_t and min() is only appropriate for
> u_ints.  Things work right only if size_t is u_int or iov_len is small.
> poolsize and apparently read_random() have type int.  read_random() had
> better not return negative values for errors.

Yup - this stinks. I'll fix it.

M
--
Mark Murray
46 Harvey Rd, Claremont, Cape Town 7700, South Africa
+27 21 61-3768 GMT+0200
Finger mark@grumble.grondar.za for PGP key



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199510160839.KAA25610>