Coverage Report

Created: 2026-08-18 10:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/agent/cgroup_cpu_ctl.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <fcntl.h>
21
#include <sys/stat.h>
22
#include <sys/types.h>
23
#include <unistd.h>
24
25
#include <shared_mutex>
26
27
#include "common/config.h"
28
#include "common/status.h"
29
#include "util/cpu_info.h"
30
31
namespace doris {
32
33
class CgroupCpuCtl {
34
public:
35
33
    virtual ~CgroupCpuCtl() = default;
36
33
    CgroupCpuCtl(uint64_t wg_id) { _wg_id = wg_id; }
37
38
    virtual Status init() = 0;
39
40
    virtual Status add_thread_to_cgroup() = 0;
41
42
    void update_cpu_hard_limit(int cpu_hard_limit);
43
44
    void update_cpu_soft_limit(int cpu_shares);
45
46
    // for log
47
    void get_cgroup_cpu_info(uint64_t* cpu_shares, int* cpu_hard_limit);
48
49
    static void init_doris_cgroup_path();
50
51
    static Status delete_unused_cgroup_path(std::set<uint64_t>& used_wg_ids);
52
53
    static std::shared_ptr<CgroupCpuCtl> create_cgroup_cpu_ctl(uint64_t wg_id);
54
55
    static bool is_a_valid_cgroup_path(std::string cg_path);
56
57
    static uint64_t cpu_soft_limit_default_value();
58
59
protected:
60
    virtual Status modify_cg_cpu_hard_limit_no_lock(int cpu_hard_limit) = 0;
61
62
    virtual Status modify_cg_cpu_soft_limit_no_lock(int cpu_shares) = 0;
63
64
    Status add_thread_to_cgroup(std::string task_file);
65
66
    static Status write_cg_sys_file(std::string file_path, std::string value, std::string msg,
67
                                    bool is_append);
68
69
    static Status init_cgroup_v2_query_path_public_file(std::string home_path,
70
                                                        std::string query_path);
71
72
protected:
73
    inline static uint64_t _cpu_core_num;
74
    // TODO (yiguolei): Should echo this period to cpu.cfs_period_us???
75
    inline const static uint64_t _cpu_cfs_period_us = 100000;
76
    inline static std::string _doris_cgroup_cpu_path = "";
77
    inline static std::string _doris_cgroup_cpu_query_path = "";
78
    inline static bool _is_enable_cgroup_v1_in_env = false;
79
    inline static bool _is_enable_cgroup_v2_in_env = false;
80
    inline static bool _is_cgroup_query_path_valid = false;
81
82
    // cgroup v2 public file
83
    inline static std::string _doris_cgroup_cpu_path_subtree_ctl_file = "";
84
    inline static std::string _cgroup_v2_query_path_subtree_ctl_file = "";
85
    inline static std::string _doris_cg_v2_procs_file = "";
86
87
protected:
88
    int _cpu_hard_limit = 0;
89
    std::shared_mutex _lock_mutex;
90
    bool _init_succ = false;
91
    uint64_t _wg_id = -1; // workload group id
92
    uint64_t _cpu_shares = 0;
93
};
94
95
/*
96
    NOTE: directory structure
97
    1 sys cgroup root path:
98
        /sys/fs/cgroup
99
    
100
    2 sys cgroup cpu controller path:
101
        /sys/fs/cgroup/cpu
102
    
103
    3 doris home path:
104
        /sys/fs/cgroup/cpu/{doris_home}/
105
    
106
    4 doris query path
107
        /sys/fs/cgroup/cpu/{doris_home}/query
108
    
109
    5 workload group path
110
        /sys/fs/cgroup/cpu/{doris_home}/query/{workload group id}
111
    
112
    6 workload group quota file:
113
        /sys/fs/cgroup/cpu/{doris_home}/query/{workload group id}/cpu.cfs_quota_us
114
    
115
    7 workload group tasks file:
116
        /sys/fs/cgroup/cpu/{doris_home}/query/{workload group id}/tasks
117
    
118
    8 workload group cpu.shares file:
119
    /sys/fs/cgroup/cpu/{doris_home}/query/{workload group id}/cpu.shares
120
*/
121
class CgroupV1CpuCtl : public CgroupCpuCtl {
122
public:
123
0
    CgroupV1CpuCtl(uint64_t tg_id) : CgroupCpuCtl(tg_id) {}
124
    Status init() override;
125
    Status modify_cg_cpu_hard_limit_no_lock(int cpu_hard_limit) override;
126
    Status modify_cg_cpu_soft_limit_no_lock(int cpu_shares) override;
127
    Status add_thread_to_cgroup() override;
128
129
private:
130
    std::string _cgroup_v1_cpu_tg_path; // workload group path
131
    std::string _cgroup_v1_cpu_tg_quota_file;
132
    std::string _cgroup_v1_cpu_tg_shares_file;
133
    std::string _cgroup_v1_cpu_tg_task_file;
134
};
135
136
/*
137
    NOTE: cgroup v2 directory structure
138
    1 root path:
139
        /sys/fs/cgroup
140
    
141
    2 doris home path:
142
        /sys/fs/cgroup/{doris_home}/
143
144
    3 doris home subtree_control file:
145
        /sys/fs/cgroup/{doris_home}/cgroup.subtree_control
146
    
147
    4 query path:
148
        /sys/fs/cgroup/{doris_home}/query/
149
150
    5 query path subtree_control file:
151
        /sys/fs/cgroup/{doris_home}/query/cgroup.subtree_control
152
153
    6 query path procs file:
154
        /sys/fs/cgroup/{doris_home}/query/cgroup.procs
155
156
    7 workload group path:
157
        /sys/fs/cgroup/{doris_home}/query/{workload_group_id}
158
159
    8 workload grou cpu.max file:
160
        /sys/fs/cgroup/{doris_home}/query/{workload_group_id}/cpu.max
161
162
    9 workload grou cpu.weight file:
163
        /sys/fs/cgroup/{doris_home}/query/{workload_group_id}/cpu.weight
164
165
    10 workload group cgroup type file:
166
        /sys/fs/cgroup/{doris_home}/query/{workload_group_id}/cgroup.type
167
168
*/
169
class CgroupV2CpuCtl : public CgroupCpuCtl {
170
public:
171
33
    CgroupV2CpuCtl(uint64_t tg_id) : CgroupCpuCtl(tg_id) {}
172
    Status init() override;
173
    Status modify_cg_cpu_hard_limit_no_lock(int cpu_hard_limit) override;
174
    Status modify_cg_cpu_soft_limit_no_lock(int cpu_shares) override;
175
    Status add_thread_to_cgroup() override;
176
177
private:
178
    std::string _cgroup_v2_query_wg_path;
179
    std::string _cgroup_v2_query_wg_cpu_max_file;
180
    std::string _cgroup_v2_query_wg_cpu_weight_file;
181
    std::string _cgroup_v2_query_wg_thread_file;
182
    std::string _cgroup_v2_query_wg_type_file;
183
};
184
185
} // namespace doris