Android 10 และสูงกว่าใช้เลเยอร์นามธรรมของกลุ่มควบคุม (cgroup) พร้อมโปรไฟล์งาน ซึ่งนักพัฒนาสามารถใช้เพื่ออธิบายชุด (หรือชุด) ของข้อจำกัดที่จะนำไปใช้กับเธรดหรือกระบวนการ จากนั้นระบบจะปฏิบัติตามการดำเนินการที่กำหนดไว้ของโปรไฟล์งานเพื่อเลือกกลุ่ม cgroup ที่เหมาะสมอย่างน้อย 1 กลุ่ม ซึ่งจะใช้ข้อจำกัดต่างๆ และการเปลี่ยนแปลงชุดคุณลักษณะ cgroup พื้นฐานสามารถทำได้โดยไม่กระทบต่อชั้นซอฟต์แวร์ที่สูงกว่า
เกี่ยวกับซีกรุ๊ป
Cgroups จัดเตรียมกลไกสำหรับการรวบรวมและแบ่งพาร์ติชันชุดงาน (ซึ่งประกอบด้วยกระบวนการ เธรด และรายการย่อยทั้งหมดในอนาคต) ออกเป็นกลุ่มตามลำดับชั้นที่มีพฤติกรรมเฉพาะทาง Android ใช้ cgroups เพื่อควบคุมและพิจารณาทรัพยากรระบบ เช่น CPU และการใช้งานและการจัดสรรหน่วยความจำ พร้อมรองรับเคอร์เนล Linux cgroups v1 และ cgroups v2
Android 9 และต่ำกว่า
ใน Android 9 และต่ำกว่า สคริปต์การเริ่มต้น init.rc
มีชุดของกลุ่ม cgroup ที่พร้อมใช้งาน จุดเมานท์ และเวอร์ชันต่างๆ แม้ว่าสิ่งเหล่านี้สามารถเปลี่ยนแปลงได้ แต่เฟรมเวิร์ก 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
แบบเดิม
ไฟล์คำอธิบาย Cgroups
Cgroups ได้รับการอธิบายไว้ในไฟล์ cgroups.json
ที่อยู่ภายใต้ <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
ตัวควบคุมแต่ละตัวมีการอธิบายไว้ในส่วนย่อยและต้องมีคุณสมบัติขั้นต่ำดังต่อไปนี้:
- ชื่อ กำหนดโดยฟิลด์ ตัวควบคุม
- เส้นทางการเมานต์ กำหนดโดยฟิลด์ เส้นทาง
- Mode , UID (ID ผู้ใช้) และ GID (ID กลุ่ม) ที่อธิบายเจ้าของและโหมดการเข้าถึงสำหรับไฟล์ภายใต้พาธนี้ (ไม่บังคับทั้งหมด)
- แอตทริบิวต์ ทางเลือก ตั้งค่า เป็นจริง เพื่อให้ระบบละเว้นข้อผิดพลาดในการติดตั้งที่เกิดจากตัวควบคุม 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
ตามชื่อ - ฟิลด์ ไฟล์ตั้งชื่อไฟล์เฉพาะภายใต้คอนโทรลเลอร์นี้
แอ็ตทริบิวต์ คือการอ้างอิงในคำจำกัดความโปรไฟล์งาน ภายนอกโปรไฟล์งาน ให้ใช้ เฉพาะ เมื่อเฟรมเวิร์กต้องการการเข้าถึงไฟล์เหล่านั้นโดยตรง และไม่สามารถแยกการเข้าถึงโดยใช้โปรไฟล์งานได้ ในกรณีอื่นๆ ทั้งหมด ให้ใช้โปรไฟล์งาน โดยให้การแยกส่วนที่ดีขึ้นระหว่างพฤติกรรมที่ต้องการและรายละเอียดการใช้งาน
ส่วน โปรไฟล์ ประกอบด้วยคำจำกัดความของโปรไฟล์งานดังต่อไปนี้:
- ฟิลด์ ชื่อ กำหนดชื่อโปรไฟล์
ส่วน การดำเนินการ จะแสดงชุดการดำเนินการที่ดำเนินการเมื่อมีการใช้โปรไฟล์ แต่ละการกระทำมีดังต่อไปนี้:
- ฟิลด์ ชื่อ ระบุการดำเนินการ
- ส่วน Params ระบุชุดของพารามิเตอร์สำหรับการดำเนินการ
การดำเนินการที่รองรับแสดงอยู่ในตาราง:
การกระทำ | พารามิเตอร์ | คำอธิบาย |
---|---|---|
SetTimerSlack | Slack | ตัวจับเวลาหย่อนใน ns |
SetAttribute | Name | ชื่อที่อ้างอิงถึงคุณลักษณะจากส่วน คุณลักษณะ | Value | ค่าที่จะเขียนลงในไฟล์ที่แสดงโดยแอตทริบิวต์ที่มีชื่อ |
WriteFile | FilePath | เส้นทางไปยังไฟล์ | Value | ค่าที่จะเขียนลงในไฟล์ |
JoinCgroup | Controller | ชื่อของตัวควบคุม cgroup จาก cgroups.json |
Path | เส้นทางกลุ่มย่อยในลำดับชั้นของตัวควบคุม cgroup |
Android 12 ขึ้นไปมีส่วน AggregateProfiles ที่มีโปรไฟล์รวม ซึ่งแต่ละโปรไฟล์เป็นชื่อแทนสำหรับชุดโปรไฟล์ตั้งแต่ 1 โปรไฟล์ขึ้นไป คำจำกัดความโปรไฟล์รวมประกอบด้วยสิ่งต่อไปนี้:
- ฟิลด์ ชื่อ ระบุชื่อของโปรไฟล์รวม
- ฟิลด์ โปรไฟล์ แสดงรายการชื่อของโปรไฟล์ที่รวมอยู่ในโปรไฟล์รวม
เมื่อใช้โปรไฟล์รวม โปรไฟล์ที่มีทั้งหมดจะถูกใช้โดยอัตโนมัติด้วย โปรไฟล์รวมสามารถมีทั้งโปรไฟล์ส่วนบุคคลหรือโปรไฟล์รวมอื่นๆ ตราบใดที่ไม่มีการเรียกซ้ำ (โปรไฟล์ที่รวมตัวเอง)
task_profiles คำสั่งภาษาเริ่มต้น
คำสั่ง 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
API โปรไฟล์งาน
API ส่วนตัวใน processgroup/processgroup.h
ถูกกำหนดไว้ในตาราง:
พิมพ์ | API และคำจำกัดความ |
---|---|
bool | SetTaskProfiles(int tid, const std::vector & profiles) SetTaskProfiles(int tid, const std::vector & profiles) ใช้โปรไฟล์งานที่ระบุใน profiles กับเธรดที่ระบุโดย ID เธรด (tid) โดยใช้พารามิเตอร์ tid |
bool | SetProcessProfiles(uid_t uid, pid_t pid, const std::vector & profiles) SetProcessProfiles(uid_t uid, pid_t pid, const std::vector & profiles) ใช้โปรไฟล์งานที่ระบุใน profiles กับกระบวนการที่ระบุโดยผู้ใช้และ ID กระบวนการโดยใช้พารามิเตอร์ 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 เป็นพาธของไฟล์ที่เกี่ยวข้องกับแอ็ตทริบิวต์โปรไฟล์นั้น และตั้งค่าเป็นเธรดที่ระบุโดย ID เธรดโดยใช้พารามิเตอร์ tid |
bool | UsePerAppMemcg() ส่งคืนว่าระบบได้รับการกำหนดค่าให้ใช้ cgroups หน่วยความจำต่อแอปหรือไม่ |