Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: chrome/browser/memory/tab_manager_delegate_chromeos.cc

Issue 2247433002: TabManager: Set OOM scores via a new debugd interface on ChromeOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/memory/tab_manager_delegate_chromeos.h" 5 #include "chrome/browser/memory/tab_manager_delegate_chromeos.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 14 matching lines...) Expand all
25 #include "base/synchronization/lock.h" 25 #include "base/synchronization/lock.h"
26 #include "base/time/time.h" 26 #include "base/time/time.h"
27 #include "chrome/browser/chromeos/arc/arc_process.h" 27 #include "chrome/browser/chromeos/arc/arc_process.h"
28 #include "chrome/browser/chromeos/arc/arc_process_service.h" 28 #include "chrome/browser/chromeos/arc/arc_process_service.h"
29 #include "chrome/browser/memory/tab_stats.h" 29 #include "chrome/browser/memory/tab_stats.h"
30 #include "chrome/browser/ui/browser.h" 30 #include "chrome/browser/ui/browser.h"
31 #include "chrome/browser/ui/browser_list.h" 31 #include "chrome/browser/ui/browser_list.h"
32 #include "chrome/browser/ui/tabs/tab_strip_model.h" 32 #include "chrome/browser/ui/tabs/tab_strip_model.h"
33 #include "chrome/common/chrome_constants.h" 33 #include "chrome/common/chrome_constants.h"
34 #include "chrome/common/chrome_features.h" 34 #include "chrome/common/chrome_features.h"
35 #include "chromeos/dbus/dbus_thread_manager.h"
36 #include "chromeos/dbus/debug_daemon_client.h"
35 #include "components/arc/arc_bridge_service.h" 37 #include "components/arc/arc_bridge_service.h"
36 #include "components/arc/common/process.mojom.h" 38 #include "components/arc/common/process.mojom.h"
37 #include "components/arc/metrics/oom_kills_histogram.h" 39 #include "components/arc/metrics/oom_kills_histogram.h"
38 #include "components/exo/shell_surface.h" 40 #include "components/exo/shell_surface.h"
39 #include "content/public/browser/browser_thread.h" 41 #include "content/public/browser/browser_thread.h"
40 #include "content/public/browser/notification_service.h" 42 #include "content/public/browser/notification_service.h"
41 #include "content/public/browser/notification_types.h" 43 #include "content/public/browser/notification_types.h"
42 #include "content/public/browser/render_process_host.h" 44 #include "content/public/browser/render_process_host.h"
43 #include "content/public/browser/render_widget_host.h" 45 #include "content/public/browser/render_widget_host.h"
44 #include "content/public/browser/zygote_host_linux.h" 46 #include "content/public/browser/zygote_host_linux.h"
(...skipping 28 matching lines...) Expand all
73 return false; 75 return false;
74 std::string application_id = exo::ShellSurface::GetApplicationId(window); 76 std::string application_id = exo::ShellSurface::GetApplicationId(window);
75 return base::StartsWith(application_id, kArcProcessNamePrefix, 77 return base::StartsWith(application_id, kArcProcessNamePrefix,
76 base::CompareCase::SENSITIVE); 78 base::CompareCase::SENSITIVE);
77 } 79 }
78 80
79 bool IsArcMemoryManagementEnabled() { 81 bool IsArcMemoryManagementEnabled() {
80 return base::FeatureList::IsEnabled(features::kArcMemoryManagement); 82 return base::FeatureList::IsEnabled(features::kArcMemoryManagement);
81 } 83 }
82 84
85 void OnSetOomScoreAdj(bool success, const std::string& output) {
86 VLOG(2) << "OnSetOomScoreAdj " << success << " " << output;
87 if (!success || output != "") {
Georges Khalil 2016/08/15 18:47:54 nit: !output.empty() nit: no braces
cylee1 2016/08/16 19:47:10 Done.
88 LOG(WARNING) << "Set OOM score error: " << output;
89 }
90 }
91
83 } // namespace 92 } // namespace
84 93
85 std::ostream& operator<<(std::ostream& os, const ProcessType& type) { 94 std::ostream& operator<<(std::ostream& os, const ProcessType& type) {
86 switch (type) { 95 switch (type) {
87 case ProcessType::FOCUSED_APP: 96 case ProcessType::FOCUSED_APP:
88 return os << "FOCUSED_APP/FOCUSED_TAB"; 97 return os << "FOCUSED_APP/FOCUSED_TAB";
89 case ProcessType::VISIBLE_APP: 98 case ProcessType::VISIBLE_APP:
90 return os << "VISIBLE_APP"; 99 return os << "VISIBLE_APP";
91 case ProcessType::BACKGROUND_APP: 100 case ProcessType::BACKGROUND_APP:
92 return os << "BACKGROUND_APP"; 101 return os << "BACKGROUND_APP";
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 // The focused process doesn't render a tab. Could happen when the focus 489 // The focused process doesn't render a tab. Could happen when the focus
481 // just switched to an ARC app. We can not avoid the race. 490 // just switched to an ARC app. We can not avoid the race.
482 if (pid == base::kNullProcessHandle) 491 if (pid == base::kNullProcessHandle)
483 return; 492 return;
484 { 493 {
485 base::AutoLock oom_score_autolock(oom_score_lock_); 494 base::AutoLock oom_score_autolock(oom_score_lock_);
486 oom_score_map_[pid] = chrome::kLowestRendererOomScore; 495 oom_score_map_[pid] = chrome::kLowestRendererOomScore;
487 } 496 }
488 VLOG(3) << "Set OOM score " << chrome::kLowestRendererOomScore 497 VLOG(3) << "Set OOM score " << chrome::kLowestRendererOomScore
489 << " for focused tab " << pid; 498 << " for focused tab " << pid;
490 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore( 499 std::map<int, int> dict;
491 pid, chrome::kLowestRendererOomScore); 500 dict[pid] = chrome::kLowestRendererOomScore;
501 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->SetOomScoreAdj(
502 dict, base::Bind(&OnSetOomScoreAdj));
492 } 503 }
493 504
494 void TabManagerDelegate::OnFocusTabScoreAdjustmentTimeout() { 505 void TabManagerDelegate::OnFocusTabScoreAdjustmentTimeout() {
495 BrowserThread::PostTask( 506 BrowserThread::PostTask(
496 BrowserThread::FILE, FROM_HERE, 507 BrowserThread::FILE, FROM_HERE,
497 base::Bind(&TabManagerDelegate::AdjustFocusedTabScoreOnFileThread, 508 base::Bind(&TabManagerDelegate::AdjustFocusedTabScoreOnFileThread,
498 base::Unretained(this))); 509 base::Unretained(this)));
499 } 510 }
500 511
501 void TabManagerDelegate::AdjustFocusedTabScore(base::ProcessHandle pid) { 512 void TabManagerDelegate::AdjustFocusedTabScore(base::ProcessHandle pid) {
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 DistributeOomScoreInRange(candidates.begin(), lower_priority_part, 750 DistributeOomScoreInRange(candidates.begin(), lower_priority_part,
740 chrome::kLowestRendererOomScore, range_middle, 751 chrome::kLowestRendererOomScore, range_middle,
741 &new_map); 752 &new_map);
742 // Lower priority part. 753 // Lower priority part.
743 DistributeOomScoreInRange(lower_priority_part, candidates.end(), range_middle, 754 DistributeOomScoreInRange(lower_priority_part, candidates.end(), range_middle,
744 chrome::kHighestRendererOomScore, &new_map); 755 chrome::kHighestRendererOomScore, &new_map);
745 base::AutoLock oom_score_autolock(oom_score_lock_); 756 base::AutoLock oom_score_autolock(oom_score_lock_);
746 oom_score_map_.swap(new_map); 757 oom_score_map_.swap(new_map);
747 } 758 }
748 759
749 void TabManagerDelegate::SetOomScoreAdjForApp(int nspid, int score) { 760 void TabManagerDelegate::SetOomScoreAdj(
750 if (!arc_process_instance_)
751 return;
752 if (arc_process_instance_version_ < 2) {
753 VLOG(1) << "ProcessInstance version < 2 does not "
754 "support SetOomScoreAdj() yet.";
755 return;
756 }
757 arc_process_instance_->SetOomScoreAdj(nspid, score);
758 }
759
760 void TabManagerDelegate::SetOomScoreAdjForTabs(
761 const std::vector<std::pair<base::ProcessHandle, int>>& entries) { 761 const std::vector<std::pair<base::ProcessHandle, int>>& entries) {
762 BrowserThread::PostTask( 762 BrowserThread::PostTask(
763 BrowserThread::FILE, FROM_HERE, 763 BrowserThread::FILE, FROM_HERE,
764 base::Bind(&TabManagerDelegate::SetOomScoreAdjForTabsOnFileThread, 764 base::Bind(&TabManagerDelegate::SetOomScoreAdjOnFileThread,
765 base::Unretained(this), entries)); 765 base::Unretained(this), entries));
766 } 766 }
767 767
768 void TabManagerDelegate::SetOomScoreAdjForTabsOnFileThread( 768 // XXX: In the past it writes to procfs directly so running in file thread.
769 // Now it talks to debugd via DBus and the write is done in debugd
770 // asynchronously. Consider moving it back to UI thread.
771 void TabManagerDelegate::SetOomScoreAdjOnFileThread(
769 const std::vector<std::pair<base::ProcessHandle, int>>& entries) { 772 const std::vector<std::pair<base::ProcessHandle, int>>& entries) {
770 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 773 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
771 for (const auto& entry : entries) { 774
772 content::ZygoteHost::GetInstance()->AdjustRendererOOMScore(entry.first, 775 std::map<int, int> dict;
773 entry.second); 776 // Ignore duplicated keys but the last occurrence.
774 } 777 for (const auto& entry : entries)
778 dict[entry.first] = entry.second;
779 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->SetOomScoreAdj(
hashimoto 2016/08/15 03:54:23 D-Bus clients are not thread-safe. They must be ac
cylee1 2016/08/16 19:47:10 Done.
780 dict, base::Bind(&OnSetOomScoreAdj));
775 } 781 }
776 782
777 void TabManagerDelegate::DistributeOomScoreInRange( 783 void TabManagerDelegate::DistributeOomScoreInRange(
778 std::vector<TabManagerDelegate::Candidate>::const_iterator begin, 784 std::vector<TabManagerDelegate::Candidate>::const_iterator begin,
779 std::vector<TabManagerDelegate::Candidate>::const_iterator end, 785 std::vector<TabManagerDelegate::Candidate>::const_iterator end,
780 int range_begin, 786 int range_begin,
781 int range_end, 787 int range_end,
782 ProcessScoreMap* new_map) { 788 ProcessScoreMap* new_map) {
783 // OOM score setting for tabs involves file system operation so should be 789 std::vector<std::pair<base::ProcessHandle, int>> oom_scores_to_change;
784 // done on file thread.
785 std::vector<std::pair<base::ProcessHandle, int>> oom_score_for_tabs;
786 790
787 // Though there might be duplicate process handles, it doesn't matter to 791 // Though there might be duplicate process handles, it doesn't matter to
788 // overestimate the number of processes here since the we don't need to 792 // overestimate the number of processes here since the we don't need to
789 // use up the full range. 793 // use up the full range.
790 int num = (end - begin); 794 int num = (end - begin);
791 const float priority_increment = 795 const float priority_increment =
792 static_cast<float>(range_end - range_begin) / num; 796 static_cast<float>(range_end - range_begin) / num;
793 797
794 float priority = range_begin; 798 float priority = range_begin;
795 for (auto cur = begin; cur != end; ++cur) { 799 for (auto cur = begin; cur != end; ++cur) {
796 int score = static_cast<int>(priority + 0.5f); 800 int score = static_cast<int>(priority + 0.5f);
797 if (cur->app()) { 801 if (cur->app()) {
802 base::ProcessHandle pid = cur->app()->pid();
798 // Use pid as map keys so it's globally unique. 803 // Use pid as map keys so it's globally unique.
799 (*new_map)[cur->app()->pid()] = score; 804 (*new_map)[pid] = score;
800 int cur_app_pid_score = 0; 805 int cur_app_pid_score = 0;
801 { 806 {
802 base::AutoLock oom_score_autolock(oom_score_lock_); 807 base::AutoLock oom_score_autolock(oom_score_lock_);
803 cur_app_pid_score = oom_score_map_[cur->app()->pid()]; 808 cur_app_pid_score = oom_score_map_[pid];
804 } 809 }
805 if (cur_app_pid_score != score) { 810 if (cur_app_pid_score != score) {
806 VLOG(3) << "Set OOM score " << score << " for " << *cur; 811 VLOG(3) << "Set OOM score " << score << " for " << *cur;
807 SetOomScoreAdjForApp(cur->app()->nspid(), score); 812 oom_scores_to_change.push_back(std::make_pair(pid, score));
808 } 813 }
809 } else { 814 } else {
810 base::ProcessHandle process_handle = cur->tab()->renderer_handle; 815 base::ProcessHandle process_handle = cur->tab()->renderer_handle;
811 // 1. tab_list contains entries for already-discarded tabs. If the PID 816 // 1. tab_list contains entries for already-discarded tabs. If the PID
812 // (renderer_handle) is zero, we don't need to adjust the oom_score. 817 // (renderer_handle) is zero, we don't need to adjust the oom_score.
813 // 2. Only add unseen process handle so if there's multiple tab maps to 818 // 2. Only add unseen process handle so if there's multiple tab maps to
814 // the same process, the process is set to an OOM score based on its "most 819 // the same process, the process is set to an OOM score based on its "most
815 // important" tab. 820 // important" tab.
816 if (process_handle != 0 && 821 if (process_handle != 0 &&
817 new_map->find(process_handle) == new_map->end()) { 822 new_map->find(process_handle) == new_map->end()) {
818 (*new_map)[process_handle] = score; 823 (*new_map)[process_handle] = score;
819 int process_handle_score = 0; 824 int process_handle_score = 0;
820 { 825 {
821 base::AutoLock oom_score_autolock(oom_score_lock_); 826 base::AutoLock oom_score_autolock(oom_score_lock_);
822 process_handle_score = oom_score_map_[process_handle]; 827 process_handle_score = oom_score_map_[process_handle];
823 } 828 }
824 if (process_handle_score != score) { 829 if (process_handle_score != score) {
825 oom_score_for_tabs.push_back(std::make_pair(process_handle, score));
826 VLOG(3) << "Set OOM score " << score << " for " << *cur; 830 VLOG(3) << "Set OOM score " << score << " for " << *cur;
831 oom_scores_to_change.push_back(std::make_pair(process_handle, score));
827 } 832 }
828 } else { 833 } else {
829 continue; // Skip priority increment. 834 continue; // Skip priority increment.
830 } 835 }
831 } 836 }
832 priority += priority_increment; 837 priority += priority_increment;
833 } 838 }
834 839
835 if (oom_score_for_tabs.size()) 840 if (oom_scores_to_change.size())
836 SetOomScoreAdjForTabs(oom_score_for_tabs); 841 SetOomScoreAdj(oom_scores_to_change);
837 } 842 }
838 843
839 } // namespace memory 844 } // namespace memory
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698