Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cutils: Add support for ioprio cgroup #1

Open
wants to merge 1 commit into
base: mm6.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/cutils/iosched_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ typedef enum {
extern int android_set_ioprio(int pid, IoSchedClass clazz, int ioprio);
extern int android_get_ioprio(int pid, IoSchedClass *clazz, int *ioprio);

extern int android_set_rt_ioprio(int pid, int rt);

#ifdef __cplusplus
}
#endif
Expand Down
101 changes: 89 additions & 12 deletions libcutils/iosched_policy.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/*
** Copyright 2007, The Android Open Source Project
** Copyright 2007-2014, The Android Open Source Project
** Copyright 2015, The CyanogenMod Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
Expand All @@ -20,28 +21,30 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

#include <cutils/iosched_policy.h>
#define LOG_TAG "iosched_policy"
#include <cutils/log.h>

#define __android_unused __attribute__((__unused__))

#ifdef HAVE_ANDROID_OS
#include <linux/ioprio.h>
#include <sys/syscall.h>
#define __android_unused
#else
#define __android_unused __attribute__((__unused__))
#endif
#include <sys/stat.h>

static int __rtio_cgroup_supported = -1;
static pthread_once_t __rtio_init_once = PTHREAD_ONCE_INIT;

int android_set_ioprio(int pid __android_unused, IoSchedClass clazz __android_unused, int ioprio __android_unused) {
#ifdef HAVE_ANDROID_OS
if (syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, pid, ioprio | (clazz << IOPRIO_CLASS_SHIFT))) {
return -1;
}
#endif
return 0;
}

int android_get_ioprio(int pid __android_unused, IoSchedClass *clazz, int *ioprio) {
#ifdef HAVE_ANDROID_OS
int rc;

if ((rc = syscall(SYS_ioprio_get, IOPRIO_WHO_PROCESS, pid)) < 0) {
Expand All @@ -50,9 +53,83 @@ int android_get_ioprio(int pid __android_unused, IoSchedClass *clazz, int *iopri

*clazz = (rc >> IOPRIO_CLASS_SHIFT);
*ioprio = (rc & 0xff);
return 0;
}

static void __initialize_rtio(void) {
if (!access("/sys/fs/cgroup/bfqio/tasks", W_OK) ||
!access("/sys/fs/cgroup/bfqio/rt-display/tasks", W_OK)) {
__rtio_cgroup_supported = 1;
} else {
__rtio_cgroup_supported = 0;
}
}

int android_set_rt_ioprio(int tid, int rt) {
int fd = -1, rc = -1;

pthread_once(&__rtio_init_once, __initialize_rtio);
if (__rtio_cgroup_supported != 1) {
return -1;
}

if (rt) {
fd = open("/sys/fs/cgroup/bfqio/rt-display/tasks", O_WRONLY | O_CLOEXEC);
} else {
fd = open("/sys/fs/cgroup/bfqio/tasks", O_WRONLY | O_CLOEXEC);
}

if (fd < 0) {
return -1;
}

#ifdef HAVE_GETTID
if (tid == 0) {
tid = gettid();
}
#endif

// specialized itoa -- works for tid > 0
char text[22];
char *end = text + sizeof(text) - 1;
char *ptr = end;
*ptr = '\0';
while (tid > 0) {
*--ptr = '0' + (tid % 10);
tid = tid / 10;
}

rc = write(fd, ptr, end - ptr);
if (rc < 0) {
/*
* If the thread is in the process of exiting,
* don't flag an error
*/
if (errno == ESRCH) {
rc = 0;
} else {
SLOGV("android_set_rt_ioprio failed to write '%s' (%s); fd=%d\n",
ptr, strerror(errno), fd);
}
}

close(fd);
return rc;
}

#else
int android_set_ioprio(int pid __android_unused, IoSchedClass clazz __android_unused, int ioprio __android_unused) {
return 0;
}

int android_get_ioprio(int pid __android_unused, IoSchedClass *clazz, int *ioprio) {
*clazz = IoSchedClass_NONE;
*ioprio = 0;
#endif
return 0;
}

int android_set_rt_ioprio(int tid __android_unused, int rt __android_unused)
{
return 0;
}
#endif