Android 10 ขึ้นไปใช้เลเยอร์การแยกส่วนของกลุ่มควบคุม (cgroup) ที่มีโปรไฟล์งาน ซึ่งนักพัฒนาแอปสามารถใช้เพื่ออธิบายชุด (หรือชุด) ข้อจำกัดที่จะใช้กับเธรดหรือกระบวนการ จากนั้นระบบจะ ทำตามการดำเนินการที่กำหนดไว้ในโปรไฟล์งานเพื่อเลือก Cgroup ที่เหมาะสมอย่างน้อย 1 รายการ ซึ่งจะใช้ข้อจำกัด และทำการเปลี่ยนแปลงชุดฟีเจอร์ Cgroup พื้นฐานได้โดยไม่ส่งผลกระทบต่อเลเยอร์ซอฟต์แวร์ที่สูงกว่า
เกี่ยวกับ Cgroup
Cgroup เป็นกลไกในการรวบรวมและแบ่งพาร์ติชันชุดงาน (ซึ่งประกอบด้วยกระบวนการ เธรด และองค์ประกอบย่อยทั้งหมดในอนาคต) เป็นกลุ่มลำดับชั้น ที่มีลักษณะการทำงานเฉพาะ Android ใช้ cgroup เพื่อควบคุมและบันทึก ทรัพยากรของระบบ เช่น การใช้งานและการจัดสรร CPU และหน่วยความจำ โดยรองรับ เคอร์เนล Linux cgroup v1 และ cgroup v2
Android 9 และต่ำกว่า
ใน Android 9 และเวอร์ชันที่ต่ำกว่า init.rc
สคริปต์การเริ่มต้นมีชุด
cgroup ที่ใช้ได้ จุดติดตั้ง และเวอร์ชัน แม้ว่าค่าเหล่านี้จะ
เปลี่ยนแปลงได้ แต่เฟรมเวิร์ก Android คาดหวังให้มีชุด cgroup ที่เฉพาะเจาะจงใน
ตำแหน่งที่เฉพาะเจาะจงที่มีเวอร์ชันและลำดับชั้นของกลุ่มย่อยที่เฉพาะเจาะจงตาม
สคริปต์ ซึ่งจำกัดความสามารถในการเลือกเวอร์ชัน cgroup ถัดไปที่จะใช้ หรือเปลี่ยนลำดับชั้น cgroup เพื่อใช้ฟีเจอร์ใหม่
Android 10 ขึ้นไป
Android 10 ขึ้นไปใช้ cgroup ที่มีโปรไฟล์งาน
- การตั้งค่า Cgroup นักพัฒนาซอฟต์แวร์อธิบายการตั้งค่า cgroup ใน
cgroups.json
ไฟล์เพื่อกำหนดชุด cgroup รวมถึงตำแหน่งการติดตั้งและแอตทริบิวต์ ระบบจะติดตั้ง Cgroup ทั้งหมดในระหว่างขั้นตอนการเริ่มต้นช่วงแรกของกระบวนการเริ่มต้น - โปรไฟล์งาน ซึ่งจะช่วยให้คุณแยกฟังก์ชันการทำงานที่จำเป็นออกจากรายละเอียดของการติดตั้งใช้งานได้ เฟรมเวิร์ก Android
ใช้โปรไฟล์งานตามที่อธิบายไว้ในไฟล์
task_profiles.json
กับกระบวนการหรือเธรดโดยใช้ APISetTaskProfiles
และSetProcessProfiles
(API เหล่านี้ใช้ได้เฉพาะใน Android 11 ขึ้นไป)
ฟังก์ชันเดิม set_cpuset_policy
,
set_sched_policy
และ get_sched_policy
มี API และฟังก์ชันการทำงานเหมือนกัน
แต่มีการแก้ไขการใช้งานให้ใช้โปรไฟล์งานเพื่อมอบความเข้ากันได้แบบย้อนหลัง สำหรับ Use Case ใหม่ AOSP ขอแนะนำให้ใช้ API โปรไฟล์งานใหม่แทนฟังก์ชัน set_sched_policy
เดิม
ไฟล์คำอธิบาย Cgroups
Cgroup มีคำอธิบายอยู่ในไฟล์ cgroups.json
ซึ่งอยู่ใน <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
ตัวควบคุมแต่ละตัวจะอธิบายไว้ในส่วนย่อยและต้องมีอย่างน้อยดังต่อไปนี้
- ชื่อที่กำหนดโดยฟิลด์ตัวควบคุม
- เส้นทางการติดตั้งที่กำหนดโดยฟิลด์เส้นทาง
- โหมด, UID (รหัสผู้ใช้) และ GID (รหัสกลุ่ม) ที่อธิบายเจ้าของและ โหมดการเข้าถึงสำหรับไฟล์ภายใต้เส้นทางนี้ (ทั้งหมดเป็นตัวเลือก)
- แอตทริบิวต์ไม่บังคับ ตั้งค่าเป็น true เพื่อให้ระบบไม่สนใจข้อผิดพลาดในการติดตั้ง ที่เกิดจากตัวควบคุม Cgroup ที่เคอร์เนลไม่รองรับการติดตั้ง
ตัวอย่างไฟล์ cgroups.json
ตัวอย่างด้านล่างแสดงคำอธิบายสำหรับคอนโทรลเลอร์ cgroup v1 (Cgroups
) และ cgroup v2
(Cgroups2
) พร้อมเส้นทางที่เกี่ยวข้อง
{
"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"
}
]
}
}
ไฟล์ตัวอย่างนี้มี 2 ส่วน ได้แก่ Cgroups (อธิบายตัวควบคุม cgroup v1
) และ Cgroups2 (อธิบายตัวควบคุม cgroup v2) ระบบจะติดตั้งคอนโทรลเลอร์ทั้งหมดในลําดับชั้น cgroups v2 ไว้ที่ตำแหน่งเดียวกัน
ดังนั้น ส่วน Cgroups2 จึงมีแอตทริบิวต์ Path, Mode, UID และ
GID ของตัวเองเพื่ออธิบายตำแหน่งและแอตทริบิวต์สำหรับรูทของ
ลำดับชั้น แอตทริบิวต์เส้นทางสำหรับตัวควบคุมในส่วน Cgroups2 จะ
สัมพันธ์กับเส้นทางรากนั้น ใน Android 12 ขึ้นไป คุณสามารถกำหนดตัวควบคุม cgroup
ที่ระบุด้วยเส้นทางและโหมดเป็น "Optional"
โดยตั้งค่าเป็น true
ระบบจะแยกวิเคราะห์ไฟล์ cgroups.json
เป็นส่วนหนึ่งของกระบวนการเริ่มต้นในระหว่างขั้นตอนการเริ่มต้นช่วงแรก และจะติดตั้ง cgroup ในตำแหน่งที่ระบุ หากต้องการรับตำแหน่งการติดตั้ง cgroup ในภายหลัง ให้ใช้ฟังก์ชัน CgroupGetControllerPath
API
ไฟล์โปรไฟล์งาน
ไฟล์ task_profiles.json
อยู่ใน <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
ใช้เพื่ออธิบายชุดการดำเนินการที่เฉพาะเจาะจงที่จะใช้กับกระบวนการหรือ
เธรด ชุดการดำเนินการจะเชื่อมโยงกับชื่อโปรไฟล์ ซึ่งใช้ในการเรียก SetTaskProfiles
และ SetProcessProfiles
เพื่อเรียกใช้การดำเนินการของโปรไฟล์
ตัวอย่างไฟล์ 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" ]
}
}
กำหนดชื่อให้กับไฟล์ cgroup ที่เฉพาะเจาะจงเป็นรายการในรายการแอตทริบิวต์ แต่ละรายการจะมีข้อมูลต่อไปนี้
- ฟิลด์ชื่อระบุชื่อของแอตทริบิวต์
- ฟิลด์Controller อ้างอิงตัวควบคุม cgroup จาก
cgroups.json
ไฟล์ตามชื่อ - ชื่อฟิลด์ File จะระบุไฟล์ที่เฉพาะเจาะจงภายใต้ตัวควบคุมนี้
แอตทริบิวต์คือการอ้างอิงในคำจำกัดความของโปรไฟล์งาน นอกเหนือจากโปรไฟล์งาน ให้ใช้เฉพาะเมื่อเฟรมเวิร์กต้องเข้าถึงไฟล์เหล่านั้นโดยตรง และไม่สามารถเข้าถึงได้โดยใช้โปรไฟล์งาน ในกรณีอื่นๆ ทั้งหมด ให้ใช้โปรไฟล์งาน ซึ่งจะช่วยให้แยกพฤติกรรมที่จำเป็นออกจาก รายละเอียดการใช้งานได้ดียิ่งขึ้น
ส่วนโปรไฟล์มีคำจำกัดความของโปรไฟล์งานที่มีข้อมูลต่อไปนี้
- ฟิลด์ชื่อกำหนดชื่อโปรไฟล์
ส่วนการดำเนินการแสดงชุดการดำเนินการที่ทำเมื่อใช้โปรไฟล์ การดำเนินการแต่ละอย่างมีข้อมูลต่อไปนี้
- ฟิลด์ชื่อระบุการดำเนินการ
- ส่วน Params จะระบุชุดพารามิเตอร์สําหรับการดําเนินการ
การดำเนินการที่รองรับจะแสดงอยู่ในตารางต่อไปนี้
การทำงาน | พารามิเตอร์ | คำอธิบาย |
---|---|---|
SetTimerSlack |
Slack |
ความคลาดเคลื่อนของตัวจับเวลาในหน่วยนาโนวินาที |
SetAttribute |
Name |
ชื่อที่อ้างอิงแอตทริบิวต์จากส่วนแอตทริบิวต์ |
Value |
ค่าที่จะเขียนลงในไฟล์ที่แสดงโดยแอตทริบิวต์ที่มีชื่อ | |
WriteFile | FilePath | เส้นทางไปยังไฟล์ |
Value | ค่าที่จะเขียนลงในไฟล์ | |
JoinCgroup |
Controller |
ชื่อของตัวควบคุม Cgroup จาก cgroups.json |
Path |
เส้นทางกลุ่มย่อยในลำดับชั้นของตัวควบคุม cgroup |
Android 12 ขึ้นไปมีส่วน AggregateProfiles ซึ่งมีโปรไฟล์แบบรวม โดยแต่ละโปรไฟล์เป็นชื่อแทนของชุดโปรไฟล์อย่างน้อย 1 รายการ คำจำกัดความของโปรไฟล์รวมประกอบด้วยข้อมูลต่อไปนี้
- ฟิลด์ชื่อระบุชื่อของโปรไฟล์รวม
- ฟิลด์โปรไฟล์แสดงชื่อของโปรไฟล์ที่รวมอยู่ใน โปรไฟล์รวม
เมื่อใช้โปรไฟล์รวม ระบบจะใช้โปรไฟล์ทั้งหมดที่มีอยู่โดยอัตโนมัติด้วย โปรไฟล์รวมสามารถมีทั้งโปรไฟล์บุคคล หรือโปรไฟล์รวมอื่นๆ ตราบใดที่ไม่มีการเรียกซ้ำ (โปรไฟล์ที่ รวมตัวเอง)
task_profiles init language command
task_profiles
คำสั่งในภาษา Init ของ Android
พร้อมใช้งานสำหรับ Android 12 ขึ้นไปเพื่ออำนวยความสะดวก
ในการเปิดใช้งานโปรไฟล์งานสำหรับกระบวนการที่เฉพาะเจาะจง โดยจะแทนที่คำสั่ง writepid
(เลิกใช้งานใน Android 12) ที่ใช้ในการย้ายข้อมูล
กระบวนการระหว่าง Cgroup คำสั่ง task_profiles
ช่วยให้มีความยืดหยุ่นในการ
เปลี่ยนการติดตั้งใช้งานพื้นฐานโดยไม่มีผลต่อเลเยอร์บน ใน
ตัวอย่างด้านล่าง คำสั่งทั้ง 2 รายการนี้จะดำเนินการเดียวกันได้อย่างมีประสิทธิภาพ
writepid /dev/cpuctl/top-app/tasks
เลิกใช้งานใน Android 12 โดยใช้เพื่อเขียน PID ของงานปัจจุบันลงในไฟล์
/dev/cpuctl/top-app/tasks
task_profiles MaxPerformance
รวมกระบวนการปัจจุบันเข้ากับกลุ่มแอปยอดนิยมภายใต้ตัวควบคุม "cpu" (
cpuctl
) ซึ่งจะส่งผลให้มีการเขียน PID ของกระบวนการไปยังdev/cpuctl/top-app/tasks
ใช้คำสั่ง task_profiles
เสมอเพื่อย้ายข้อมูลงานในลำดับชั้นของ Cgroup ใน Android 12 ขึ้นไป โดยจะยอมรับพารามิเตอร์อย่างน้อย 1 รายการ ซึ่งแสดงถึงชื่อของโปรไฟล์ที่ระบุไว้ในไฟล์ task_profiles.json
โปรไฟล์งานต่อระดับ API
ใน Android 12 ขึ้นไป คุณสามารถแก้ไขหรือลบล้าง
คำจำกัดความในไฟล์ cgroups.json
และ task_profiles.json
เริ่มต้นได้ ไม่ว่าจะ
อิงตามการเปลี่ยนแปลงระดับ Android API หรือทำการเปลี่ยนแปลงจากพาร์ติชันของผู้ให้บริการ
หากต้องการลบล้างคำจำกัดความตามระดับ API อุปกรณ์ต้องมีไฟล์ต่อไปนี้
/system/etc/task_profiles/cgroups_<API level>.json
ใช้สำหรับ cgroup ที่เฉพาะเจาะจงกับระดับ API
/system/etc/task_profiles/task_profiles_<API level>.json
ใช้สำหรับโปรไฟล์ที่เฉพาะเจาะจงกับระดับ API
หากต้องการลบล้างคำจำกัดความจากพาร์ติชันของผู้ให้บริการ อุปกรณ์ต้องมีไฟล์ต่อไปนี้
/vendor/etc/cgroups.json
/vendor/etc/task_profiles.json
หากแอตทริบิวต์หรือคำจำกัดความของโปรไฟล์ในไฟล์เหล่านี้ใช้ชื่อเดียวกับในไฟล์เริ่มต้น คำจำกัดความของไฟล์ (ระดับ API หรือระดับผู้ให้บริการ) จะลบล้างคำจำกัดความก่อนหน้า นอกจากนี้ โปรดทราบว่าคำจำกัดความระดับผู้ให้บริการจะลบล้างคำจำกัดความระดับ API หากคำจำกัดความใหม่มีชื่อใหม่ ระบบจะแก้ไขชุดแอตทริบิวต์หรือโปรไฟล์ด้วยคำจำกัดความใหม่
ระบบ Android จะโหลดไฟล์ cgroup
และ task_profile
ตามลำดับต่อไปนี้
- ไฟล์
cgroups.json
และtask_profiles.json
เริ่มต้น - ไฟล์เฉพาะระดับ API (หากมี)
- ไฟล์พาร์ติชันของผู้ให้บริการ หากมี
การเปลี่ยนแปลง API ที่มีอยู่
Android 10 ขึ้นไปจะคงฟังก์ชัน set_cpuset_policy
,
set_sched_policy
และ get_sched_policy
ไว้โดยไม่มีการเปลี่ยนแปลง API
อย่างไรก็ตาม Android 10 ได้ย้ายฟังก์ชันเหล่านี้ไปไว้ในlibprocessgroup
ซึ่งตอนนี้มีฟังก์ชันทั้งหมดที่เกี่ยวข้องกับ cgroup
แม้ว่าส่วนหัว cutils/sched_policy.h
จะยังคงมีอยู่ แต่เพื่อไม่ให้โค้ดที่มีอยู่ใช้งานไม่ได้ โปรดตรวจสอบว่าโค้ดใหม่มีส่วนหัว processgroup/sched_policy.h
ใหม่แทน
โมดูลที่ใช้ฟังก์ชันเหล่านี้ควรเพิ่มการอ้างอิงใน
libprocessgroup
ลงในไฟล์ Makefile หากโมดูลไม่ได้ใช้ฟังก์ชันการทำงานอื่นๆ ของ libcutils
ให้นำการอ้างอิงไลบรารี libcutils
ออกจาก Makefile
API โปรไฟล์งาน
API ส่วนตัวใน processgroup/processgroup.h
มีการกำหนดไว้ในตารางดังนี้
ประเภท | API และคำจำกัดความ |
---|---|
bool |
SetTaskProfiles(int tid, const std::vector
ใช้โปรไฟล์งานที่ระบุใน profiles กับเธรดที่ระบุโดย
รหัสเธรด (tid) โดยใช้พารามิเตอร์ tid |
bool |
SetProcessProfiles(uid_t uid, pid_t pid, const std::vector
ใช้โปรไฟล์งานที่ระบุใน profiles กับกระบวนการที่ระบุ
โดยผู้ใช้และรหัสกระบวนการโดยใช้พารามิเตอร์ uid และ pid |
bool |
CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)
แสดงผลว่ามีตัวควบคุม cgroup ที่ระบุโดย cgroup_name หรือไม่
หาก true ให้ตั้งค่าตัวแปร path เป็นรูทของ cgroup นั้น |
bool |
CgroupGetAttributePath(const std::string& attr_name, std::string* path)
แสดงผลว่ามีแอตทริบิวต์โปรไฟล์ที่ระบุโดย attr_name หรือไม่ หากมี
true ให้ตั้งค่าตัวแปร path เป็นเส้นทางของไฟล์ที่เชื่อมโยงกับ
แอตทริบิวต์โปรไฟล์นั้น |
bool |
CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)
แสดงผลว่ามีแอตทริบิวต์โปรไฟล์ที่ระบุโดย attr_name หรือไม่ หากมี
true ให้ตั้งค่าตัวแปร path เป็นเส้นทางของไฟล์ที่เชื่อมโยงกับ
แอตทริบิวต์โปรไฟล์นั้น และตั้งค่าเป็นเธรดที่ระบุโดยรหัสเธรดโดยใช้
พารามิเตอร์ tid |
bool |
UsePerAppMemcg()
แสดงว่าระบบได้รับการกำหนดค่าให้ใช้ cgroup หน่วยความจำต่อแอปหรือไม่ |