-
Notifications
You must be signed in to change notification settings - Fork 8.4k
pm: policy: latency: Add support for immediate action #81856
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,7 @@ | |
| #include <zephyr/device.h> | ||
| #include <zephyr/pm/state.h> | ||
| #include <zephyr/sys/slist.h> | ||
| #include <zephyr/sys/onoff.h> | ||
| #include <zephyr/toolchain.h> | ||
|
|
||
| #ifdef __cplusplus | ||
|
|
@@ -27,37 +28,29 @@ | |
| */ | ||
|
|
||
| /** | ||
| * @brief Callback to notify when maximum latency changes. | ||
| * | ||
| * @param latency New maximum latency. Positive value represents latency in | ||
| * microseconds. SYS_FOREVER_US value lifts the latency constraint. Other values | ||
| * are forbidden. | ||
| */ | ||
| typedef void (*pm_policy_latency_changed_cb_t)(int32_t latency); | ||
|
|
||
| /** | ||
| * @brief Latency change subscription. | ||
| * @brief Latency request. | ||
| * | ||
| * @note All fields in this structure are meant for private usage. | ||
| */ | ||
| struct pm_policy_latency_subscription { | ||
| struct pm_policy_latency_request { | ||
| /** @cond INTERNAL_HIDDEN */ | ||
| sys_snode_t node; | ||
| pm_policy_latency_changed_cb_t cb; | ||
| uint32_t value_us; | ||
| struct onoff_client cli; | ||
| void *internal; | ||
| uint32_t flags; | ||
| /** @endcond */ | ||
| }; | ||
|
|
||
| /** | ||
| * @brief Latency request. | ||
| * @brief Callback to notify when maximum latency changes. | ||
| * | ||
| * @note All fields in this structure are meant for private usage. | ||
| * @param latency New maximum latency. Positive value represents latency in | ||
| * microseconds. SYS_FOREVER_US value lifts the latency constraint. Other values | ||
| * are forbidden. | ||
| */ | ||
| struct pm_policy_latency_request { | ||
| /** @cond INTERNAL_HIDDEN */ | ||
| sys_snode_t node; | ||
| uint32_t value_us; | ||
| /** @endcond */ | ||
| }; | ||
| typedef void (*pm_policy_latency_changed_cb_t)(struct pm_policy_latency_request *req, | ||
| int32_t latency); | ||
|
|
||
| /** | ||
| * @brief Event. | ||
|
|
@@ -275,63 +268,140 @@ | |
| * The system will not enter any power state that would make the system to | ||
| * exceed the given latency value. | ||
| * | ||
| * If immediate control manager is provided request may trigger an action asynchronous action | ||
|
||
| * to reconfigure the system runtime to fullfil requested latency. @p req contains an | ||
| * asynchronous notification field that must be initialize prior to the call to get the | ||
| * notification. | ||
| * | ||
| * @param req Latency request. | ||
| * @param value_us Maximum allowed latency in microseconds. | ||
| * | ||
| * @retval 0 if request is applied. | ||
| * @retval 1 if request required immediate action that is not completed. Configured completion | ||
| * notification will inform about completion. | ||
|
||
| * @retval -EIO immediate action returned error. | ||
| */ | ||
| int pm_policy_latency_request_add(struct pm_policy_latency_request *req, uint32_t value_us); | ||
|
|
||
| /** | ||
| * @brief Synchronously add a new latency requirement. | ||
| * | ||
| * If immediate control manager is not used then it is an equivalent of | ||
| * @ref pm_policy_latency_request_add. If immediate control manager is used then context | ||
| * blocks until request is completed. It can only be called from the thread context. | ||
| * Asynchronous notification field in the @p req is configured and used internally. | ||
| * | ||
| * @retval 0 if request required immediate action that is not completed. Configured completion | ||
| * notification will inform about completion. | ||
| * @retval -EIO immediate action returned error. | ||
| */ | ||
| void pm_policy_latency_request_add(struct pm_policy_latency_request *req, | ||
| uint32_t value_us); | ||
| int pm_policy_latency_request_add_sync(struct pm_policy_latency_request *req, uint32_t value_us); | ||
|
||
|
|
||
| /** | ||
| * @brief Update a latency requirement. | ||
| * | ||
| * @param req Latency request. | ||
| * @param value_us New maximum allowed latency in microseconds. | ||
| * | ||
| * @retval 0 if request is applied. | ||
| * @retval 1 if request required immediate action that is not completed. Configured completion | ||
| * notification will inform about completion. | ||
| * @retval -EIO immediate action returned error. | ||
| */ | ||
| int pm_policy_latency_request_update(struct pm_policy_latency_request *req, uint32_t value_us); | ||
|
|
||
| /** | ||
| * @brief Synchronously update a latency requirement. | ||
| * | ||
| * If immediate control manager is not used then it is an equivalent of | ||
| * @ref pm_policy_latency_request_update. If immediate control manager is used then context | ||
| * blocks until request is completed. It can only be called from the thread context. | ||
| * Asynchronous notification field in the @p req is configured and used internally. | ||
| * | ||
| * @retval 0 if request required immediate action that is not completed. Configured completion | ||
| * notification will inform about completion. | ||
| * @retval -EIO immediate action returned error. | ||
| */ | ||
| void pm_policy_latency_request_update(struct pm_policy_latency_request *req, | ||
| uint32_t value_us); | ||
| int pm_policy_latency_request_update_sync(struct pm_policy_latency_request *req, uint32_t value_us); | ||
|
|
||
| /** | ||
| * @brief Remove a latency requirement. | ||
| * | ||
| * @param req Latency request. | ||
| * | ||
| * @retval 0 if request removed successfully. | ||
| * @retval -EALREADY if request is not active and cannot be removed. | ||
| * @retval -EIO immediate action returned error. | ||
| */ | ||
| int pm_policy_latency_request_remove(struct pm_policy_latency_request *req); | ||
|
|
||
| /** @brief Immediate action manager for single threshold. | ||
|
||
| * | ||
| * If there is only a single threshold that triggers an action then @ref onoff_manager | ||
| * can handle that. Structure must be persistent. | ||
| */ | ||
| void pm_policy_latency_request_remove(struct pm_policy_latency_request *req); | ||
| struct pm_policy_latency_immediate_binary { | ||
| /** Onoff manager. */ | ||
| struct onoff_manager *mgr; | ||
| /** Latency threshold. Value below threshold trigger 'on' action. */ | ||
| int32_t thr; | ||
| }; | ||
|
|
||
| struct pm_policy_latency_immediate_ctrl { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And this one |
||
| /** Indication that onoff manager is used. In future gradual manager might | ||
| * also be supported. | ||
| */ | ||
| bool onoff; | ||
| /** Pointer to the manager which controls immediate action. */ | ||
| union { | ||
| struct pm_policy_latency_immediate_binary *bin_mgr; | ||
| void *mgr; | ||
| }; | ||
| }; | ||
|
|
||
| /** | ||
| * @brief Subscribe to maximum latency changes. | ||
| * | ||
| * @param req Subscription request. | ||
| * @param cb Callback function (NULL to disable). | ||
| */ | ||
| void pm_policy_latency_changed_subscribe(struct pm_policy_latency_subscription *req, | ||
| pm_policy_latency_changed_cb_t cb); | ||
| int pm_policy_latency_immediate_ctrl_add(struct pm_policy_latency_immediate_ctrl *mgr); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And restore the name of this function? The previous one was much clearer to me.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously, subscriber was getting a callback when latency changed. This module was not aware of what is done in the callback. Proposed patch changes it. When latency changes that triggers an asynchronous immediate action (in contrast to latency being only used when entering idle so there is no action as long as cpu does not go to idle). Imo, subscription name would be misleading now. |
||
|
|
||
| /** | ||
| * @brief Unsubscribe to maximum latency changes. | ||
| * | ||
| * @param req Subscription request. | ||
| */ | ||
| void pm_policy_latency_changed_unsubscribe(struct pm_policy_latency_subscription *req); | ||
| #else | ||
| static inline void pm_policy_latency_request_add( | ||
| static inline int pm_policy_latency_request_add( | ||
| struct pm_policy_latency_request *req, uint32_t value_us) | ||
| { | ||
| ARG_UNUSED(req); | ||
| ARG_UNUSED(value_us); | ||
| return 0; | ||
| } | ||
|
|
||
| static inline void pm_policy_latency_request_update( | ||
| static inline int pm_policy_latency_request_update( | ||
| struct pm_policy_latency_request *req, uint32_t value_us) | ||
| { | ||
| ARG_UNUSED(req); | ||
| ARG_UNUSED(value_us); | ||
| return 0; | ||
| } | ||
|
|
||
| static inline void pm_policy_latency_request_remove( | ||
| static inline int pm_policy_latency_request_remove( | ||
| struct pm_policy_latency_request *req) | ||
| { | ||
|
Check notice on line 394 in include/zephyr/pm/policy.h
|
||
| ARG_UNUSED(req); | ||
| return 0; | ||
| } | ||
|
|
||
| static inline int pm_policy_latency_immediate_ctrl_add(struct pm_policy_latency_immediate_ctrl *mgr) | ||
| { | ||
| ARG_UNUSED(mgr); | ||
| return 0; | ||
| } | ||
|
|
||
| #endif /* CONFIG_PM CONFIG_PM_POLICY_LATENCY_STANDALONE */ | ||
|
|
||
| /** | ||
|
|
||
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.
onoff_clientand two 32-bit variables per latency requestor seem like high memory overhead. Wouldn't it be enough to track these data per subscriber instead of per requestor?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.
if immediate action/subscription is needed then it is required. We can add kconfig option which enables that feature and have those fields conditionally compiled.