This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 8cec1d01db8 sched/sched: Fix uninitialized sporadic params returned by
nxsched_get_param()
8cec1d01db8 is described below
commit 8cec1d01db85f5911d408ffd550109706df0c642
Author: yushuailong <[email protected]>
AuthorDate: Fri Jul 31 11:32:57 2026 +0800
sched/sched: Fix uninitialized sporadic params returned by
nxsched_get_param()
When querying the calling task itself (pid == 0 or the caller's own
pid), nxsched_get_param() only filled in sched_priority and never
touched the SCHED_SPORADIC related members (sched_ss_low_priority,
sched_ss_max_repl, sched_ss_repl_period and sched_ss_init_budget).
With CONFIG_SCHED_SPORADIC enabled, the caller received uninitialized
stack garbage in these fields, and a task running under the sporadic
policy could not retrieve its own sporadic parameters.
Fix this by factoring the sporadic parameter fill-in into a common
helper nxsched_get_sporadic_param() shared by both the self-query and
the lookup paths, so both paths now return identical information.
The self-query path keeps its original fast-path behavior: no TCB
lookup and a lock-free read of sched_priority. Only the read of the
sporadic state is wrapped in a critical section, because tcb->sporadic
may be freed concurrently, e.g. by sched_setscheduler() from another
CPU switching the task away from SCHED_SPORADIC.
Signed-off-by: yushuailong <[email protected]>
---
sched/sched/sched_getparam.c | 85 ++++++++++++++++++++++++++++++--------------
1 file changed, 58 insertions(+), 27 deletions(-)
diff --git a/sched/sched/sched_getparam.c b/sched/sched/sched_getparam.c
index 7232134e2cb..b1a83bc537b 100644
--- a/sched/sched/sched_getparam.c
+++ b/sched/sched/sched_getparam.c
@@ -36,6 +36,51 @@
#include "clock/clock.h"
#include "sched/sched.h"
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxsched_get_sporadic_param
+ *
+ * Description:
+ * Fill in the SCHED_SPORADIC related members of param from the TCB.
+ * Must be called within a critical section since the sporadic scheduler
+ * state may be modified concurrently.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SCHED_SPORADIC
+static void nxsched_get_sporadic_param(FAR struct tcb_s *tcb,
+ FAR struct sched_param *param)
+{
+ if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
+ {
+ FAR struct sporadic_s *sporadic = tcb->sporadic;
+ DEBUGASSERT(sporadic != NULL);
+
+ /* Return parameters associated with SCHED_SPORADIC */
+
+ param->sched_ss_low_priority = (int)sporadic->low_priority;
+ param->sched_ss_max_repl = (int)sporadic->max_repl;
+
+ clock_ticks2time(¶m->sched_ss_repl_period,
+ sporadic->repl_period);
+ clock_ticks2time(¶m->sched_ss_init_budget,
+ sporadic->budget);
+ }
+ else
+ {
+ param->sched_ss_low_priority = 0;
+ param->sched_ss_max_repl = 0;
+ param->sched_ss_repl_period.tv_sec = 0;
+ param->sched_ss_repl_period.tv_nsec = 0;
+ param->sched_ss_init_budget.tv_sec = 0;
+ param->sched_ss_init_budget.tv_nsec = 0;
+ }
+}
+#endif
+
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -81,14 +126,24 @@ int nxsched_get_param(pid_t pid, FAR struct sched_param
*param)
}
else
{
- /* Check if the task to restart is the calling task */
+ /* Check if the PID is that of the calling task */
rtcb = this_task();
if (pid == 0 || pid == rtcb->pid)
{
- /* Return the priority if the calling task. */
+ /* Return the priority of the calling task. */
param->sched_priority = (int)rtcb->sched_priority;
+
+#ifdef CONFIG_SCHED_SPORADIC
+ /* The sporadic state may be modified concurrently, e.g. by
+ * sched_setparam() from another CPU, so it must be protected.
+ */
+
+ flags = enter_critical_section();
+ nxsched_get_sporadic_param(rtcb, param);
+ leave_critical_section(flags);
+#endif
}
/* This PID is not for the calling task, we will have to look it up */
@@ -112,31 +167,7 @@ int nxsched_get_param(pid_t pid, FAR struct sched_param
*param)
param->sched_priority = (int)tcb->sched_priority;
#ifdef CONFIG_SCHED_SPORADIC
- if ((tcb->flags & TCB_FLAG_POLICY_MASK) ==
- TCB_FLAG_SCHED_SPORADIC)
- {
- FAR struct sporadic_s *sporadic = tcb->sporadic;
- DEBUGASSERT(sporadic != NULL);
-
- /* Return parameters associated with SCHED_SPORADIC */
-
- param->sched_ss_low_priority = (int)sporadic->low_priority;
- param->sched_ss_max_repl = (int)sporadic->max_repl;
-
- clock_ticks2time(¶m->sched_ss_repl_period,
- sporadic->repl_period);
- clock_ticks2time(¶m->sched_ss_init_budget,
- sporadic->budget);
- }
- else
- {
- param->sched_ss_low_priority = 0;
- param->sched_ss_max_repl = 0;
- param->sched_ss_repl_period.tv_sec = 0;
- param->sched_ss_repl_period.tv_nsec = 0;
- param->sched_ss_init_budget.tv_sec = 0;
- param->sched_ss_init_budget.tv_nsec = 0;
- }
+ nxsched_get_sporadic_param(tcb, param);
#endif
}