Commit f1e72007 authored by Ikjoon Jang's avatar Ikjoon Jang Committed by Chromium LUCI CQ

base/thread: Fix sched_setattr() arguments for uclamp

Set valid sched_flag and uclamp range to sched_setattr(),
Without this, desired uclamp values are not applied to the task:

- sched_setattr() should have appropriated flags to apply uclamp
  min/max values to kernel.
- sched_setattr() is not using percentage format, fix it to use
  real capacity scale (~1024)

BUG=1041117
TEST=check /proc/*/sched for all urgent threads

Change-Id: I0dcdbf843591e2916fd10c6fe524f4dd71dcd20f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2518536
Commit-Queue: Ikjoon Jang <ikjn@chromium.org>
Reviewed-by: default avatarDarin Fisher <darin@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarBrian Geffon <bgeffon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837351}
parent 39313249
...@@ -46,6 +46,11 @@ namespace { ...@@ -46,6 +46,11 @@ namespace {
std::atomic<bool> g_use_sched_util(true); std::atomic<bool> g_use_sched_util(true);
std::atomic<bool> g_scheduler_hints_adjusted(false); std::atomic<bool> g_scheduler_hints_adjusted(false);
// When a device doesn't specify uclamp values via chrome switches,
// default boosting for urgent tasks is hardcoded here as 20%.
// Higher values can lead to higher power consumption thus this value
// is chosen conservatively where it does not show noticeable
// power usage increased from several perf/power tests.
const int kSchedulerBoostDef = 20; const int kSchedulerBoostDef = 20;
const int kSchedulerLimitDef = 100; const int kSchedulerLimitDef = 100;
const bool kSchedulerUseLatencyTuneDef = true; const bool kSchedulerUseLatencyTuneDef = true;
...@@ -55,6 +60,11 @@ int g_scheduler_limit_adj; ...@@ -55,6 +60,11 @@ int g_scheduler_limit_adj;
bool g_scheduler_use_latency_tune_adj; bool g_scheduler_use_latency_tune_adj;
#if !defined(OS_NACL) && !defined(OS_AIX) #if !defined(OS_NACL) && !defined(OS_AIX)
// Defined by linux uclamp ABI of sched_setattr().
const uint32_t kSchedulerUclampMin = 0;
const uint32_t kSchedulerUclampMax = 1024;
// sched_attr is used to set scheduler attributes for Linux. It is not a POSIX // sched_attr is used to set scheduler attributes for Linux. It is not a POSIX
// struct and glibc does not expose it. // struct and glibc does not expose it.
struct sched_attr { struct sched_attr {
...@@ -97,6 +107,14 @@ struct sched_attr { ...@@ -97,6 +107,14 @@ struct sched_attr {
#endif #endif
#endif #endif
#if !defined(SCHED_FLAG_UTIL_CLAMP_MIN)
#define SCHED_FLAG_UTIL_CLAMP_MIN 0x20
#endif
#if !defined(SCHED_FLAG_UTIL_CLAMP_MAX)
#define SCHED_FLAG_UTIL_CLAMP_MAX 0x40
#endif
int sched_getattr(pid_t pid, int sched_getattr(pid_t pid,
const struct sched_attr* attr, const struct sched_attr* attr,
unsigned int size, unsigned int size,
...@@ -164,7 +182,8 @@ void SetThreadLatencySensitivity(ProcessId process_id, ...@@ -164,7 +182,8 @@ void SetThreadLatencySensitivity(ProcessId process_id,
ThreadPriority priority) { ThreadPriority priority) {
struct sched_attr attr; struct sched_attr attr;
bool is_urgent = false; bool is_urgent = false;
int uclamp_min_urgent, uclamp_max_non_urgent, latency_sensitive_urgent; int boost_percent, limit_percent;
int latency_sensitive_urgent;
// Scheduler boost defaults to true unless disabled. // Scheduler boost defaults to true unless disabled.
if (!g_use_sched_util.load()) if (!g_use_sched_util.load())
...@@ -172,12 +191,12 @@ void SetThreadLatencySensitivity(ProcessId process_id, ...@@ -172,12 +191,12 @@ void SetThreadLatencySensitivity(ProcessId process_id,
// FieldTrial API can be called only once features were parsed. // FieldTrial API can be called only once features were parsed.
if (g_scheduler_hints_adjusted.load()) { if (g_scheduler_hints_adjusted.load()) {
uclamp_min_urgent = g_scheduler_boost_adj; boost_percent = g_scheduler_boost_adj;
uclamp_max_non_urgent = g_scheduler_limit_adj; limit_percent = g_scheduler_limit_adj;
latency_sensitive_urgent = g_scheduler_use_latency_tune_adj; latency_sensitive_urgent = g_scheduler_use_latency_tune_adj;
} else { } else {
uclamp_min_urgent = kSchedulerBoostDef; boost_percent = kSchedulerBoostDef;
uclamp_max_non_urgent = kSchedulerLimitDef; limit_percent = kSchedulerLimitDef;
latency_sensitive_urgent = kSchedulerUseLatencyTuneDef; latency_sensitive_urgent = kSchedulerUseLatencyTuneDef;
} }
...@@ -226,14 +245,20 @@ void SetThreadLatencySensitivity(ProcessId process_id, ...@@ -226,14 +245,20 @@ void SetThreadLatencySensitivity(ProcessId process_id,
<< "Failed to write latency file.\n"; << "Failed to write latency file.\n";
} }
attr.sched_flags |= SCHED_FLAG_UTIL_CLAMP_MIN;
attr.sched_flags |= SCHED_FLAG_UTIL_CLAMP_MAX;
if (is_urgent) { if (is_urgent) {
attr.sched_util_min = uclamp_min_urgent; attr.sched_util_min = (boost_percent * kSchedulerUclampMax + 50) / 100;
attr.sched_util_max = 100; attr.sched_util_max = kSchedulerUclampMax;
} else { } else {
attr.sched_util_min = 0; attr.sched_util_min = kSchedulerUclampMin;
attr.sched_util_max = uclamp_max_non_urgent; attr.sched_util_max = (limit_percent * kSchedulerUclampMax + 50) / 100;
} }
DCHECK_GE(attr.sched_util_min, kSchedulerUclampMin);
DCHECK_LE(attr.sched_util_max, kSchedulerUclampMax);
attr.size = sizeof(struct sched_attr); attr.size = sizeof(struct sched_attr);
if (sched_setattr(thread_id, &attr, 0) == -1) { if (sched_setattr(thread_id, &attr, 0) == -1) {
// We log it as an error because, if the PathExists above succeeded, we // We log it as an error because, if the PathExists above succeeded, we
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment