summaryrefslogtreecommitdiff
path: root/android-tools/cpuctl.txt
blob: eae05b0b0858bbc7cb046301f733c7cc609e4461 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
In init.rc, there are following settings related cpuctl
    # Create cgroup mount points for process groups
    mkdir /dev/cpuctl
    mount cgroup none /dev/cpuctl cpu
    chown system system /dev/cpuctl
    chown system system /dev/cpuctl/tasks
    chmod 0666 /dev/cpuctl/tasks
    write /dev/cpuctl/cpu.shares 1024
    write /dev/cpuctl/cpu.rt_runtime_us 800000
    write /dev/cpuctl/cpu.rt_period_us 1000000

    mkdir /dev/cpuctl/bg_non_interactive
    chown system system /dev/cpuctl/bg_non_interactive/tasks
    chmod 0666 /dev/cpuctl/bg_non_interactive/tasks
    # 5.0 %
    write /dev/cpuctl/bg_non_interactive/cpu.shares 52
    write /dev/cpuctl/bg_non_interactive/cpu.rt_runtime_us 700000
    write /dev/cpuctl/bg_non_interactive/cpu.rt_period_us 1000000


In Documentation/scheduler/sched-rt-group.txt, cpu.rt_runtime_us is described as following:
    2.3 Basis for grouping tasks
    ----------------------------

    Enabling CONFIG_RT_GROUP_SCHED lets you explicitly allocate real
    CPU bandwidth to task groups.

    This uses the cgroup virtual file system and "<cgroup>/cpu.rt_runtime_us"
    to control the CPU time reserved for each control group.

    For more information on working with control groups, you should read
    Documentation/cgroups/cgroups.txt as well.

    Group settings are checked against the following limits in order to keep the 
    configuration schedulable:

       \Sum_{i} runtime_{i} / global_period <= global_runtime / global_period

    For now, this can be simplified to just the following (but see Future plans):

        \Sum_{i} runtime_{i} <= global_runtime

In Documentation/scheduler/sched-rt-group.txt, cpu.rt_period_us is described as following:
    3. Future plans
    ===============

    There is work in progress to make the scheduling period for each group
    ("<cgroup>/cpu.rt_period_us") configurable as well.

    The constraint on the period is that a subgroup must have a smaller or
    equal period to its parent. But realistically its not very useful _yet_
    as its prone to starvation without deadline scheduling.

    Consider two sibling groups A and B; both have 50% bandwidth, but A's 
    period is twice the length of B's.

    * group A: period=100000us, runtime=10000us
        - this runs for 0.01s once every 0.1s

    * group B: period= 50000us, runtime=10000us
        - this runs for 0.01s twice every 0.1s (or once every 0.05 sec).

    This means that currently a while (1) loop in A will run for the full period of
    B and can starve B's tasks (assuming they are of lower priority) for a whole
    period.


In Documentation/scheduler/sched-design-CFS.txt, cpu.shares is described as following:
    When CONFIG_FAIR_GROUP_SCHED is defined, a "cpu.shares" file is created for each
    group created using the pseudo filesystem.  See example steps below to create
    task groups and modify their CPU share using the "cgroups" pseudo filesystem.

        # mount -t tmpfs cgroup_root /sys/fs/cgroup
        # mkdir /sys/fs/cgroup/cpu
        # mount -t cgroup -ocpu none /sys/fs/cgroup/cpu
        # cd /sys/fs/cgroup/cpu

        # mkdir multimedia  # create "multimedia" group of tasks
        # mkdir browser     # create "browser" group of tasks

        # #Configure the multimedia group to receive twice the CPU bandwidth
        # #that of browser group

        # echo 2048 > multimedia/cpu.shares
        # echo 1024 > browser/cpu.shares

        # firefox & # Launch firefox and move it to "browser" group
        # echo <firefox_pid> > browser/tasks

        # #Launch gmplayer (or your favourite movie player)
        # echo <movie_player_pid> > multimedia/tasks



In system/core/libcutils/sched_policy.c:

    int set_sched_policy(int tid, SchedPolicy policy)
    {
        if (tid == 0) {
            tid = gettid();
        }
        policy = _policy(policy);
        pthread_once(&the_once, __initialize);
        .....
        if (__sys_supports_schedgroups) {
            int fd;
            switch (policy) {
                case SP_BACKGROUND:
                    fd = bg_cgroup_fd;
                    break;
                case SP_FOREGROUND:
                case SP_AUDIO_APP:
                case SP_AUDIO_SYS:
                    fd = fg_cgroup_fd;
                    break;
                default:
                    fd = -1;
                    break;
            }

            if (add_tid_to_cgroup(tid, fd) != 0) {
                if (errno != ESRCH && errno != ENOENT) return -errno;
            }
        } else {
            struct sched_param param;

            param.sched_priority = 0;
            sched_setscheduler(tid, (policy == SP_BACKGROUND) ? SCHED_BATCH : SCHED_NORMAL, &param);
        }

        prctl(PR_SET_TIMERSLACK_PID, policy == SP_BACKGROUND ? TIMER_SLACK_BG : TIMER_SLACK_FG, tid);

        return 0;
    }

SP_BACKGROUND will be set to the background group,
and the SP_FOREGROUND/SP_AUDIO_APP/SP_AUDIO_SYS will be set to foreground group

And set_sched_policy is only used in set_cpuset_policy when ENABLE_CPUSETS  is set:
   int set_cpuset_policy(int tid, SchedPolicy policy)
   {
       // in the absence of cpusets, use the old sched policy
   #ifndef USE_CPUSETS
       return set_sched_policy(tid, policy);
   #else
       ....
   }


Following are the places where set_sched_policy is called:
12:03:08 liuyq: marshmallow$ grep -rn set_sched_policy system/
system/bt/utils/src/bt_utils.c:127:        // set_sched_policy does not support tid == 0
system/bt/utils/src/bt_utils.c:128:        rc = set_sched_policy(tid, SP_AUDIO_SYS);
system/core/logd/main.cpp:90:    if (set_sched_policy(0, SP_BACKGROUND) < 0) {
system/core/logd/main.cpp:170:    set_sched_policy(0, SP_BACKGROUND);
system/core/include/cutils/sched_policy.h:29:    SP_SYSTEM     = 2,  // can't be used with set_sched_policy()
system/core/include/cutils/sched_policy.h:45:extern int set_sched_policy(int tid, SchedPolicy policy);
system/core/logcat/logcat.cpp:216:        if (set_sched_policy(0, SP_BACKGROUND) < 0) {
system/core/libutils/Threads.cpp:89:            set_sched_policy(0, SP_BACKGROUND);
system/core/libutils/Threads.cpp:91:            set_sched_policy(0, SP_FOREGROUND);
    Called in androidCreateThreadEtc, androidCreateRawThreadEtc when Thread initialized with canCallJava
system/core/libutils/Threads.cpp:313:        rc = set_sched_policy(tid, SP_BACKGROUND);
system/core/libutils/Threads.cpp:315:        rc = set_sched_policy(tid, SP_FOREGROUND);
    Called in functions in androidSetThreadPriority
        called by android_os_Process_setThreadPriority in frameworks/base/core/jni/android_util_Process.cpp
        others are called by media projects
system/core/libcutils/sched_policy.c:245:    return set_sched_policy(tid, policy);
system/core/libcutils/sched_policy.c:277:int set_sched_policy(int tid, SchedPolicy policy)
system/core/libcutils/sched_policy.c:367:int set_sched_policy(int tid UNUSED, SchedPolicy policy UNUSED)
12:03:13 liuyq: marshmallow$ grep -rn set_sched_policy frameworks/
frameworks/av/media/libmedia/AudioTrack.cpp:581:            set_sched_policy(0, mPreviousSchedulingGroup);
frameworks/av/media/libmedia/AudioTrack.cpp:621:        set_sched_policy(0, mPreviousSchedulingGroup);
frameworks/av/media/libmedia/AudioRecord.cpp:359:        set_sched_policy(0, mPreviousSchedulingGroup);
frameworks/av/media/libmedia/IMediaMetadataRetriever.cpp:54:    set_sched_policy(gettid(), policy);
frameworks/av/media/libmedia/IMediaMetadataRetriever.cpp:58:    set_sched_policy(gettid(), SP_FOREGROUND);
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp:259:  errno = -set_sched_policy(0, SP_DEFAULT);
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp:261:    ALOGE("set_sched_policy(0, SP_DEFAULT) failed");
frameworks/base/core/jni/android_util_Process.cpp:170:    int res = set_sched_policy(tid, sp);
frameworks/base/core/jni/android_util_Process.cpp:272:        err = set_sched_policy(t_pid, sp);
frameworks/native/libs/binder/IPCThreadState.cpp:447:        set_sched_policy(mMyThreadId, SP_FOREGROUND);
frameworks/native/libs/binder/IPCThreadState.cpp:486:    set_sched_policy(mMyThreadId, SP_FOREGROUND);
frameworks/native/libs/binder/IPCThreadState.cpp:1066:                    set_sched_policy(mMyThreadId, SP_BACKGROUND);
frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp:42:    set_sched_policy(0, SP_FOREGROUND);
frameworks/native/cmds/installd/commands.cpp:1086:        if (set_sched_policy(0, SP_BACKGROUND) < 0) {
frameworks/native/cmds/installd/commands.cpp:1087:            ALOGE("set_sched_policy failed: %s\n", strerror(errno));
12:04:01 liuyq: marshmallow$