rt-app: Allow to set only nice or runtime value for SCHED_OTHER/BATCH…#149
rt-app: Allow to set only nice or runtime value for SCHED_OTHER/BATCH…#149deggeman wants to merge 1 commit into
Conversation
|
Only lightly tested with those rt-app json files on my Arm64 VM: `--- { { { { { |
With this test on a arm64 qemu setup I get these logs at the start of each phase: In this case the nice value is clamped at the end of To confirm this I added if (sched_getattr(0, &_sa_params, sizeof(_sa_params), 0) == -1) {
perror("sched_getattr: failed to get SCHED_OTHER attributes");
exit(EXIT_FAILURE);
}
log_debug("[%d] proceeding with nice=%d runtime=%llu", data->ind, _sa_params.sched_nice, _sa_params.sched_runtime);right at the end of |
With this test, THREAD_PRIORITY_UNCHANGED never reaches /* There is no "phases" object which means that thread and phase will
* use same scheduling parameters. But thread object looks for default
* value when parameters are not defined whereas phase doesn't.
* We remove phase's scheduling policy which is a subset of thread's one
*/
free(data->phases[0].sched_data);
data->phases[0].sched_data = NULL;A thread's default (initial) priority cannot be data->sched_data = parse_sched_data(obj, opts->policy);and the If you add log_debug("[%d] set_thread_param() using policy=%d prio=%d runtime=%lu", data->ind, sched_data->policy, sched_data->prio, sched_data->runtime);after the NULL check in |
|
[rt-app] [0] setting scheduler SCHED_OTHER nice=2147483647 runtime=40000000 I think this is happening since we use INT_MAX forTHREAD_PRIORITY_UNCHANGED and not -1. [rt-app] [0] proceeding with nice=19 runtime=40000000 This is a bug which can be fixed by: @@ -984,7 +984,7 @@ static void __set_thread_sched_other_attrs(thread_data_t *data,
it will be effort to use the retrieved prio for logging instead of INT_MAX or (-1). I don't want to set sched_data->prio to the retrieved value to let the logging show the actual value we used for resetting? |
Which is what I suggested in #148 (comment). But even then, we only get this behaviour on fair tasks when there is a phases object present. Otherwise it's the current behaviour where you get rt-app's default attributes, since |
|
True, you're right about the issue of def_prio for def_policy in the phase-less setup. I'm trying: BTW, how does it work with the system settings on those tasks rt-app creates. Which OS infrastructural bits can set nice and slicelen between task spawning and rt-app doing sched_setattr() on the task? |
|
How do I get meaningful code snippets into those comment fields ??? |
| policy_to_string(sched_data->policy), sched_data->prio, | ||
| sched_data->runtime); | ||
|
|
||
| if (sched_data->prio != THREAD_PRIORITY_UNCHANGED || !sched_data->runtime) { |
There was a problem hiding this comment.
I think the condition here should be sched_data->prio == THREAD_PRIORITY_UNCHANGED otherwise sched_getattr() is skipped.
Markdown syntax for code blocks: ``` It also supports language syntax highlighting. I was using ```C |
|
Ah, nice! If you press the Code button, it gives me ` ` instead of ``` ```. Thanks! |
From my understanding it is |
8aaa5a8 to
08d4550
Compare
But we always call pthread_create() and then sched_setattr()? Vincent talked about a "system manager" which could have set a specific runtime for the task, which I assume is a different one than the default se.slice? E.g. with systemd you can put systemd slice (cgroup placement) and the nice value (scheduler priority) directly in a service unit file: [Service] |
|
I faced this case while testing schedqos which sets nice and slice duration. |
| log_debug(PIN "key: set scheduler %d with priority %d", data->policy, data->prio); | ||
|
|
||
| return NULL; | ||
| return data; |
There was a problem hiding this comment.
So you always return a sched_data_t even if there is no change. We have a mechanism to skip set_thread_param when there is not change between 2 phases
There was a problem hiding this comment.
Yeah, this is not necessary. I just have to make sure that I create a sched_data_t for the task in case we have data->sched_data != NULL for the task in case. At least there is a :
/* Set scheduling policy and print pretty info on stdout */
log_notice("[%d] Starting with %s policy with priority %d",
data->ind, policy_to_string(data->sched_data->policy),
data->sched_data->prio);
in thread_body().
Let me change this back and fix this differently in the next version.
| new_data = malloc(sizeof(sched_data_t)); | ||
| memcpy( new_data, &tmp_data,sizeof(sched_data_t)); | ||
| data = malloc(sizeof(sched_data_t)); | ||
| memcpy(data, &tmp_data,sizeof(sched_data_t)); |
There was a problem hiding this comment.
Should we add a null check here? memcpy with a null destination pointer has UB.
There was a problem hiding this comment.
Yes, you're right. But I would like to avoid this fix in this patch-set since there are other places with the same issue. And this has nothing to do with the actual problem this patch should fix.
Ah, OK, and schedqos uses netlink to monitor task activities like FORK & EXEC and can then apply QoS params like nice and slicelen. |
|
|
||
| /* In the CFS case, sched_data->prio is the NICE value. */ | ||
| sa_params.sched_nice = sched_data->prio; | ||
| if (sched_data->prio) |
There was a problem hiding this comment.
-
if (sched_data->prio)
-
if (sched_data->prio != THREAD_PRIORITY_UNCHANGED)
| new_data = malloc(sizeof(sched_data_t)); | ||
| memcpy( new_data, &tmp_data,sizeof(sched_data_t)); | ||
| data = malloc(sizeof(sched_data_t)); | ||
| memcpy(data, &tmp_data,sizeof(sched_data_t)); |
There was a problem hiding this comment.
Yes, you're right. But I would like to avoid this fix in this patch-set since there are other places with the same issue. And this has nothing to do with the actual problem this patch should fix.
| log_debug(PIN "key: set scheduler %d with priority %d", data->policy, data->prio); | ||
|
|
||
| return NULL; | ||
| return data; |
There was a problem hiding this comment.
Yeah, this is not necessary. I just have to make sure that I create a sched_data_t for the task in case we have data->sched_data != NULL for the task in case. At least there is a :
/* Set scheduling policy and print pretty info on stdout */
log_notice("[%d] Starting with %s policy with priority %d",
data->ind, policy_to_string(data->sched_data->policy),
data->sched_data->prio);
in thread_body().
Let me change this back and fix this differently in the next version.
… tasks
sa_params.sched_flags = SCHED_FLAG_KEEP_PARAMS can't be used to keep the
current se.slice value for a task in case it is not specified in its
rt-app profile since in this case the nice value which might be in the
profile gets ignored too:
Kernel-side sched_setattr retrieves the parameters from the task in case
SCHED_FLAG_KEEP_PARAMS is set:
SYSCALL_DEFINE3(sched_setattr, ...) does:
if (attr.sched_flags & SCHED_FLAG_KEEP_PARAMS)
get_params(p, &attr, 0);
So in case either sched_data's prio or runtime is not set, retrieve the
task parameters from the kernel to be able to set the value in case it
is not specified in sched_data.
Make sure that 'sched_data->prio == THREAD_PRIORITY_UNCHANGED' can
reach __set_thread_sched_other_attrs().
To enable this for phase-less (i.e. only task data) configs too set the
default priority of SCHED_OTHER/BATCH/IDLE tasks to
THREAD_PRIORITY_UNCHANGED in parse_sched_data().
But this means we now have to create a task sched_data_t (def_policy !=
0) as well in case all other scheduler parameters (prio (nice), runtime,
period, deadline, util_min, util_max) are not specified in the task
profile.
Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
08d4550 to
dd8ac10
Compare
|
testcases ran on latest version: (~/scripts) e125579 $ ./test_rt-app_sched_setattr.sh (~/scripts) e125579 $ ./test_rt-app_taskgroups_v1.sh |
|
@deggeman Thanks for the update, I will review your latest version beg of next week |
|
I have the log below when I don't set a prio. The end result is ok because there is no scheduler change but the log is weird with 2147483647 for THREAD_PRIORITY_UNCHANGED :
|
… tasks
sa_params.sched_flags = SCHED_FLAG_KEEP_PARAMS can't be used to keep the current se.slice value for a task in case it is not specified in its rt-app profile since in this case the nice value which might be in the profile gets ignored too:
Kernel-side sched_setattr retrieves the parameters from the task in case SCHED_FLAG_KEEP_PARAMS is set:
SYSCALL_DEFINE3(sched_setattr, ...) does:
if (attr.sched_flags & SCHED_FLAG_KEEP_PARAMS)
get_params(p, &attr, 0);
So in case either sched_data's prio or runtime is not set, retrieve the task parameters from the kernel to be able to set the value in case it is not specified in sched_data.
Make sure that the sched_data->prio == THREAD_PRIORITY_UNCHANGED can reach __set_thread_sched_other_attrs().