[PATCH] Support: Avoid buffered reads of /dev/urandom

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 10 11:57:31 PST 2015


LGTM.

Switching to getrandom might be possible, but can be done as a followup patch.

Do you have commit access?

Cheers,
Rafael


On 25 November 2015 at 21:15, Anton Blanchard <anton at samba.org> wrote:
> Hi,
>
>> Would it be best to just use open/read/close instead of
>> fopen/fread/fclose?
>
> I just realised I forgot to send a reworked version out. How does
> this look?
>
> Anton
> --
>
> I am seeing disappointing clang performance on a large PowerPC64
> Linux box. GetRandomNumberSeed() does a buffered read from
> /dev/urandom to seed its PRNG. As a result we read an entire page
> even though we only need 4 bytes.
>
> With every clang task reading a page worth of /dev/urandom we
> end up spending a large amount of time stuck on a kernel spinlock.
>
> diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc
> index df13bd2..27083ee 100644
> --- a/lib/Support/Unix/Process.inc
> +++ b/lib/Support/Unix/Process.inc
> @@ -430,13 +430,18 @@ const char *Process::ResetColor() {
>  #if !defined(HAVE_DECL_ARC4RANDOM) || !HAVE_DECL_ARC4RANDOM
>  static unsigned GetRandomNumberSeed() {
>    // Attempt to get the initial seed from /dev/urandom, if possible.
> -  if (FILE *RandomSource = ::fopen("/dev/urandom", "r")) {
> +  int urandomFD = open("/dev/urandom", O_RDONLY);
> +
> +  if (urandomFD != -1) {
>      unsigned seed;
> -    int count = ::fread((void *)&seed, sizeof(seed), 1, RandomSource);
> -    ::fclose(RandomSource);
> +    // Don't use a buffered read to avoid reading more data
> +    // from /dev/urandom than we need.
> +    int count = read(urandomFD, (void *)&seed, sizeof(seed));
> +
> +    close(urandomFD);
>
>      // Return the seed if the read was successful.
> -    if (count == 1)
> +    if (count == sizeof(seed))
>        return seed;
>    }
>


More information about the llvm-commits mailing list