-
Notifications
You must be signed in to change notification settings - Fork 4
Common power-libperfmgr bringup #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: fourteen-v3
Are you sure you want to change the base?
Conversation
Based on implementation from hardware/google/pixel as of commit 0338a0e. Change-Id: I3df57bd3e8298141272add55c911fb5eece9aebe
Bug: 147840817 Test: boot and check power hint Change-Id: I9c0c98e76ef4b5f4756f63ed5122efc366737869
Bug: 151896829 Test: boot flame Change-Id: Ie951008cabe2a5680fbc546a21bdc9a428864ef9
Bug: 147840817 Test: boot Change-Id: Ic1d6e04109683b999bb99484930e95dc9813fc59
Bug: 152811907 Test: Build Change-Id: I6848e929d8a26b540fcee9145376b896c3cd9799
Because perfmgr is a vendor process, it cannot adjust system priority directly. Bug: 162791243 Test: build and using emul temp/running burn8 to verify it Change-Id: I55e49cb7d0b2d4c0e42dff8398b5d42c6546cafa
Bug: 162791243 Bug: 72471476 Test: build and using emul temp/running burn8 to verify it Change-Id: I5ca475be8b73b940e4858634595a7918ae92f6ef
Change-Id: Iac0e65a16f660583d3400a35622113d35d8d1d27
To workaround b/141025174, adding support for devices without display idle signals. Also added a property to override idle display function. Besides the idle signal support, this CL also makes touch boost duration tunable through several new vendor properties. It also named display idle monitor thread and cleans out the obsolete HIDL Power HAL implementation. Bug: 168080943 Bug: 169065024 Bug: 171494137 Test: Boot and trace Change-Id: I76067d10958654d539624ec4cac8f346103e67bc
Test: Build Bug: 169065024 Signed-off-by: Wei Wang <[email protected]> Change-Id: I3cef3aff4bb2394571a3de13e535283722c308ed
Test: build Bug: 173222103 Signed-off-by: Wei Wang <[email protected]> Change-Id: I14e7e0aa349e446f6889cbfc9a914f5314438e6b
Bug: 150578172 Test: m Change-Id: I4a9bf218b92252403e9ebbe8f89b10ee1899283f
Adapted from PoC from ag/13100800
Added more ATRACE for further tuning and debug
Test: APPPID=$(adb shell pidof com.prefabulated.touchlatency); watch -n
1 adb shell grep uclamp /proc/${APPPID}/sched
Test: atest VtsHalPowerTargetTest
Bug: 177492680
Change-Id: I6bfd61b21dc1cde04f6ba9ae8d3533cd263ad814
Signed-off-by: Wei Wang <[email protected]>
Add bunch of TODO for team as well. Test: build Bug: 177492680 Bug: 185368789 Signed-off-by: Wei Wang <[email protected]> Change-Id: Ic1d5ecea10a60b23343866cd62519fda37bd6ec5
The patch includes: 1. Move from folder adpf to aidl. 2. Add PowerSessionManager class to maintain hint status. And PowerHintMointor looper thread for monitoring or updating PowerHintSession status. 3. Use PID algorithm to replace the step-wise alogrithm for cpu resource control. Test: build, boot to home, trace analysis Bug: 177493042 Change-Id: Ib7d3f414225b18954350341ca22b7be87a6202e7
Fixes: ag/14313466 Bug: 177493042 Bug: 191163855 Test: Build Change-Id: I94812997a8214b77a2e1d0bcf90ef62205c5adf6 Signed-off-by: Wei Wang <[email protected]>
Cache active state and reduce log spam Add value tracing into libperfmgr Use adaptive stale timeout based on rate limit Bug: 191331719 Bug: 191296994 Bug: 177493042 Test: boot Signed-off-by: Wei Wang <[email protected]> Change-Id: I1c1484c9277209bf68bd287ceae83e2b37684c62
Also change default window setting to 0 Bug: 191409203 Test: Build Signed-off-by: Wei Wang <[email protected]> Change-Id: Ieadf50a64e795d9942373c411189adf9daaee779
clean up ADPF trace points and use vendor.powerhal.adpf.uclamp.boost_cap instead of vendor.powerhal.adpf.uclamp.cap_ratio. Bug: 191551452 Test: build Change-Id: I457710b1bd9a7adbb55749d7bb915c736dde2751
Bug: 191480755 Test: Build Signed-off-by: Wei Wang <[email protected]> Change-Id: Id559796ee4a423410148b8c2df0524909658af82
When seesion is created, set uclamp to boost CPU for top-app. Bug: 192143316 Test: Build and run UiBenchSlowNestedRecyclerViewInitialFlingMicrobenchmark test Change-Id: I748037019fae439ab1863a5ed21aa98b9d26e0dc
"GPU completion" task inherits a high uclamp value from RenderThread.
But it's not in the ADPF thread list, so it remains a high uclamp value.
Use SetTaskProfiles("ResetUclampGrp") and
SetTaskProfiles("NoResetUclampGrp") to manage the uclamp_fork_reset for
tasks.
Bug: 191973176
Bug: 192149875
Test: vendor/google_testing/pts/tests/common/utils/perf/run_pts/jank_test.sh
Test: adb shell cat /proc/vendor_sched/dump_task
Change-Id: I6aed171e88c0a6db5f762e7c791344bb3f4b7a90
To get rid of error logs, avoid to call close() twice. 07-29 17:20:35.341 E powerhal-libperfmgr: Unexpected Error! Failed to look up tid:2585 in TidRefCountMap 07-29 17:20:35.341 E powerhal-libperfmgr: Unexpected Error! Failed to look up tid:2586 in TidRefCountMap 07-29 17:20:35.341 E powerhal-libperfmgr: Unexpected Error! Failed to look up tid:2031 in TidRefCountMap 07-29 17:20:35.341 E powerhal-libperfmgr: Unexpected Error! Failed to look up tid:2585 in TidRefCountMap Bug: 194775170 Test: build and check log. Change-Id: I91adf907b837382f68935b9054e19465a499049c
Tuning the PID control loop as the below: ILowLimit: -512 -> -120 kPOver: 2->5 kPunder: 2->3 kDOver: 1->5 kDUnder: 0->0 Bug: 193165816 Test: cuj/youtuble, cuj/facebook, PtsUiBench Change-Id: Icc1a9a8d04004f60e47cabb7c4131ea67585be53
Test: systrace Bug: 199776250 Change-Id: I9bb4d5a50faa93e7bc638ef723bdc2662fb63b24
1. set uclamp.min high to 384 (from 512)
2. set uclamp.min low to 2 (from 0)
3. set kPo to 2 (from 5)
4. set kPu to 1 (from 3)
5. instead of the previous boost value, use I Error-Integral as the base
of boost value.
6. add more traces (wakeup, overtime)
Bug: 198708191
Bug: 197586898
Bug: 197540375
Test: build and check trace
adb shell perfetto -o \
/data/misc/perfetto-traces/trace_file.perfetto-trace -t 20s sched \
freq idle am wm gfx view power hal
Change-Id: I35484322a84c2ab19f3024cf6634c1818ba570b0
Bug: 196192645 Test: Manual Change-Id: Ibdbb8f47a16032ce3249aa667fa0c11e7869748f
Add a bool property `vendor.powerhal.config.debug`.
Power HAL would use `/data/vendor/etc/powerhint.json` when vendor.powerhal.config.debug = true.
Bug: 218872105
Bug: 206061061
Test: adb wait-for-device root; adb shell mkdir -p /data/vendor/etc/;
adb push powerhint_mod.json /data/vendor/etc/powerhint.json
Test: adb shell setprop vendor.powerhal.config.debug true && \
adb shell getprop vendor.powerhal.config.debug && \
adb shell stop vendor.power-hal-aidl && \
adb shell start vendor.power-hal-aidl && adb shell stop && adb shell start
Test: adb pull /data/local.prop ; vim local.prop
+ vendor.powerhal.config.debug=true
Test: adb wait-for-device root && adb shell perfetto -o \
/data/misc/perfetto-traces/trace_file.perfetto-trace -t 20s sched freq \
idle am wm gfx view power hal && \
adb pull /data/misc/perfetto-traces/trace_file.perfetto-trace trace_profile_debug.pftrace
Change-Id: Ibaf5df280b989a8268efce1e3ab9a3f1e5510800
An init trigger would restart powerhal as early as the property was loaded and it is hopefully early than any clients would try to connect. Also remove the obsolete restart hook with audio. Bug: 218872105 Test: boot Signed-off-by: Wei Wang <[email protected]> Change-Id: Ib55897f65709a963016b729f213718aae5af8e8c
1. Clean all messages before add new. 2. Insteading of using `this`, use the unique mStaleHandler sp so Looper can hold the sp to keep the instance alive until the last message done. Test: Manual Test Bug: 219965773 Change-Id: Ic039146f0b966c1f27d86b121d4b72b75ff360e5
For DISPLAY_UPDATE_IMMINENT wakeup signal, non-stale session's timer should be also extended. This resolves the performance issue caused those sessions to go stale prematurely. Bug: 241621485 Test: Build Signed-off-by: Wei Wang <[email protected]> Change-Id: I06330e064060248bb556ae35e0cb8fd302cef231
…ble boost. Optimize boost: A more efficient way is to trigger the wakeup boost through mTidSessionListMap, so the time complexity reduce from O(n^3) to O(n^2). The original code path: PSM:wakeSessions() contains a loop that is O(n), inside the loop, it calls to PHS::wakeup() which call to PSM::setUclampMinLocked(), and PSM::setUclampMinLocked() contains two loops O(n^2) The new code path: PSM::wakeSessions() directly checks all the ADPF tasks O(n) and get the wakeup boost value O(n), then directly set the uclamp.min The time complexity lower to O(n^2). Fix unstable boost: The original flow is to find max boost and wake it up from stale state one by one. But the previous woken ones would not be counted when the later ones finding their max boost value. The new flow boost all the tasks first, then wake up all those sessions. Bug: 235510337 Test: Manually playing UIBench -> Transitions -> ActivityTransition Change-Id: I995673b74401e198eb72188134ba1ebc134f971c
The main problem is the timer thread could be woken after the session was destroyed. We did have a closed flag which was set in destructor and the flag would be checked before handleMessage accessing the session instance. To fix the problem, the operations of flag checking and session instance accessing should be guarded by the lock. Bug: 236674672 Test: manual test Change-Id: I49a18efbc135b1bc070b101038a8a0bcc6e19fec (cherry picked from commit 5c75978f530b27bd976d8695ed79acd336c24776) Merged-In: I49a18efbc135b1bc070b101038a8a0bcc6e19fec
Send a hint only when the system can support the hint. Bug: 243025173 Test: PtsUiBench & CUJ Change-Id: If56d0c22f8dd61f5fe27ba79f08f2963269abe41 Merged-In: If56d0c22f8dd61f5fe27ba79f08f2963269abe41
To send ADPF_FIRST_FRAME hint when reportWorkDurations was called first time after stale state. Bug: 243025173 Test: PtsUiBench & CUJ Change-Id: I4377b1f549646bcf44bdf26b2657b7bc0646f9a4 Merged-In: I4377b1f549646bcf44bdf26b2657b7bc0646f9a4
The ndk_platform backend will soon be deprecated because the ndk backend can serve the same purpose. This is to eliminate the confusion about having two variants (ndk and ndk_platform) for the same ndk backend. Bug: 161456198 Test: m Change-Id: I14a1c57bd06f1f2aa52491f779c7030d4de03547
… ADPF Bug: 201769701 Test: atest android.gamemanager.cts.GameManagerTest Change-Id: I268ca9cc8e2f212bdb9c8bb1c890e7a845170ec6
Bug: 256515601 Test: build Change-Id: I9b63c6ee3decaa4c70f38bcc66a0e9e1de464ad6
Bug: 256515601 Test: build Change-Id: Ia7f80c838961b837733c457b189f16c6433cf3c3
Reset traced hint value to -1 on reportActualWorkDuration or stale timeout, and rewrite existing tracing for readability. Bug: b/243973548 Test: manual Change-Id: I135ec5f8971a9902d880e4089b0df746f5b917e2
…anager Currently, all sessions get boosted any time DISPLAY_UPDATE_IMMINENT is sent from SurfaceFlinger which can lead to large, unnecessary boosts. This patch aims to change that by removing the wakeup behavior, relying instead on sessions to boost themselves with new load change hints. * Remove wakeup() from PowerHintSession * Remove wakeSessions from PowerSessionManager * Remove related timers and message handlers * Remove DISPLAY_UPDATE_IMMINENT behavior entirely Test: manual Bug: b/260136431 Change-Id: I4610edfefe8fcbef7d4cdbf5768830a9392a54f7
Have pixel PowerHintSessions implement the new sendHint API to provide load change hints, allowing hint sessions to rapidly wake up and respond to sudden changes in workload. Bug: b/243973548 Test: manual Change-Id: Ic10a3cee2b88f2bbbf6c74dd1bbad45859145192
…ng tracing Reset traced hint value to -1 on reportActualWorkDuration or stale timeout, and rewrite existing tracing for readability. Bug: b/243973548 Test: manual Original-Change-Id: I135ec5f8971a9902d880e4089b0df746f5b917e2 Change-Id: I9c622ca8d1fdada5a0cda253ebdbfd42f170d184
…ange hint Bug: b/243973548 Test: manual Change-Id: I101e7d9b9d5e6f74c3f3000508314173bed14c9c
Implement IPowerHintSession.setThreads, when threads are updated, remove all previous threads and readd new threads, set the boost to initial state. Minor: Update IPower version to 4. Bug: b/244216750 Bug: b/257217984 Test: manual Change-Id: I29e2574d3a107a3e75bf27a4528635e3eedc2d14
Give the first frame after a load change hint an extra boost for CPU_LOAD_UP and CPU_LOAD_RESET, as it tends to be much more expensive than the subsequent frames. Bug: b/243973548 Test: manual Change-Id: I78942beefeb836862fb65f8fe1a036dd26a44937
Currently, load hint signals boost the first frame but rely on frames reporting an actual duration to end that boost. This change adds a secondary timer to provide a maximum boost time based on the target, in case the session fails to report an actual duration or gets rate limited. This patch also refactors the existing timer into a generic superclass to make sharing timer logic easier. Bug: 261130508 Test: manual Change-Id: Icc7fbaed0cb764b6960a8f92a2b6505c7a8583dc
Current reset hint is too aggressive to turn off and uses arbitrary scaling. This patch seeks to fix existing issues by changing how the reset hint timeout is calculated. Bug: 266266524 Bug: 266259814 Test: manual Change-Id: Ic458ccdd0efeea36ce273681f4ff842d03f9ad7e
Currently the boost timer resets the stale timer when it turns off. That's less than ideal, but this should fix it. This also adds code to prevent multiple sequential boosts from re-using uclamp.min values when calculating what to return to once the boost ends Bug: 267385642 Bug: 267391322 Test: manual Change-Id: I70d835f4add242c10788aa893fb2f49774e1a538
Increasingly, cpu_load_up exists as a tool to boost stray expensive frames rather than to increase the PID setpoint, so this change reflects that and seeks to prevent power regressions in its use towards this goal Bug: 261130508 Test: manual Change-Id: I6608f92decbdfc59d92b4e5716a75b323c1d2c3e
mTidSessionListMap alone can be used to check the ref count. Bug: b/268744922 Test: n/a Change-Id: Ic7a3aa32560790683e402253e9e04eadb288e1f7
Set the profile on resume/pause Bug: 245675204 Bug: 275687673 Test: adb shell dumpsys android.hardware.power.IPower/default Change-Id: Icadf526a2f262e77d7adb2184f61b3ccba44c601
Replace current init behavior with a reset hint. This makes sense, because creating a session is implicitly a "load reset" plus HWUI may not always send a reset hint after its background refactor. This will also reduce first-frame boost latency for new sessions. Bug: 279505058 Test: manual Change-Id: I5bdeedecbd4e0afb7d777be332e5dd9fb386e1ac
Give the first frame minimum mif freq to avoid the situation that mif at lower level but memlat can't reflect the loading in time. Bug: 259275437 Bug: 263383561 Test: manual Original-Change-Id: I1dbcc23fa4a7bc2e3daf05b7cc0489a1ac5953d5 Change-Id: I2f34ba6111027832cf0e544ebc288116855c47cb Signed-off-by: Luke Chang <[email protected]>
Send a hint only when the system can support the hint. Bug: 243025173 Test: PtsUiBench & CUJ Original-Change-Id: If56d0c22f8dd61f5fe27ba79f08f2963269abe41 Change-Id: I2c190ac357aa8c5b5da52e3e1566f4f62c388ba6
… update If thread is detected as dead while setting the uclamp min, it currently sends warning log. This caused log spamming issue. Change it to verbose log first, then consider long term solution in master branch. Bug: 296159697 Test: Manual Change-Id: Ia8ea632be75a431ce0f9faa4c3792635f540be16
Bug: 296159697 Test: Manual Change-Id: Idb74d12fd0d1028514382a4e09116b506b5ec176
* Some devices may want to implement custom hooks Change-Id: Icb2d66471ec649a69b1e69849fd86282775052cb
WalkthroughThe changes introduce a comprehensive power management framework in the LineageOS Android project. New classes and configurations enhance the hardware abstraction layer (HAL) for power services, allowing for dynamic performance tuning based on user interaction and system states. The structure facilitates better management of power modes, hints, and sessions, optimizing resource usage while ensuring responsiveness and efficiency in device performance. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant InteractionHandler
participant Power
participant PowerSessionManager
participant HintManager
User->>InteractionHandler: Request performance lock
InteractionHandler->>Power: Acquire lock
Power->>HintManager: Apply performance hint
PowerSessionManager->>Power: Update session state
Note right of Power: Dynamic adjustments based on user interactions
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 30
Outside diff range, codebase verification and nitpick comments (9)
power-libperfmgr/aidl/PowerModeExtension.cpp (1)
17-17: Include guard or pragma once.Consider adding an include guard or
#pragma onceto prevent potential multiple inclusion issues.#pragma oncepower-libperfmgr/aidl/service.cpp (1)
17-17: Consider using a more descriptive log tag.The log tag
powerhal-libperfmgris descriptive but could be more specific to the functionality.power-libperfmgr/aidl/PowerExt.cpp (1)
17-17: Consider using a more descriptive log tag.The log tag
android.hardware.power-service.lineage.ext-libperfmgris descriptive but could be more specific to the functionality.power-libperfmgr/aidl/PowerSessionManager.h (5)
Line range hint
116-120:
Add error handling for the session parameter.Consider adding error handling to check if the session parameter is valid before using it.
if (!session) { ALOGW("PowerSessionManager::removePowerSession: session is null"); return; }
Line range hint
154-157:
Add error handling for the session parameter.Consider adding error handling to check if the session parameter is valid before using it.
if (!session) { ALOGW("PowerSessionManager::setUclampMin: session is null"); return; }
Line range hint
172-189:
Simplify the return type.Consider returning a boolean value directly instead of using
std::optional<bool>.bool PowerSessionManager::isAnyAppSessionActive() { std::lock_guard<std::mutex> guard(mLock); for (PowerHintSession *s : mSessions) { if (s->isActive() && !s->isTimeout() && s->isAppSession()) { return true; } } return false; }
Line range hint
191-201:
Add logging for debugging purposes.Consider adding logging to help debug the message handling process.
void PowerSessionManager::handleMessage(const Message &message) { ALOGV("PowerSessionManager::handleMessage: received message"); auto active = isAnyAppSessionActive(); if (!active.has_value()) { return; } if (active.value()) { disableSystemTopAppBoost(); } else { enableSystemTopAppBoost(); } }
Line range hint
203-223:
Add error handling for the file descriptor.Consider adding error handling to check if the file descriptor is valid before using it.
if (fd < 0) { ALOGE("PowerSessionManager::dumpToFd: invalid file descriptor"); return; }power-libperfmgr/aidl/InteractionHandler.cpp (1)
145-191: Consider adding more detailed logging.The
Acquirefunction performs several checks and operations. Adding more detailed logging can help with debugging and understanding the flow of execution.void InteractionHandler::Acquire(int32_t duration) { ATRACE_CALL(); std::lock_guard<std::mutex> lk(mLock); int inputDuration = duration + kDurationOffsetMs; int finalDuration; if (inputDuration > kMaxDurationMs) finalDuration = kMaxDurationMs; else if (inputDuration > kMinDurationMs) finalDuration = inputDuration; else finalDuration = kMinDurationMs; ALOGV("%s: input: %d, offset: %d, final duration: %d", __func__, duration, kDurationOffsetMs, finalDuration); // Fallback to do boost directly // 1) override property is set OR // 2) InteractionHandler not initialized if (!kDisplayIdleSupport || mState == INTERACTION_STATE_UNINITIALIZED) { HintManager::GetInstance()->DoHint("INTERACTION", std::chrono::milliseconds(finalDuration)); return; } struct timespec cur_timespec; clock_gettime(CLOCK_MONOTONIC, &cur_timespec); if (mState != INTERACTION_STATE_IDLE && finalDuration <= mDurationMs) { size_t elapsed_time = CalcTimespecDiffMs(mLastTimespec, cur_timespec); // don't hint if previous hint's duration covers this hint's duration if (elapsed_time <= (mDurationMs - finalDuration)) { ALOGV("%s: Previous duration (%d) cover this (%d) elapsed: %lld", __func__, static_cast<int>(mDurationMs), static_cast<int>(finalDuration), static_cast<long long>(elapsed_time)); return; } } mLastTimespec = cur_timespec; mDurationMs = finalDuration; ALOGV("%s: input: %d final duration: %d", __func__, duration, finalDuration); if (mState == INTERACTION_STATE_WAITING) AbortWaitLocked(); else if (mState == INTERACTION_STATE_IDLE) PerfLock(); mState = INTERACTION_STATE_INTERACTION; mCond.notify_one(); }
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (15)
- power-libperfmgr/Android.bp (1 hunks)
- power-libperfmgr/aidl/InteractionHandler.cpp (1 hunks)
- power-libperfmgr/aidl/InteractionHandler.h (1 hunks)
- power-libperfmgr/aidl/Power.cpp (1 hunks)
- power-libperfmgr/aidl/Power.h (1 hunks)
- power-libperfmgr/aidl/PowerExt.cpp (1 hunks)
- power-libperfmgr/aidl/PowerExt.h (1 hunks)
- power-libperfmgr/aidl/PowerHintSession.cpp (1 hunks)
- power-libperfmgr/aidl/PowerHintSession.h (1 hunks)
- power-libperfmgr/aidl/PowerModeExtension.cpp (1 hunks)
- power-libperfmgr/aidl/PowerSessionManager.cpp (1 hunks)
- power-libperfmgr/aidl/PowerSessionManager.h (1 hunks)
- power-libperfmgr/aidl/android.hardware.power-service.lineage-libperfmgr.rc (1 hunks)
- power-libperfmgr/aidl/android.hardware.power-service.lineage.xml (1 hunks)
- power-libperfmgr/aidl/service.cpp (1 hunks)
Additional comments not posted (45)
power-libperfmgr/aidl/android.hardware.power-service.lineage.xml (1)
1-7: Ensure XML manifest correctness.The XML manifest appears to be correctly formatted and specifies the HAL for
android.hardware.powerwith version 4. Ensure this aligns with the rest of the project requirements and configurations.power-libperfmgr/aidl/PowerModeExtension.cpp (2)
1-15: Ensure license compliance.The license header is correctly included and follows the Apache License, Version 2.0. Ensure compliance with the license terms.
19-45: Namespace and function implementations look good.The namespace structure is well-defined, and the functions
isDeviceSpecificModeSupportedandsetDeviceSpecificModeare correctly stubbed out. Ensure these functions are correctly integrated and implemented as needed.power-libperfmgr/aidl/android.hardware.power-service.lineage-libperfmgr.rc (6)
1-5: Service definition looks good.The service definition for
vendor.power-hal-aidlis correctly specified with appropriate class, user, group, and priority settings.
7-9: Ensure service starts correctly onlate-fs.The
on late-fstrigger to start the service is correctly specified. Ensure this aligns with the overall system initialization sequence.
10-16: Handle framework restart correctly.The script correctly handles the restart of the powerHAL service when the framework restarts. Ensure this logic is tested thoroughly.
17-25: Ensure property handling fordalvik.vmproperties.The script handles
dalvik.vmproperties correctly. Ensure these properties are set and restored as intended.
26-29: Debug property handling looks good.The script correctly handles the restart of the powerHAL service when debug properties are set. Ensure this logic is tested thoroughly.
30-32: Persisted debug property handling looks good.The script correctly handles persisted debug properties. Ensure this logic is tested thoroughly.
power-libperfmgr/Android.bp (3)
7-12: Namespaces and imports look good.The
soong_namespacesection correctly specifies the namespaces and imports.
14-47: Binary configuration looks good.The
cc_binarysection correctly specifies the binary configuration, including dependencies, source files, and other settings.
49-58: Static library configuration looks good.The
cc_library_staticsection correctly specifies the static library configuration, including dependencies and source files.power-libperfmgr/aidl/PowerExt.h (3)
1-25: File header and includes look good.The file header contains correct licensing information, and the necessary headers are included.
26-39: Class definition and public methods look good.The class
PowerExtextendsBnPowerExtand provides methods for setting and checking power modes and boosts. The methods are correctly defined.
41-42: Private section is correctly defined.The private section of the class
PowerExtis currently empty but correctly defined.power-libperfmgr/aidl/InteractionHandler.h (4)
1-24: File header and includes look good.The file header contains correct licensing information, and the necessary headers are included.
32-37: Enum definition looks good.The enum
InteractionStatecorrectly defines various states for interaction management.
39-46: Class definition and public methods look good.The class
InteractionHandlerprovides methods for initializing, exiting, acquiring, and releasing interactions. The methods are correctly defined.
48-64: Private section looks good.The private section of the class
InteractionHandlercontains private methods and member variables for managing interactions. The methods and variables are correctly defined.power-libperfmgr/aidl/Power.h (3)
1-15: Ensure compliance with the Apache License.The file includes the Apache License header, which is good practice.
19-25: Ensure all necessary headers are included.The file includes several headers, which seem appropriate for the functionality.
38-55: ClassPowerimplementation looks good.The class
PowerextendsBnPowerand implements several methods related to power management.power-libperfmgr/aidl/service.cpp (3)
1-15: Ensure compliance with the Apache License.The file includes the Apache License header, which is good practice.
19-31: Ensure all necessary headers are included.The file includes several headers, which seem appropriate for the functionality.
40-83: Main function implementation looks good.The main function initializes the power HAL service, registers the service, and starts the necessary components.
power-libperfmgr/aidl/PowerExt.cpp (3)
1-15: Ensure compliance with the Apache License.The file includes the Apache License header, which is good practice.
19-31: Ensure all necessary headers are included.The file includes several headers, which seem appropriate for the functionality.
33-87: ClassPowerExtimplementation looks good.The class
PowerExtextends functionality for power management and implements several methods.power-libperfmgr/aidl/PowerSessionManager.h (2)
100-104: Clarify the purpose of the method.The method logs the boost and duration but does not perform any action. Clarify if this is intentional or if additional logic is required.
106-108: LGTM!The method is simple and correctly implemented.
power-libperfmgr/aidl/PowerHintSession.h (1)
84-84: LGTM!The method is simple and correctly implemented.
power-libperfmgr/aidl/PowerSessionManager.cpp (2)
100-104: Clarify the purpose of the method.The method logs the boost and duration but does not perform any action. Clarify if this is intentional or if additional logic is required.
106-108: LGTM!The method is simple and correctly implemented.
power-libperfmgr/aidl/InteractionHandler.cpp (3)
49-50: Ensure the property key is correct.The property key
vendor.powerhal.disp.idle_supportis used to determine display idle support. Verify that this key is correct and exists in the system properties.
51-52: Confirm the validity of file paths.The file paths
/sys/class/drm/card0/device/idle_stateand/sys/class/graphics/fb0/idle_stateare used to check the display idle state. Ensure these paths are correct and accessible on the target devices.
53-60: Verify property keys and default values.The property keys
vendor.powerhal.disp.idle_wait,vendor.powerhal.interaction.min,vendor.powerhal.interaction.max, andvendor.powerhal.interaction.offsetare used to configure various parameters. Ensure these keys are correct and the default values are appropriate.power-libperfmgr/aidl/Power.cpp (5)
129-137: LGTM!The
isModeSupportedmethod correctly checks for mode support.
177-181: LGTM!The
isBoostSupportedmethod correctly checks for boost support.
188-201: LGTM!The
dumpmethod correctly writes the current state to a file descriptor.
204-221: LGTM!The
createHintSessionmethod correctly creates a new power hint session.
224-232: LGTM!The
getHintSessionPreferredRatemethod correctly retrieves the preferred rate for hint sessions.power-libperfmgr/aidl/PowerHintSession.cpp (4)
150-152: LGTM!The
traceSessionValmethod correctly traces session values.
154-157: LGTM!The
isAppSessionmethod correctly checks if the session is an application session.
159-171: LGTM!The
updateUniveralBoostModemethod correctly updates the universal boost mode.
173-179: LGTM!The
tryToSendPowerHintmethod correctly sends power hints.
| * limitations under the License. | ||
| */ | ||
|
|
||
| #pragma once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using #ifndef guards instead of #pragma once.
While #pragma once is widely supported, using #ifndef guards can improve portability.
#ifndef AIDL_GOOGLE_HARDWARE_POWER_IMPL_PIXEL_POWER_H
#define AIDL_GOOGLE_HARDWARE_POWER_IMPL_PIXEL_POWER_H
// ... code ...
#endif // AIDL_GOOGLE_HARDWARE_POWER_IMPL_PIXEL_POWER_H| void updateHintMode(const std::string &mode, bool enabled); | ||
| void updateHintBoost(const std::string &boost, int32_t durationMs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validate the mode string.
Consider adding validation for the mode string to ensure it matches expected values.
if (mode.empty()) {
ALOGW("PowerSessionManager::updateHintMode: mode is empty");
return;
}|
|
||
| } // namespace pixel | ||
| } // namespace impl | ||
| } // namespace power | ||
| } // namespace hardware |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for the session parameter.
Consider adding error handling to check if the session parameter is valid before using it.
if (!session) {
ALOGW("PowerSessionManager::addPowerSession: session is null");
return;
}| struct AppHintDesc { | ||
| AppHintDesc(int32_t tgid, int32_t uid, std::vector<int32_t> threadIds) | ||
| : tgid(tgid), | ||
| uid(uid), | ||
| threadIds(std::move(threadIds)), | ||
| duration(0LL), | ||
| current_min(0), | ||
| is_active(true), | ||
| update_count(0), | ||
| integral_error(0), | ||
| previous_error(0) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add validation for the input parameters.
Consider adding validation to check if the input parameters are valid before using them.
if (tgid < 0 || uid < 0) {
ALOGW("AppHintDesc: invalid tgid or uid");
return;
}| explicit PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds, | ||
| int64_t durationNanos); | ||
| ~PowerHintSession(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add validation for the input parameters.
Consider adding validation to check if the input parameters are valid before using them.
if (tgid < 0 || uid < 0) {
ALOGW("PowerHintSession: invalid tgid or uid");
return;
}| ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) { | ||
| LOG(DEBUG) << "Power setMode: " << toString(type) << " to: " << enabled; | ||
| if (HintManager::GetInstance()->GetAdpfProfile() && | ||
| HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs > 0) { | ||
| PowerSessionManager::getInstance()->updateHintMode(toString(type), enabled); | ||
| } | ||
| if (setDeviceSpecificMode(type, enabled)) { | ||
| return ndk::ScopedAStatus::ok(); | ||
| } | ||
|
|
||
| switch (type) { | ||
| case Mode::SUSTAINED_PERFORMANCE: | ||
| if (enabled) { | ||
| HintManager::GetInstance()->DoHint("SUSTAINED_PERFORMANCE"); | ||
| } | ||
| mSustainedPerfModeOn = true; | ||
| break; | ||
| case Mode::LAUNCH: | ||
| if (mSustainedPerfModeOn) { | ||
| break; | ||
| } | ||
| [[fallthrough]]; | ||
| case Mode::DOUBLE_TAP_TO_WAKE: | ||
| [[fallthrough]]; | ||
| case Mode::FIXED_PERFORMANCE: | ||
| [[fallthrough]]; | ||
| case Mode::EXPENSIVE_RENDERING: | ||
| [[fallthrough]]; | ||
| case Mode::INTERACTIVE: | ||
| [[fallthrough]]; | ||
| case Mode::DEVICE_IDLE: | ||
| [[fallthrough]]; | ||
| case Mode::DISPLAY_INACTIVE: | ||
| [[fallthrough]]; | ||
| case Mode::AUDIO_STREAMING_LOW_LATENCY: | ||
| [[fallthrough]]; | ||
| case Mode::GAME_LOADING: | ||
| [[fallthrough]]; | ||
| default: | ||
| if (enabled) { | ||
| HintManager::GetInstance()->DoHint(toString(type)); | ||
| } else { | ||
| HintManager::GetInstance()->EndHint(toString(type)); | ||
| } | ||
| break; | ||
| } | ||
|
|
||
| return ndk::ScopedAStatus::ok(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for HintManager methods.
The HintManager::DoHint and HintManager::EndHint methods might fail, and this is not currently handled.
if (enabled) {
if (!HintManager::GetInstance()->DoHint(toString(type))) {
LOG(ERROR) << "Failed to apply hint for mode: " << toString(type);
// Handle the error appropriately
}
} else {
if (!HintManager::GetInstance()->EndHint(toString(type))) {
LOG(ERROR) << "Failed to end hint for mode: " << toString(type);
// Handle the error appropriately
}
}Add error handling for HintManager methods.
The HintManager::DoHint and HintManager::EndHint methods might fail, and this is not currently handled.
if (enabled) {
if (!HintManager::GetInstance()->DoHint(toString(type))) {
LOG(ERROR) << "Failed to apply hint for mode: " << toString(type);
// Handle the error appropriately
}
} else {
if (!HintManager::GetInstance()->EndHint(toString(type))) {
LOG(ERROR) << "Failed to end hint for mode: " << toString(type);
// Handle the error appropriately
}
}| ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) { | ||
| LOG(DEBUG) << "Power setBoost: " << toString(type) << " duration: " << durationMs; | ||
| if (HintManager::GetInstance()->GetAdpfProfile() && | ||
| HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs > 0) { | ||
| PowerSessionManager::getInstance()->updateHintBoost(toString(type), durationMs); | ||
| } | ||
| switch (type) { | ||
| case Boost::INTERACTION: | ||
| if (mSustainedPerfModeOn) { | ||
| break; | ||
| } | ||
| mInteractionHandler->Acquire(durationMs); | ||
| break; | ||
| case Boost::DISPLAY_UPDATE_IMMINENT: | ||
| [[fallthrough]]; | ||
| case Boost::ML_ACC: | ||
| [[fallthrough]]; | ||
| case Boost::AUDIO_LAUNCH: | ||
| [[fallthrough]]; | ||
| default: | ||
| if (mSustainedPerfModeOn) { | ||
| break; | ||
| } | ||
| if (durationMs > 0) { | ||
| HintManager::GetInstance()->DoHint(toString(type), | ||
| std::chrono::milliseconds(durationMs)); | ||
| } else if (durationMs == 0) { | ||
| HintManager::GetInstance()->DoHint(toString(type)); | ||
| } else { | ||
| HintManager::GetInstance()->EndHint(toString(type)); | ||
| } | ||
| break; | ||
| } | ||
|
|
||
| return ndk::ScopedAStatus::ok(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for HintManager methods.
The HintManager::DoHint and HintManager::EndHint methods might fail, and this is not currently handled.
if (durationMs > 0) {
if (!HintManager::GetInstance()->DoHint(toString(type), std::chrono::milliseconds(durationMs))) {
LOG(ERROR) << "Failed to apply hint for boost: " << toString(type);
// Handle the error appropriately
}
} else if (durationMs == 0) {
if (!HintManager::GetInstance()->DoHint(toString(type))) {
LOG(ERROR) << "Failed to apply hint for boost: " << toString(type);
// Handle the error appropriately
}
} else {
if (!HintManager::GetInstance()->EndHint(toString(type))) {
LOG(ERROR) << "Failed to end hint for boost: " << toString(type);
// Handle the error appropriately
}
}Add error handling for HintManager methods.
The HintManager::DoHint and HintManager::EndHint methods might fail, and this is not currently handled.
if (durationMs > 0) {
if (!HintManager::GetInstance()->DoHint(toString(type), std::chrono::milliseconds(durationMs))) {
LOG(ERROR) << "Failed to apply hint for boost: " << toString(type);
// Handle the error appropriately
}
} else if (durationMs == 0) {
if (!HintManager::GetInstance()->DoHint(toString(type))) {
LOG(ERROR) << "Failed to apply hint for boost: " << toString(type);
// Handle the error appropriately
}
} else {
if (!HintManager::GetInstance()->EndHint(toString(type))) {
LOG(ERROR) << "Failed to end hint for boost: " << toString(type);
// Handle the error appropriately
}
}| int64_t PowerHintSession::convertWorkDurationToBoostByPid( | ||
| const std::vector<WorkDuration> &actualDurations) { | ||
| std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile(); | ||
| const nanoseconds &targetDuration = mDescriptor->duration; | ||
| int64_t &integral_error = mDescriptor->integral_error; | ||
| int64_t &previous_error = mDescriptor->previous_error; | ||
| uint64_t samplingWindowP = adpfConfig->mSamplingWindowP; | ||
| uint64_t samplingWindowI = adpfConfig->mSamplingWindowI; | ||
| uint64_t samplingWindowD = adpfConfig->mSamplingWindowD; | ||
| int64_t targetDurationNanos = (int64_t)targetDuration.count(); | ||
| int64_t length = actualDurations.size(); | ||
| int64_t p_start = | ||
| samplingWindowP == 0 || samplingWindowP > length ? 0 : length - samplingWindowP; | ||
| int64_t i_start = | ||
| samplingWindowI == 0 || samplingWindowI > length ? 0 : length - samplingWindowI; | ||
| int64_t d_start = | ||
| samplingWindowD == 0 || samplingWindowD > length ? 0 : length - samplingWindowD; | ||
| int64_t dt = ns_to_100us(targetDurationNanos); | ||
| int64_t err_sum = 0; | ||
| int64_t derivative_sum = 0; | ||
| for (int64_t i = std::min({p_start, i_start, d_start}); i < length; i++) { | ||
| int64_t actualDurationNanos = actualDurations[i].durationNanos; | ||
| if (std::abs(actualDurationNanos) > targetDurationNanos * 20) { | ||
| ALOGW("The actual duration is way far from the target (%" PRId64 " >> %" PRId64 ")", | ||
| actualDurationNanos, targetDurationNanos); | ||
| } | ||
| // PID control algorithm | ||
| int64_t error = ns_to_100us(actualDurationNanos - targetDurationNanos); | ||
| if (i >= d_start) { | ||
| derivative_sum += error - previous_error; | ||
| } | ||
| if (i >= p_start) { | ||
| err_sum += error; | ||
| } | ||
| if (i >= i_start) { | ||
| integral_error += error * dt; | ||
| integral_error = std::min(adpfConfig->getPidIHighDivI(), integral_error); | ||
| integral_error = std::max(adpfConfig->getPidILowDivI(), integral_error); | ||
| } | ||
| previous_error = error; | ||
| } | ||
| int64_t pOut = static_cast<int64_t>((err_sum > 0 ? adpfConfig->mPidPo : adpfConfig->mPidPu) * | ||
| err_sum / (length - p_start)); | ||
| int64_t iOut = static_cast<int64_t>(adpfConfig->mPidI * integral_error); | ||
| int64_t dOut = | ||
| static_cast<int64_t>((derivative_sum > 0 ? adpfConfig->mPidDo : adpfConfig->mPidDu) * | ||
| derivative_sum / dt / (length - d_start)); | ||
|
|
||
| int64_t output = pOut + iOut + dOut; | ||
| if (ATRACE_ENABLED()) { | ||
| traceSessionVal("pid.err", err_sum / (length - p_start)); | ||
| traceSessionVal("pid.integral", integral_error); | ||
| traceSessionVal("pid.derivative", derivative_sum / dt / (length - d_start)); | ||
| traceSessionVal("pid.pOut", pOut); | ||
| traceSessionVal("pid.iOut", iOut); | ||
| traceSessionVal("pid.dOut", dOut); | ||
| traceSessionVal("pid.output", output); | ||
| } | ||
| return output; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for potential issues in the PID calculation.
The PID control algorithm might encounter issues, such as division by zero or overflow, and this is not currently handled.
try {
// PID control algorithm
int64_t error = ns_to_100us(actualDurationNanos - targetDurationNanos);
if (i >= d_start) {
derivative_sum += error - previous_error;
}
if (i >= p_start) {
err_sum += error;
}
if (i >= i_start) {
integral_error += error * dt;
integral_error = std::min(adpfConfig->getPidIHighDivI(), integral_error);
integral_error = std::max(adpfConfig->getPidILowDivI(), integral_error);
}
previous_error = error;
} catch (const std::exception &e) {
ALOGE("PID calculation error: %s", e.what());
// Handle the error appropriately
}| PowerHintSession::PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds, | ||
| int64_t durationNanos) | ||
| : mStaleTimerHandler(sp<StaleTimerHandler>::make(this)), | ||
| mBoostTimerHandler(sp<BoostTimerHandler>::make(this)) { | ||
| mDescriptor = new AppHintDesc(tgid, uid, threadIds); | ||
| mDescriptor->duration = std::chrono::nanoseconds(durationNanos); | ||
| mIdString = StringPrintf("%" PRId32 "-%" PRId32 "-%" PRIxPTR, mDescriptor->tgid, | ||
| mDescriptor->uid, reinterpret_cast<uintptr_t>(this) & 0xffff); | ||
|
|
||
| mPowerManagerHandler = PowerSessionManager::getInstance(); | ||
| mLastUpdatedTime.store(std::chrono::steady_clock::now()); | ||
| if (ATRACE_ENABLED()) { | ||
| traceSessionVal("target", mDescriptor->duration.count()); | ||
| traceSessionVal("active", mDescriptor->is_active.load()); | ||
| } | ||
| PowerSessionManager::getInstance()->addPowerSession(this); | ||
| // init boost | ||
| sendHint(SessionHint::CPU_LOAD_RESET); | ||
| ALOGV("PowerHintSession created: %s", mDescriptor->toString().c_str()); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for potential issues in the initialization.
The initialization might encounter issues, such as failed memory allocation or invalid arguments, and this is not currently handled.
try {
mDescriptor = new AppHintDesc(tgid, uid, threadIds);
mDescriptor->duration = std::chrono::nanoseconds(durationNanos);
mIdString = StringPrintf("%" PRId32 "-%" PRId32 "-%" PRIxPTR, mDescriptor->tgid,
mDescriptor->uid, reinterpret_cast<uintptr_t>(this) & 0xffff);
mPowerManagerHandler = PowerSessionManager::getInstance();
mLastUpdatedTime.store(std::chrono::steady_clock::now());
if (ATRACE_ENABLED()) {
traceSessionVal("target", mDescriptor->duration.count());
traceSessionVal("active", mDescriptor->is_active.load());
}
PowerSessionManager::getInstance()->addPowerSession(this);
// init boost
sendHint(SessionHint::CPU_LOAD_RESET);
ALOGV("PowerHintSession created: %s", mDescriptor->toString().c_str());
} catch (const std::exception &e) {
ALOGE("Initialization error: %s", e.what());
// Handle the error appropriately
}| PowerHintSession::~PowerHintSession() { | ||
| close(); | ||
| ALOGV("PowerHintSession deleted: %s", mDescriptor->toString().c_str()); | ||
| if (ATRACE_ENABLED()) { | ||
| traceSessionVal("target", 0); | ||
| traceSessionVal("actl_last", 0); | ||
| traceSessionVal("active", 0); | ||
| } | ||
| delete mDescriptor; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for potential issues in the cleanup.
The cleanup might encounter issues, such as failed resource deallocation, and this is not currently handled.
try {
close();
ALOGV("PowerHintSession deleted: %s", mDescriptor->toString().c_str());
if (ATRACE_ENABLED()) {
traceSessionVal("target", 0);
traceSessionVal("actl_last", 0);
traceSessionVal("active", 0);
}
delete mDescriptor;
} catch (const std::exception &e) {
ALOGE("Cleanup error: %s", e.what());
// Handle the error appropriately
}
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Chores