
Entropy generator to provide significant lag reduction in Android - moeffju
http://forum.xda-developers.com/showthread.php?t=1987032&nocache=0
======
thefreeman
> This is all fascinating, and I'm not totally dismissing that something is
> happening here.

Qualcomm devices have a hardware random device, which when coupled with the
qrngd daemon feeds the kernel entropy pool. In normal operation of Android, I
_never_ see this pool actually get low unless running the qrngtest tool, in
which case qrngd just fills it right back up.

Looking in drivers/char/random.c though, the functions which are called in the
interrupt, input, and block device paths have an inner function
add_timer_randomness which calls preempt_disable().

As a totally non scientific test, I turned all of these functions into no-ops
and recompiled. This way, we're ONLY relying on the hardware RNG.

There's no change in entropy available because random numbers really just
aren't being used all that often.

But now, I'm seeing a modest increase in interactivity on the device. Certain
things feel smoother, and there is less UI jank. There's no change in
frequency scaling or power usage as proposed earlier. qrngtest passes just
fine as well.

What's going on here? I'm not entirely sure. We're either all crazy, or this
is tickling a subtle scheduling bug in the kernel. More investigation is
needed. [1]

[1] Steve Kondik (CyanogenMod maintainer)
[https://code.google.com/p/android/issues/detail?id=42265#c11...](https://code.google.com/p/android/issues/detail?id=42265#c114)

~~~
judofyr
Nice to see somewhat knowledgable commenting on this issue and _actually test
things out_. It's very easy to say "meh, you haven't done a scientific test so
it's probably placebo", but remember that you're being _equally_ un-scientific
in such an analyse.

When so many users are reporting improvements you (aka. Google) owe them to
get to the bottom of it.

I also find it surprisingly that nearly no-one posts information about what
phone they tested it on. Android ships in so many variants that it wouldn't
surprise me if it only works in some of them.

~~~
mistercow
>It's very easy to say "meh, you haven't done a scientific test so it's
probably placebo", but remember that you're being equally un-scientific in
such an analyse.

No, dismissing unblinded observations of phenomena the perceptions of which
are notoriously suggestible (like UI responsiveness) is _not_ "equally un-
scientific" as making unblinded observations of phenomena the perceptions of
which are notoriously suggestible.

Pointing out that such observations is unreliable is, in fact, a simple
application of science. Grandstanding tu quoque arguments are not.

------
mmastrac
The Android bug seems to explain that this was a bug in Android <=
Gingerbread:

<https://code.google.com/p/android/issues/detail?id=42265>

A comment by Elliott Hughes on the bug:

"i don't know why you think this is anything to do with dalvik (or libcore).
neither touches /dev/random. java.util.Random is just a PRNG seeded from the
clock. java.util.SecureRandom uses /dev/urandom.

"what version of Android are you reporting this against? i think there was a
bug once upon a time. <checks> oh, yeah, <= gingerbread was broken. >
gingerbread should be fine."

~~~
ajross
I hate to say it, but this kind of bad analysis is just endemic in the Android
modding world. There's no technical leadership at the top (the AOSP people
are, for the most part, silent except occasionally in bug reports like this),
so people just throw whatever hack they want onto forums filled with even-
less-clueful folks and things go viral.

If you tried this on a "real" Linux project you'd be laughed at. Where's the
test showing latency improvement? Hell, there isn't even any identifaction of
_any code at all_ that reads from /dev/random (and of course it appears there
is none).

It seems a little unfair, but frankly I blame Google for this mess. They
refuse to run AOSP as a "project", which leaves the AOSP-derived projects a
big soup of developers with no clear meritocracy. Some bits (Cyanogenmod) are
really quite good. But the stuff on XDA is probably 60% useless junk.

~~~
nailer
Android master HEAD is always proprietary and always has been. Android master
HEAD also fails Andy Rubin's own definition of open:
<https://twitter.com/Arubin/status/27808662429>, since that website is out of
date.

