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