New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 756311 link

Starred by 6 users

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Aug 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 1
Type: Bug



Sign in to add a comment

Heavy CPU usage on tab restore

Project Member Reported by borisv@chromium.org, Aug 17 2017

Issue description

Chrome Version: 62.0.3187.0
OS: OSX 10.12.6
What steps will reproduce the problem?
(1) Open several tabs, including these:
    gmail.com, calendar.google.com, business insider articles, http://mytaglist.com/index.html, if google employee, open Cider.
(2) Open a new tab and navigate to chrome://restart. Alternatively, set Chrome to restore tabs, close it and open it again.
(3) Go to Menu/More Tools/Task manager and order by CPU.

What is the expected result?
Short spike in CPU usage that goes away.

What happens instead?
A few tabs (Calendar is typical), that are not active, end up hitting 100% CPU forever. If you are on laptop, the CPU fans become very noise. Activating these tabs even for a short time fixes the problem.

Please use labels and text to provide additional information.


For graphics-related bugs, please copy/paste the contents of the about:gpu
page at the end of this report.

 

Comment 1 by borisv@chromium.org, Aug 17 2017

The issue seems to be with onetimers firing too early. The code below resets the timer to start 5 seconds later. However, instead of 5s later, the timer fires immediately. If the timer is not restarted in these lines, the CPU usage increase is not observed. I also added diagnostic printouts in RendererWebMediaPlayerDelegate::UpdateTask() and the code obviously gets into infinite loops of removing and re-adding idle players with lay less than 5s firing of that timer.

https://cs.chromium.org/chromium/src/content/renderer/media/renderer_webmediaplayer_delegate.cc?rcl=72818ed6711498ddaf5d2eb2e16158b176bfa31e&l=348

  idle_cleanup_timer_.Stop();
  if (!idle_player_map_.empty()) {
    idle_cleanup_timer_.Start(
        FROM_HERE, idle_cleanup_interval_,
        base::Bind(&RendererWebMediaPlayerDelegate::UpdateTask,
                   base::Unretained(this)));
  }
Cc: borisv@chromium.org
Labels: -Pri-3 M-62 Pri-1
Owner: sande...@chromium.org
Status: Assigned (was: Untriaged)
Cc: hubbe@chromium.org
+hubbe who had changes here recently. We should make sure this isn't related to the patch just merged to M61.

Comment 4 by borisv@chromium.org, Aug 17 2017

The problem seems to be triggered by this change. 
https://chromium.googlesource.com/chromium/src/+/d2506f13c3fba1e6f3280c5ccb0a6802360aad8b

This change causes an infinite loop of adding and removing a player to the idle_player_map_:
1. RendererWebMediaPlayerDelegate::UpdateTask() is called on timer every 15 s
2. This results in a call to RendererWebMediaPlayerDelegate::CleanUpIdlePlayers(15s)
3. CleanupIdlePlayers removes the player from idle_player_map_ and adds it the player to stale_players_. Then it calls player->OnIdleTimeout()
4. OnIdleTimeout() checks "IfPrerollAttemptNeeded()" after the CL above returns true (even though the tab is not active).
5. This causes RendererWebMediaPlayerDelegate::ClearStaleFlag to be called, which erases the player from state_players_ and re-adds it to the idle_player_map_.
6. RendererWebMediaPlayerDelegate::ClearStaleFlag reschedules the update task

Cc: -hubbe@chromium.org sande...@chromium.org
Owner: hubbe@chromium.org
Thanks for tracking it down. hubbe@ can you revert that patch for now?
(Or fix if its reasonable).

Comment 7 by hubbe@chromium.org, Aug 17 2017

It's in the queue to be reverted.
It looks like this is triggering a latent bug in RendererWebMediaPlayerDelegate, whereby prerolling elements can result in a task posting loop.

The solution is a change to how ClearStaleFlag() works--it should set a new expiry time that is at least some distance into the future (eg. 1 second), and that distance should not be overridden by the aggressive cleanup mode.

It might be time to review the ClearStaleFlag() idea again, it was a hack that reduced code complexity, but it's clearly at some cost to predictability. In an ideal world, WMPI would not consider itself to be idle while prerolling and then we wouldn't need it at all.

Comment 9 by borisv@chromium.org, Aug 17 2017

Yep, pushing out the update was a solution I considered too before hubbe reverted the CL as a mitigation to the issue. 

But on a similar note, why do we even do the whole idle_player_map_ and stale_plaers_ dance? In fact, why do we even bother with updating the state for inactive tab? Isn't it smarter to preserve power in this case?
The state machine here is a bit much to cover in a bug, but it comes down to JS events. If we don't progress through the playback process, many pages will be broken. The goal is to move to the 'Suspended' state when idle, but we do so carefully.

On Android, we have an additional type of suspend, background suspend, which is a little more forceful about inactive tabs. The process is similarly careful, but the result is more janky than desktop.
Would returning 'false' in IfPrerollAttemptNeeded() for inactive tab going to break such events? No prerolling will happen, so we are probably lying anyway.
Ultimately, if the CL is reverted, this bug should be fixed. There are multiple ways for hubbe@ to re-implement the original CL and I will leave to hubbe@ to decide the best approach. 
Cc: charliea@chromium.org
Luckily this is caught by our benchmark infrastructure (charliea@ discovered that this blows up the trace size & reverted it in  issue 756003 ).

When you reland the CL, can you run perf tryjob to make sure that it doesn't regress?

Comment 14 by ojan@chromium.org, Aug 21 2017

How is the media player getting instantiated on these sites? Is this just for the audio the gmail, etc. use to notify for chats?

Are issues 756455 and  713504  duplicates of this?
Issue 756455 has been merged into this issue.
I am not sure about how the media player is instantiated. But I broke it into debugger and confirmed comment 4 above. Also, I changed the code and confirmed that this is not happening anymore. Furthermore, the issue is not observed after the CL was reverted, while before that I had 100% stable repro.

I think crbug/756455 is a duplicate of this issue, based on UpdateState present heavily in the stack. I just merged that bug into the current issue.

crbug/713504 is different - it was originally reported in April, but then it was reactivated again after the aforementioned CL started impacting the Canary. I am not sure what to do with that one. Most likely the original issue was long gone. I will drop a comment there too, but I won't resolve as duplicate.
Cc: altimin@chromium.org skyos...@chromium.org panicker@chromium.org
 Issue 713504  has been merged into this issue.
hubbe@, are we okay to mark this as Fixed now?

Comment 20 by hubbe@chromium.org, Aug 25 2017

Status: Fixed (was: Assigned)
Yes.

Sign in to add a comment