Only a few people inside Google are allowed to see it. Their colleagues aren't
allowed to sit in the same cafeteria as the Android developers, much less see
the source code, until it's already done.

If it was actually Open Source, XDA developers would actually have real,
original development, and features like lock screen widgets, officially added
in JB 4.2 in 2012, would have been completed by the community in 2009.

Only old, already released versions of Android are Open Source. This makes it
useless for real developers - who would want to fix something that might
already be a non-issue as of six months ago?

As a result, the only 'community development' in Android is people who know
how to tweak settings files and make ROMs with particular apps and settings
built in.

~~~
VikingCoder
Android is open soure - it's just not developed in an open, community manner.

The existence of Cyanogenmod and Amazon Kindle Fire prove that you are over-
stating the case.

~~~
nailer
Cyanogenmod doesn't have access to the current android source. The current
test release, 10.1 is based on Android 4.2, there is no version based on the
actual current android source code as that is not available to anyone who
isn't a Google employee on the Android team.

The kindle fire is a fork of Android 2.x.

~~~
gbog
And? I mean, ok, we get it, the most recently committed code is not open yet,
probably because Google would prefer its flagship phones not be spoiled. So
what? My phone runs an OS whose code is on github, and I install new versions
when I choose to do so, from nightly builds.

~~~
nailer
And all the drawbacks I cited in the original post, ie, nobody outside the
Android team bothers contributing anything, and the project has less
developers and less features than it would if it were truly open.

Why would new phones be 'spoiled' if their source code was released?

~~~
gbog
> nobody outside the Android team bothers contributing anything

Do you have any figures to back this claim? Somewhere above or below a guy
said he did send a patch.

> less developers and less features than it would if it were truly open

Very unlikely. Were it fully open (say, the Linux-way), it would not be pushed
forward so steadily by Google, it would not have so many high-end apps (many
written by Google), it would not have such a big piece of the market, it would
not be the solution of choice for manufacturers, etc.

I also wish Android to be more open, and I hope we will see soon emerge a
"Landroid" that will be to Android what Linux is to Unix, and probably
Cyanogenmod is paving its path, but this is no reason to spit in the soup:
Android is a giant step forward and without it we would be all sandwiched in a
MS-Apple cross-fight.

> Why would new phones be 'spoiled' if their source code was released?

Suppose the most recent feature developed by Google on Android reveals that
their next phone will have two-faced screens, wouldn't you think Google might
prefer to decide when and how this new phone will be announced? As a result,
we have a slightly lagging opening of the source code. It is sad, but better
than nothing.

~~~
saurik
It is definitely incorrect to say "nobody outside the Android team bothers
contributing anything": you can check the Android AOSP patch review website to
see otherwise. However, I think it is a fair assessment to say that doing so
is incredibly discouraging; while I don't have "numbers" to back it up, I
definitely have tons of anecdotes on this.

On my own side, I can say this: I actually have code right now in Android;
however, there is probably no chance that I will ever bother submitting
another patch again.

What, in my experience, happens is that you submit a patch, and one person
looks at it, thinks it is great, and gives it a +1. However, he can't merge it
until someone agrees. Only, there isn't enough involvement on Google's end to
get two people to agree. It isn't like someone else disagrees: you just don't
get two peoples' opinions on the patch.

<https://android-review.googlesource.com/#/c/7288/>

That is a patch that I submitted in January of 2009. Apparently, in May of
2010, a second person agreed, and the patch was merged. Yes: 16 months later.
(There were three other patches I submitted in November of 2008 that were
merged in August of 2009, but that was a "much more reasonable" 9 month gap,
so... yeah ;P.)

<https://android-review.googlesource.com/#/c/7290/>

With this patch, that same second guy had "disagreed"; well, he wanted
justification for why I wanted the feature. Two months later, the patch died,
as I had long moved on. Now, had that question come, I dunno, a year earlier?
(So, a mere 4 months after I submitted it), maybe I'd have remembered whether
or not it was required for my use case. ;P

<https://android-review.googlesource.com/#/c/14339/>

