From 2f13f0a48a6fded990e68b03ab1e44edf8c58164 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 1 Jul 2016 17:45:06 -0700 Subject: [PATCH] sched_policy: Add support for /proc//timerslack_ns over PR_SET_TIMERSLACK_PID The PR_SET_TIMERSLACK_PID number has collided with upstream changes a number of times, and thus the number is not consistent between AOSP common kernel versions. In 4.6+, the upstream kernel added equivalent functionaity via the /proc//timerslack_ns entry. This patch changes the sched_policy logic to support /proc//timerslack_ns if its available, falling back to the older PR_SET_TIMERSLACK_PID method if not. NOTE: Eventually PR_SET_TIMERSLACK_PID usage will need to be removed as it is likely to conflict with valid future upstream PR_* entries. Also add missing O_CLOEXEC to other open calls in this file. Change-Id: Iec0b8a62de0dc8bdd57b60df82bd4d31c5d64709 Signed-off-by: John Stultz --- libcutils/sched_policy.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c index 7bb8223be..d7b4b0be1 100644 --- a/libcutils/sched_policy.c +++ b/libcutils/sched_policy.c @@ -160,7 +160,7 @@ static int getSchedulerGroup(int tid, char* buf, size_t bufLen) FILE *fp; snprintf(pathBuf, sizeof(pathBuf), "/proc/%d/cgroup", tid); - if (!(fp = fopen(pathBuf, "r"))) { + if (!(fp = fopen(pathBuf, "re"))) { return -1; } @@ -292,6 +292,27 @@ int set_cpuset_policy(int tid, SchedPolicy policy) #endif } +static void set_timerslack_ns(int tid, unsigned long long slack) { + char buf[64]; + + /* v4.6+ kernels support the /proc//timerslack_ns interface. */ + snprintf(buf, sizeof(buf), "/proc/%d/timerslack_ns", tid); + int fd = open(buf, O_WRONLY | O_CLOEXEC); + if (fd != -1) { + int len = snprintf(buf, sizeof(buf), "%llu", slack); + if (write(fd, buf, len) != len) { + SLOGE("set_timerslack_ns write failed: %s\n", strerror(errno)); + } + close(fd); + return; + } + + /* If the above fails, try the old common.git PR_SET_TIMERSLACK_PID. */ + if (prctl(PR_SET_TIMERSLACK_PID, slack, tid) == -1) { + SLOGE("set_timerslack_ns prctl failed: %s\n", strerror(errno)); + } +} + int set_sched_policy(int tid, SchedPolicy policy) { if (tid == 0) { @@ -304,12 +325,11 @@ int set_sched_policy(int tid, SchedPolicy policy) char statfile[64]; char statline[1024]; char thread_name[255]; - int fd; snprintf(statfile, sizeof(statfile), "/proc/%d/stat", tid); memset(thread_name, 0, sizeof(thread_name)); - fd = open(statfile, O_RDONLY); + int fd = open(statfile, O_RDONLY | O_CLOEXEC); if (fd >= 0) { int rc = read(fd, statline, 1023); close(fd); @@ -372,8 +392,8 @@ int set_sched_policy(int tid, SchedPolicy policy) ¶m); } - prctl(PR_SET_TIMERSLACK_PID, - policy == SP_BACKGROUND ? TIMER_SLACK_BG : TIMER_SLACK_FG, tid); + set_timerslack_ns(tid, policy == SP_BACKGROUND ? + TIMER_SLACK_BG : TIMER_SLACK_FG); return 0; }