Open Bug 1401628 Opened 2 years ago Updated 10 months ago

consider throttling or pausing workers for background tabs

Categories

(Core :: DOM: Workers, enhancement, P3)

57 Branch
enhancement

Tracking

()

Tracking Status
firefox57 --- affected

People

(Reporter: bkelly, Unassigned)

References

Details

It seems some sites are experimenting with bitcoin mining as an alternative to ads:

http://www.creativeapplications.net/mining-for-xmr/

Whether that is reasonable or not is probably up to the user, but it does seem abusive for tabs that are in the background or not visible.  We should probably consider throttling or pausing dedicated workers for background tabs.  This would be consistent with our policies to throttle setTimeout, rAF, etc on background tabs.
Andreas, Ehsan, this may interest you given your work towards reducing the impact of background tabs.
Anne, would this require a spec change?
Flags: needinfo?(annevk)
Priority: -- → P3
Might be best to ask lth. As long as there's still the guarantee of forward progress I think it should be okay. We just shouldn't let it end up in a situation where we create deadlocks.
Flags: needinfo?(annevk) → needinfo?(lhansen)
Throttling workers should be OK, but pausing is going to be a problem for both JS and WebAssembly that use workers for shared-memory threads.  (For WebAssembly that might change, eventually - but only by making some lighter-weight notion of threads available, and they will have the same issue.)

Workers that are shared-memory threads will probably have their own event loops though, so throttling by reducing eg message delivery frequency will likely not be effective.  You may have to forcibly reprioritize the thread as it moves to the background and back into the foreground.
Flags: needinfo?(lhansen)
What do you mean by "workers that are shared-memory threads"?  Does this just mean using SharedArrayBuffer?

My idea was that if we decided that a worker needed to be throttled we would trigger a js interrupt, block the thread for a while, and then let it continue after some amount of time passes.  The goal would be to limit CPU usage over some time window to a configurable percentage.

> You may have to forcibly reprioritize the thread as it moves to the background and back into the foreground.

This is inadequate for this kind of abuse, though.  We should not let background sites drain the users battery.
See comment 5, please.
Flags: needinfo?(lhansen)
Interrupting and blocking for a while should be just fine.  The blocking Atomics.wait has also been designed to be properly interruptible without the user program needing to worry about it, in case we end up blocking a thread that is already blocking.
Flags: needinfo?(lhansen)
Luke suggested another mitigation could be to pin background workers to a single core.  This would not be completely adequate because a they could still use 50% CPU on low-end dual-core machines, but it would be a nice first step.  It could also have battery improvements by limiting CPU wakeups across many cores.

Nathan, do you know if we have any primitives in xpcom or mfbt to pin threads to a single core?
I forgot to NI for comment 8.  Do we have any gecko APIs to pin threads to a single CPU core?

I don't see anything here:

http://searchfox.org/mozilla-central/source/nsprpub/pr/include/prthread.h
Flags: needinfo?(nfroyd)
Last I looked there was nothing reliable cross-platform for pinning a thread.  Notably MacOS only had advisory APIs last I looked and did not implement the pthread affinity API.  Of course if there's something on Windows then that solves most of the problem, so I'd love to hear more.

Older findings here:
https://github.com/tc39/ecmascript_sharedmem/issues/1#issuecomment-173644263

Background for that post:
https://github.com/tc39/ecmascript_sharedmem/issues/1#issuecomment-146700460
(In reply to Ben Kelly [:bkelly] from comment #8)
> Nathan, do you know if we have any primitives in xpcom or mfbt to pin
> threads to a single core?

We do not.  I see that Windows has SetThreadAffinityMask:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms686247(v=vs.85).aspx

which I assume works the same was as pthread_setaffinity_np.  I'm surprised that nothing exists for MacOS.
Flags: needinfo?(nfroyd)
See also bug 1401628.  I wonder if people will become annoyed even by foreground tabs burning up all their CPUs and so we'll need some affinity-based throttling even there.
Oops, I meant bug 1403281.
Blocks: 1403109
Note that there are reports of coin miners in addons (Chrome extensions) too:

- https://www.ghacks.net/2017/09/19/first-chrome-extension-with-javascript-crypto-miner-detected/

- (in French) https://securite.intrinsec.com/2017/10/06/malwares-crypto-monnaies-et-fournisseurs/

"A Chrome add-on (Short URL (goo.gl), fortunately quite uncommon) has been embedding a bit.js file since its latest release, which contains the CoinHive's JS source, and it seems to continuously run it as long as the addon is active."

Do addons run under the same privilege settings as background tabs? If not, we might need to mitigate against this.
See Also: → 1275621
Possible solution reported at bug https://bugzilla.mozilla.org/show_bug.cgi?id=1403109
Please consider making this a priority. Mining on websites is in the news again (https://www.theverge.com/2018/2/13/17008158/salon-suppress-ads-cryptocurrency-mining-coinhive-monero-beta-testing). 

I think Firefox should get in front of this. An interim solution like pausing everything and showing a message like "This tab consumes lots of resources. [Leave page][Stay on page]" might be enough to discurage this kind of thing from spreading.
You need to log in before you can comment on or make changes to this bug.