This patch wasn't even mine, but somehow I ended up in the system as "maybe
he'll be second reviewer this time!" (and no, I have no clue how or why or
what the rules are).

Only, this was the most depressing of all: when I reviewed the patch, I
determined that the original code actually had a buffer overflow in it... this
was an _important_ patch.

The patch, of course, had already been in the system for a while: it was
submitted in April, but it wasn't until nearly two months later that I got
poked to review it. But, I don't think I actually could be "second reviewer",
so there just ended up being a bunch of +1s from random people until yet
another month went by; it finally got merged.

Another half of the problem is the same thing people here are complaining
about: that AOSP is really just "an occasionally merged external branch" to
"the real code".

The result is that when you are working on a patch, you actually can't know
whether you are working on code that even exists anymore in the upstream
branch. Maybe the code exists, but doesn't have the bug anymore; or maybe it
does, but the implementation is sufficiently different that your code no
longer merges against it.

What this means is that even if someone reviewed your patch instantly, it
already might not apply anymore, and if it doesn't it isn't like they can even
ask you to fix it.

It used to be that Google was promising that they'd merge the internal and
AOSP branches, so they'd be working in public on nearly the same codebase
(closer to Chromium). However, that promise at some point dissolved so greatly
that they simply _closed the source_ for something like eight months, not even
attempting to merge it.

Why? As far as I can tell (and I've stared at this a lot), it was to hobble
Amazon slightly, who had just announced that they were working on a tablet
based on Android. Not just "an Android tablet", but "we are going to use all
of that valuable work you did, but not pay you anything for it because we
don't need your first-party Google apps".

The code didn't become open again until Amazon started shipping their tablets
to users. At which point, the story with the open source codebase changed a
lot. Now, the promise is more "we will make certain our preferred partners get
access to the codebase quickly", but otherwise the code doesn't get dropped
until the product ships.

Due to this, when we received our Android 4.0 test devices at Google I/O, and
I soon there-after found a bug in libdl (broken shared object initializers), I
was largely screwed. I seriously wasted a week (successfully!) figuring out
what caused the bug and reverse-engineering what they changed using a
disassembler, so I could file a bug.

When I managed to get the bug filed to the mailing list was about when the
code finally dropped, so maybe that week was just wasted, but maybe I needed
that time to find it anyway. Of course, Android 4.0 shipped with that bug. The
issue was fixed in Android 4.0.1, and "luckily" almost no one upgraded to
Android 4.0 until Android 4.0.2, but... frowny. :(

------
untog
I am extremely- _extremely_ \- dubious of these claims. The app linked runs
every second- it is far more likely that this constantly running app is
keeping the CPU speed artificially high, probably at a detriment to battery
life.

There doesn't appear to be any actual benchmark evidence to back up what's
going on- just that things appear faster. Sometimes I really feel sorry for
people that administrate these bug boards. "I have no evidence to back up what
I'm saying other than gut feeling but _why won't you listen to us, Google?!?_
"

~~~
juliano_q
I am running it all day and my CPU frequencies looks the same (I am tracking
it on CPU Spy). Battery life is also the same. I didn't noticed any
improvement on my Galaxy Nexus with Android 4.2.1.

------
B-Con
Looking at the patch, they just modified rngd to populate /dev/random from
/dev/urandom instead of /dev/hwrng.

/dev/urandom in turn just uses the kernel's internal entropy pool, which is
the same one /dev/random uses, and a PRNG to stretch the entropy when the raw
entropy available is depleted.

My fear here is that the kernel's internal entropy pool is just constantly
being replaced by the PRNG output from /dev/urandom, which is then being used
by /dev/urandom to reseed it's PRNG output, causing essentially just a cascade
of a PRNG reseeding itself. In turn, /dev/urandom's PRNG was seeded by some
initial entropy condition that may have been less than optimal, especially if
it was just whatever default was there soon after boot time.

If /dev/hwrng was designed to be a primary, or worse _the_ , source of good
entropy, then this patch may have eliminated good entropy.

Anyone with kernel-level knowledge of the Linux entropy pool care to weigh in?
I don't know as much as I wish I did.

~~~
nly2
random and urandom are more or less the same... /dev/random is still a PRNG,
using the same algorithms as urandom, it just maintains a record of some
desirable degree of estimated entropy and just blocks until it's satisfied.

They also use separate entropy buffers, called the blocking and non-blocking
pools, respectively. The latter doesn't directly seed itself from the former
like you might expect.

Both use the SHA1 hash function on their buffers, presumably to prevent any
practical leakage of raw data from the pool to the outside world, and both
then mix this hash back in to their pool before outputting just half of it to
the user.

------
mistercow
It seems like a device that has a radio antenna inside it has no excuse for
ever running out of entropy.

~~~
rbanffy
May be a dangerous idea if an attacker gains control of the antenna.

~~~
mistercow
In order to exercise any control whatsoever over radio noise, the attacker
would have to have exceptional control over your surrounding environment. And
if you're sampling at a high enough frequency, the attacker isn't going to be
able to control the noise unless broadcasting it very near you. And even under
those circumstances, there will always be some outside noise that they
couldn't eliminate.

------
exabrial
Uh What? Did they just replace a cryptographically secure random generator
with a more deterministic pseudorandom generator???

Granted, blocking on /dev/random is dumb, but this is ridiculous as well...
seems like there should be a way to implement a cache in the kernel.

~~~
Freaky
FreeBSD, OS X and iOS have non-blocking /dev/random thanks to
<http://en.wikipedia.org/wiki/Yarrow_algorithm>

~~~
B-Con
Those are more or less the equivalent of /dev/urandom, not /dev/random. On
Linux, /dev/random is only raw entropy, /dev/urandom is raw entropy plus PRG
stretching when raw entropy runs out.

~~~
__alexs
/dev/random is not "raw entropy" it goes through the exact same mixing and
(SHA-1) compression stages that /dev/urandom does. It just happens to block if
there's not much entropy in the pool at the start.

Source: <http://eprint.iacr.org/2012/251.pdf> also, the kernel source.

~~~
B-Con
I understand that, my words were not precise. My point in phrasing it that way
was that there is no entropy stretching. (You only get to read (about) as much
entropy as has been gathered. You don't have to worry about reading 128 bytes
and having them be associated with the previously read 128 bytes, because the
pools that generated them are distinct.)

------
cocoflunchy
Wow! I've installed this on my old Motorola Defy running CM7 and it is _very_
noticeably faster than before. Going back to home screen is a joy!

------
aidenn0
If the effect is real, it may just be that since it's precalculating numbers
for /dev/urandom (which is possibly slow for the quantity of data needed,
particularly on a slow ARM), that means that the PRNG is run ahead-of-time
instead of on-demand. A better solution might be to keep a pool of lower-
quality bits for /dev/urandom to fall back on when the entropy pool is low.

------
neverever
[http://www.xda-developers.com/android/entropy-seed-
generator...](http://www.xda-developers.com/android/entropy-seed-generator-
not-all-its-hacked-up-to-be/) and here is what xda news has to say...

------
deelowe
My guess is that the AHA moment happened when he ran this: "watch -n x.xx cat
/proc/sys/kernel/random/entropy_avail"

Which itself appears to deplete entropy:
[http://strugglers.net/~andy/blog/2010/06/06/adventures-in-
en...](http://strugglers.net/~andy/blog/2010/06/06/adventures-in-entropy-
part-1/)

As others have said, there's good evidence that nothing in android touches
/dev/random these days.

~~~
tytso
The reason why this drains entropy is because when you start a new process
(for example "cat" in this case), the kernel passes 16 bytes of randomness at
exec time for the benefit of userspace. This allows for fast stack
randomization, without the overhead of explicitly opening and reading from
/dev/urandom.

Due to the internal kernel interface which gets used, this draws from the
/dev/random pool, thus decreasing entropy_avail, although it is not a blocking
call. There has been some discussions that the userspace randomization should
use a CRNG, or perhaps draw from the urandom pool instead.

------
buzzkillr2
I have been running this on my toro (Verizon Galaxy Nexus) AOKP rom'd phone.
Unscientifically this seems to make a difference to render speed of most
everything.

~~~
DannyBee
That's the problem though. Every report of speed increase is unscientific, and
every scientific mechanism shows it can't possibly speed anything up.

 _nothing_ is opening and using /dev/random continuously, as shown by using
inotify to watch it.

Things are using /dev/urandom, but /dev/urandom doesn't block anyway.

I see a bunch of people showing that this patch makes more entropy available
(duh), but without anything using /dev/random, that should not matter.

The only thing i can think of is that something in the kernel is asking for
random numbers from the blocking interface. Otherwise, it should show up in
inotify.

~~~
vidarh
This assertion:

> and every scientific mechanism shows it can't possibly speed anything up.

Does not follow from this:

> nothing is opening and using /dev/random continuously, as shown by using
> inotify to watch it.

The finding that nothing is opening and using /dev/random rules out the
explanation the author of the app gave. It does not in any way prove that the
app has no effect, even if it might be for totally different reasons.

Several people appear to be looking at ways of doing some proper tests to
determine if there is a real measurable effect, so we'll presumably find out
soon enough.

------
lifeguard
It would he hilarious if this patch broke some spyware that is on some phones
and not others and thus increase performance seemingly at random.

------
nwhitehead
This thread and patch are silly, but running out of entropy can be a real
performance problem sometimes. I've seen it on embedded Linux systems that
I've set up to be headless servers. After turning off lots of device drivers,
I noticed that SSH was incredibly slow sometimes. The problem was a lack of
entropy, causing reads to /dev/random to block. Like in the article, the quick
hack is to redirect /dev/urandom to /dev/random, but that isn't a real fix
because of the security implications. The right fix was digging through the
available devices and figuring out where entropy could be legitimately
captured.

------
jedahan
One explanation is that this application wakes up every second which keeps the
CPU and GPU from sleeping or lowering frequency, which would reduce the delay
introduced by whatever CPU/GPU governors are being used.

------
qxcv
This is highly amusing. As the developer on the official AOSP ticket for this
said, Java apps get their random bits from RandomBitsSupplier, which, quite
clearly, does _not_ read from /dev/urandom, as evidenced by line 72 in
[https://android.googlesource.com/platform/libcore/+/master/l...](https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/org/apache/harmony/security/provider/crypto/RandomBitsSupplier.java):

    
    
      private static final String DEVICE_NAMES[] = { "/dev/urandom" /*, "/dev/random" */ };

------
ctbeiser
Correct me if I'm wrong, but couldn't it just be that people are seeing
improvements because running this every second makes more memory heavy apps in
the background leave ram? It seems, just looking at the comments here, that
symlinkers have had no good effects, while those installing the app have.

------
ck2
Isn't this proof of a "win" for open source where an independent dev has
discovered a significant bug/performance improvement because they can examine
the source and recompile their own fix?

Would not happen on ios or mobile windows?

------
rachelbythebay
Besides the obvious thing of showing a process blocking on a read() from a
source of entropy, you could also change the minor number on /dev/random to
temporarily make it the same as /dev/urandom. No code needs to be re-compiled
or added to the system. Just make everything restart (so it grabs the right
/dev entry with the new minor number) and see if it changes.

That should tell you if it's actually a lack of entropy, or another process
undoing the CPU governor, or something else entirely.

------
mrb
I went ahead, opened a root shell on my Gingerbread phone, and symlinked
random to urandom.

No noticeable difference whatsoever.

I agree that the "speedups" reported by some users are either (1) because they
had to reboot their phones, or (2) because rngd prevents the system from going
into deeper sleep states which are costlier to recover from. There must be a
very small number of users who truly run specific apps that drain the entropy
pool, on Gingerbread, and who are helped by this hack.

~~~
BenoitEssiambre
This solution might not help because urandom depletes random entropy anyways
when there is some available.

It might be that it is not the blocking on urandom calls that is the problem
but rather depleting the entropy which triggers processes to generate more of
it at just the wrong time when processors are busy rendering things.

If the entropy would be pre-generated when the device is idle then there would
be more power available for rendering later.

~~~
mrb
There are no processes that generate entropy on a stock Android. The whole
point of the reported hack is to install such a process (rngd).

------
Shadow_Death
I've been trying this on UnSense 2.1 and 3.0 for the Thunderbolt. The APK
doesn't seem to do much even after enabled and applied on boot. The zip seems
to work once flashed in 4ext but then again it could also be the placibo
effect. I don't know if it's a all around improvement or if it's just the
Windows XP effect. "Show the desktop before windows is finished loading to
give the illusion of a faster boot time".

------
micro_cam
I have no low level experience with android but we have fought this issue on
our analytical servers. One culprit was java code (hadoop) that read small
amounts of entropy with buffered io essentially filling and discarding a large
unneeded buffer every time it needed a small unique id. It caused all sorts of
weird lags especially with ssh and was a pain to debug.

------
donretag
Too bad the version in the Play app store also requires a rooted phone:

[https://play.google.com/store/apps/details?id=com.lcis.seede...](https://play.google.com/store/apps/details?id=com.lcis.seeder)

I've done so many Linux installs back in the '90s, that nowadays I appreciate
anything that is plugin-and-go. Haven't rooted my phone yet.

~~~
brian_cloutier
I greatly appreciate that an app which messes up with chromes ability to
generate secure SSL keys requires root to run.

------
adulau
One of the option for Android would be to run havege[1] (and haveged[2]) on
the device.

[1] <http://www.irisa.fr/caps/projects/hipsor/> [2]
<http://www.issihosts.com/haveged/>

------
javanix
It seems to result in quite a bit of an improvement on my CM7 phone (Motorola
Triumph) which would fit with what Elliot Hughes said.

------
ricardobeat
The lack of actual Android developers commenting on the issue (and
testing/debugging) is astounding.

~~~
DannyBee
There is at least one actual android engineer who has responded to about 10
comments in the bug report. At this point, the bug report is mostly filled
with people saying "i think my phone goes faster, fix this bug", which is non-
helpful.

------
nsp
:s

------
JohnFromBuffalo
Have you heard that entropy isn't what it used to be?

------
stcredzero
It just occurred to me, if an entire mobile OS and its apps were written in a
language like Go, this sort of bug could conceivably never happen, because
with a few coding conventions, nothing would ever block.

~~~
rogerbinns
That isn't a fix. The problem isn't blocking as such but rather latency. If
for example a screen refresh and reading from 10 different network connections
were all done in one thread (non-blocking) it could still take some time
before the screen refresh code gets to run.

60fps gives you 16ms per frame. Correctly written Android apps (and iOS for
that matter) are expected to do work on secondary threads, and keep UI only
code in the UI thread. Of course many applications don't quite stick to that.

In the Android developer settings you can make it whine about work being done
in the UI thread (eg storage/network activity - StrictMode). You can also make
it flash a red border whenever the UI thread blocks. In Android 4.0 I used to
see a lot of red border from Google's own apps. In 4.2 it happens a lot less
often.

~~~
stcredzero
_The problem isn't blocking as such but rather latency. If for example a
screen refresh and reading from 10 different network connections were all done
in one thread (non-blocking)_

Yes, but in the sort of environment I just described, if things are done
correctly, the thread handling UI updates would not only never block, it would
never be waiting on anything high latency.

 _In the Android developer settings you can make it whine about work being
done in the UI thread_

Good to know.

~~~
rogerbinns
> Yes, but in the sort of environment I just described, if things are done
> correctly, the thread handling UI updates would not only never block, it
> would never be waiting on anything high latency.

That is already the case today for well written apps on Android (Java) and
Objective C (iOS). Rewriting in Go wouldn't be a solution. It is how the
execution is structured in any language.

