Android 10 trở lên sử dụng một nhóm đối chứng (cgroup) tầng trừu tượng có hồ sơ tác vụ mà nhà phát triển có thể sử dụng để mô tả một tập hợp (hoặc tập hợp) các quy định hạn chế áp dụng cho một luồng hoặc một quy trình. Khi đó, hệ thống tuân theo các hành động được quy định trong hồ sơ công việc để chọn một hoặc nhiều các nhóm phù hợp, thông qua đó các hạn chế được áp dụng và các thay đổi đối với có thể thiết lập bộ tính năng cơ bản của cgroup mà không ảnh hưởng đến phần mềm cao hơn các lớp.
Giới thiệu về cgroups
Cgroups cung cấp một cơ chế để tổng hợp và phân vùng các nhóm tác vụ (bao gồm các quy trình, luồng và tất cả các tác vụ con trong tương lai) thành các nhóm phân cấp với hành vi chuyên biệt. Android sử dụng các nhóm để kiểm soát và tính đến các tài nguyên hệ thống như sử dụng và phân bổ CPU và bộ nhớ, có hỗ trợ cho Cgroups cho nhân hệ điều hành Linux phiên bản 1 và cgroups v2.
Android 9 trở xuống
Trong Android 9 trở xuống, tập lệnh khởi chạy init.rc
chứa tập hợp
cgroups có sẵn, các điểm gắn kết và phiên bản của chúng. Mặc dù những cách này có thể
đã thay đổi, khung Android kỳ vọng sẽ có một tập hợp nhóm cụ thể
các vị trí cụ thể có phiên bản và hệ phân cấp nhóm con cụ thể, dựa trên
tập lệnh. Điều này hạn chế khả năng chọn phiên bản cgroup tiếp theo để sử dụng hoặc thay đổi hệ phân cấp cgroup để sử dụng các tính năng mới.
Android 10 trở lên
Android 10 trở lên sử dụng các nhóm có hồ sơ tác vụ:
- Thiết lập nhóm. Nhà phát triển mô tả cách thiết lập nhóm kênh này trong
cgroups.json
để xác định các nhóm nhóm cũng như vị trí và thuộc tính gắn kết của chúng. Tất cả các cgroups được liên kết trong giai đoạn khởi tạo sớm của quá trình khởi chạy của chúng tôi. - Hồ sơ việc cần làm. Các lớp này cung cấp một bản tóm tắt tách biệt chức năng bắt buộc khỏi thông tin chi tiết về cách triển khai chức năng đó. Khung Android áp dụng hồ sơ tác vụ như mô tả trong tệp
task_profiles.json
cho một quy trình hoặc luồng bằng cách sử dụng APISetTaskProfiles
vàSetProcessProfiles
. (Các API này chỉ dành riêng cho Android 11 trở lên.)
Để cung cấp khả năng tương thích ngược, các hàm cũ set_cpuset_policy
,
set_sched_policy
và get_sched_policy
cung cấp API và chức năng giống nhau,
nhưng cách triển khai của chúng đã được sửa đổi để sử dụng hồ sơ công việc. Dành cho người dùng mới
trường hợp AOSP đề xuất sử dụng API hồ sơ tác vụ mới thay vì API cũ
Hàm set_sched_policy
.
Tệp mô tả Cgroups
Các nhóm được mô tả trong cgroups.json
nằm trong <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
.
Mỗi bộ điều khiển được mô tả trong một tiểu mục và phải có tối thiểu các yếu tố sau:
- Tên, do trường Controller (Bộ điều khiển) xác định.
- Đường dẫn gắn kết, được xác định bằng trường Path (Đường dẫn).
- Mode (Chế độ), UID (mã nhận dạng người dùng) và GID (mã nhóm) mô tả chủ sở hữu và chế độ truy cập cho các tệp trong đường dẫn này (tất cả đều không bắt buộc).
- Thuộc tính không bắt buộc, đặt thành true để cho phép hệ thống bỏ qua yêu cầu gắn lỗi do trình điều khiển cgroup gây ra mà nhân hệ điều hành không hỗ trợ được kết nối.
Ví dụ về tệp cgroups.json
Ví dụ bên dưới cho thấy nội dung mô tả cho cgroup v1 (Cgroups
) và cgroup v2
(Cgroups2
) với đường dẫn tương ứng.
{
"Cgroups": [
{
"Controller": "cpu",
"Path": "/dev/cpuctl",
"Mode": "0755",
"UID": "system",
"GID": "system"
},
{
"Controller": "memory",
"Path": "/dev/memcg",
"Mode": "0700",
"Optional": true
}
],
"Cgroups2": {
"Path": "/sys/fs/cgroup",
"Mode": "0755",
"UID": "system",
"GID": "system",
"Controllers": [
{
"Controller": "freezer",
"Path": ".",
"Mode": "0755",
"UID": "system",
"GID": "system"
}
]
}
}
Tệp mẫu này chứa hai phần, Cgroups (mô tả trình điều khiển cgroup v1) và Cgroups2 (mô tả trình điều khiển cgroup v2). Tất cả
các bộ điều khiển trong hệ phân cấp cgroups v2 được gắn kết tại cùng một vị trí.
Do đó, mục Cgroups2 có Đường dẫn, Chế độ, UID riêng và
Các thuộc tính GID để mô tả vị trí và các thuộc tính của gốc
thứ bậc. Thuộc tính Path (Đường dẫn) cho Controllers (Bộ điều khiển) trong Cgroups2 tương ứng với đường dẫn gốc đó. Trong Android 12 trở lên, bạn có thể xác định một cgroup
bộ điều khiển được chỉ định với đường dẫn và chế độ là "Optional"
bằng cách đặt thành true
.
Tệp cgroups.json
được phân tích cú pháp trong quá trình khởi tạo, trong quá trình khởi tạo sớm
và các nhóm được gắn tại các vị trí đã chỉ định. Để nhận sau này
các vị trí gắn kết cgroup, hãy sử dụng hàm API CgroupGetControllerPath
.
Tệp hồ sơ việc cần làm
task_profiles.json
nằm trong <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
.
Sử dụng thuộc tính này để mô tả một nhóm hành động cụ thể sẽ được áp dụng cho một quy trình hoặc một
chuỗi. Một tập hợp các hành động được liên kết với tên hồ sơ, được dùng trong các lệnh gọi SetTaskProfiles
và SetProcessProfiles
để gọi các hành động trong hồ sơ.
Ví dụ về tệp task_profiles.json
{
"Attributes": [
{
"Name": "MemSoftLimit",
"Controller": "memory",
"File": "memory.soft_limit_in_bytes"
},
{
"Name": "MemSwappiness",
"Controller": "memory",
"File": "memory.swappiness"
}
],
"Profiles": [
{
"Name": "MaxPerformance",
"Actions" : [
{
"Name" : "JoinCgroup",
"Params" :
{
"Controller": "schedtune",
"Path": "top-app"
}
}
]
},
{
"Name": "TimerSlackHigh",
"Actions" : [
{
"Name" : "SetTimerSlack",
"Params" :
{
"Slack": "40000000"
}
}
]
},
{
"Name": "LowMemoryUsage",
"Actions" : [
{
"Name" : "SetAttribute",
"Params" :
{
"Name" : "MemSoftLimit",
"Value" : "16MB"
}
},
{
"Name" : "SetAttribute",
"Params" :
{
"Name" : "MemSwappiness",
"Value" : "150"
}
}
]
}
]
"AggregateProfiles": [
{
"Name": "SCHED_SP_DEFAULT",
"Profiles": [ "TimerSlackHigh", "MaxPerformance" ]
},
{
"Name": "SCHED_SP_BACKGROUND",
"Profiles": [ "LowMemoryUsage" ]
}
}
Gán tên cho các tệp cgroup cụ thể dưới dạng mục nhập trong danh sách Attributes (Thuộc tính). Mỗi mục nhập chứa các thông tin sau:
- Trường Name (Tên) chỉ định tên của Thuộc tính.
- Trường Controller (Đơn vị điều khiển) tham chiếu đến một đơn vị kiểm soát cgroup từ
cgroups.json
theo tên. - Trường Tệp đặt tên cho một tệp cụ thể trong bộ điều khiển này.
Thuộc tính là các tham chiếu trong định nghĩa hồ sơ công việc. Ngoài nhiệm vụ hồ sơ, chỉ sử dụng các hồ sơ đó khi khung yêu cầu quyền truy cập trực tiếp vào các hồ sơ đó tệp và quyền truy cập không thể trừu tượng hoá bằng hồ sơ công việc. Trong tất cả các trường hợp khác, sử dụng hồ sơ công việc; chúng giúp phân tách tốt hơn giữa hành vi bắt buộc và thông tin chi tiết về việc triển khai.
Phần Profiles (Hồ sơ) chứa các định nghĩa về hồ sơ công việc như sau:
- Trường Name (Tên) xác định tên hồ sơ.
Phần Thao tác liệt kê một tập hợp các thao tác được thực hiện khi hồ sơ được áp dụng. Mỗi thao tác đều có:
- Trường Name (Tên) chỉ định hành động.
- Phần Params (Tham số) chỉ định một nhóm tham số cho thao tác.
Các thao tác được hỗ trợ được liệt kê trong bảng:
Hành động | Thông số | Mô tả |
---|---|---|
SetTimerSlack |
Slack |
Độ trễ của bộ tính giờ tính bằng ns |
SetAttribute |
Name |
Tên tham chiếu đến một thuộc tính trong mục Thuộc tính |
Value |
Một giá trị được ghi vào tệp được biểu thị bằng thuộc tính có tên | |
WriteFile | FilePath | đường dẫn đến tệp |
Value | một giá trị cần ghi vào tệp | |
JoinCgroup |
Controller |
Tên của đơn vị kiểm soát cgroup trong cgroups.json |
Path |
Đường dẫn nhóm con trong hệ phân cấp của bộ điều khiển cgroup |
Android 12 trở lên có AggregateProfiles chứa các hồ sơ tổng hợp, mỗi hồ sơ là một bí danh của một tập hợp một hoặc nhiều hồ sơ. Định nghĩa hồ sơ tổng hợp bao gồm:
- Trường Name (Tên) chỉ định tên của hồ sơ tổng hợp.
- Trường Hồ sơ liệt kê tên của hồ sơ có trong hồ sơ tổng hợp.
Khi áp dụng hồ sơ tổng hợp, tất cả các hồ sơ chứa cũng sẽ được được áp dụng tự động. Hồ sơ tổng hợp có thể chứa cả hồ sơ riêng lẻ hoặc hồ sơ tổng hợp khác, miễn là không có đệ quy (một hồ sơ bao gồm chính nó).
Lệnh ngôn ngữ trong phần mềm task_profiles init
Lệnh task_profiles
trong Ngôn ngữ khởi động Android có sẵn cho Android 12 trở lên để hỗ trợ kích hoạt hồ sơ tác vụ cho một quy trình cụ thể. Phương thức này thay thế cho writepid
lệnh (không dùng nữa trong Android 12) dùng để di chuyển một
giữa các nhóm. Lệnh task_profiles
mang lại sự linh hoạt để
thay đổi các phương pháp triển khai cơ bản mà không ảnh hưởng đến các lớp trên. Trong ví dụ dưới đây, hai lệnh này thực hiện cùng một thao tác một cách hiệu quả:
writepid /dev/cpuctl/top-app/tasks
Không dùng nữa trong Android 12, tuỳ chọn này được dùng để ghi PID của công việc hiện tại vào tệp
/dev/cpuctl/top-app/tasks
.task_profiles MaxPerformance
Tham gia quy trình hiện tại vào nhóm ứng dụng hàng đầu trong "cpu" tay điều khiển (
cpuctl
), dẫn đến việc ghi PID của quá trình vàodev/cpuctl/top-app/tasks
.
Luôn sử dụng lệnh task_profiles
để di chuyển các công việc trong hệ phân cấp cgroup trong
Android 12 trở lên. Hàm này chấp nhận một hoặc nhiều thông số, đại diện cho
tên của cấu hình được chỉ định trong tệp task_profiles.json
.
Theo hồ sơ tác vụ cấp độ API
Trong Android 12 trở lên, bạn có thể sửa đổi hoặc ghi đè
định nghĩa trong các tệp cgroups.json
và task_profiles.json
mặc định, có thể là
dựa trên thay đổi của bạn ở cấp độ API Android hoặc tạo thay đổi từ nhà cung cấp
phân vùng.
Để ghi đè các định nghĩa dựa trên cấp độ API, các tệp sau phải có trên thiết bị:
/system/etc/task_profiles/cgroups_<API level>.json
Sử dụng thuộc tính này cho các nhóm dành riêng cho một cấp độ API.
/system/etc/task_profiles/task_profiles_<API level>.json
Sử dụng thuộc tính này cho hồ sơ dành riêng cho một cấp độ API.
Để ghi đè định nghĩa trong phân vùng nhà cung cấp, các tệp sau phải xuất hiện trên thiết bị:
/vendor/etc/cgroups.json
/vendor/etc/task_profiles.json
Nếu một thuộc tính hoặc định nghĩa hồ sơ trong các tệp này sử dụng cùng tên với tên trong tệp mặc định, thì định nghĩa tệp (cấp độ API hoặc cấp nhà cung cấp) sẽ ghi đè định nghĩa trước đó. Ngoài ra, xin lưu ý rằng các định nghĩa ở cấp nhà cung cấp sẽ ghi đè Định nghĩa cấp độ API. Nếu định nghĩa mới có tên mới, thì tập hợp thuộc tính hoặc hồ sơ được sửa đổi với định nghĩa mới.
Hệ thống Android tải các tệp cgroup
và task_profile
theo thứ tự sau:
- Mặc định
cgroups.json
vàtask_profiles.json
tệp. - Tệp dành riêng cho cấp độ API, nếu có.
- Tệp phân vùng của nhà cung cấp, nếu có.
Thay đổi đối với API hiện có
Android 10 trở lên giữ nguyên các hàm set_cpuset_policy
,
set_sched_policy
và get_sched_policy
không có thay đổi về API.
Tuy nhiên, Android 10 chuyển các hàm này sang
libprocessgroup
, hiện chứa tất cả chức năng liên quan đến cgroup.
Mặc dù tiêu đề cutils/sched_policy.h
vẫn tồn tại, nhưng để tránh bị lỗi
mã hiện tại đảm bảo rằng mã mới bao gồm processgroup/sched_policy.h
mới
để thay thế.
Các mô-đun sử dụng bất kỳ hàm nào trong số này phải thêm phần phụ thuộc trên
libprocessgroup
vào tệp makefile của họ. Nếu một mô-đun không sử dụng bất kỳ
Chức năng libcutils
, hãy bỏ libcutils
phần phụ thuộc thư viện khỏi tệp makefile.
API hồ sơ tác vụ
Các API riêng tư trong processgroup/processgroup.h
được định nghĩa trong bảng:
Loại | API và định nghĩa |
---|---|
bool |
SetTaskProfiles(int tid, const std::vector
Áp dụng hồ sơ tác vụ được chỉ định trong profiles cho luồng được chỉ định bởi
mã nhận dạng luồng (thu gọn) bằng cách sử dụng tham số tid . |
bool |
SetProcessProfiles(uid_t uid, pid_t pid, const std::vector
Áp dụng hồ sơ tác vụ được chỉ định trong profiles cho quy trình được chỉ định
theo mã nhận dạng người dùng và mã quy trình bằng tham số uid và pid |
bool |
CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)
Trả về việc một tay điều khiển nhóm do cgroup_name chỉ định có tồn tại hay không;
nếu là true , hãy đặt biến path thành gốc của nhóm đó |
bool |
CgroupGetAttributePath(const std::string& attr_name, std::string* path)
Trả về liệu thuộc tính hồ sơ do attr_name chỉ định có tồn tại hay không; nếu
true , hãy đặt biến path thành đường dẫn của tệp liên kết với
thuộc tính hồ sơ đó. |
bool |
CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)
Trả về liệu thuộc tính hồ sơ do attr_name chỉ định có tồn tại hay không; nếu
true , hãy đặt biến path thành đường dẫn của tệp liên kết với
thuộc tính hồ sơ đó và với luồng do mã luồng chỉ định bằng cách sử dụng
tham số tid . |
bool |
UsePerAppMemcg()
Trả về việc hệ thống có được định cấu hình để sử dụng các nhóm bộ nhớ cho mỗi ứng dụng hay không. |