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

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 11 15:02:31 PST 2015


r255386.

Thanks,
Rafael


On 11 December 2015 at 17:34, Anton Blanchard <anton at samba.org> wrote:
>
>> LGTM.
>>
>> Switching to getrandom might be possible, but can be done as a
>> followup patch.
>
> Thanks Rafael!
>
>> Do you have commit access?
>
> No, I don't have access.
>
> Anton
>
>> 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