I am trying to spawn threads with SCHED_FIFO or SCHED_RR policies as root on a Linux system but my calls to pthread_create() are returning 1 (EPERM). The man page for pthread_create() says that EPERM indicates that "[t]he caller does not have appropriate permission to set the required scheduling parameters or scheduling policy." Shouldn't root be able to specify SCHED_FIFO or SCHED_RR?
I've stripped out the code that creates a thread into a small program that does only that. It looks right to me but still gets the error. What am I doing wrong?
The program:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static void *_Thread(void *arg)
{
(void)arg;
printf("Thread running!\n");
return NULL;
}
int main(void)
{
int retVal;
pthread_attr_t attr;
struct sched_param schedParam;
pthread_t thread;
retVal = pthread_attr_init(&attr);
if (retVal)
{
fprintf(stderr, "pthread_attr_init error %d\n", retVal);
exit(1);
}
retVal = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
if (retVal)
{
fprintf(stderr, "pthread_attr_setinheritsched error %d\n", retVal);
exit(1);
}
retVal = pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
if (retVal)
{
fprintf(stderr, "pthread_attr_setschedpolicy error %d\n", retVal);
exit(1);
}
schedParam.sched_priority = 1;
retVal = pthread_attr_setschedparam(&attr, &schedParam);
if (retVal)
{
fprintf(stderr, "pthread_attr_setschedparam error %d\n", retVal);
exit(1);
}
retVal = pthread_create(&thread,
&attr,
_Thread,
NULL);
if (retVal)
{
fprintf(stderr, "pthread_create error %d\n", retVal);
exit(1);
}
retVal = pthread_join(thread, NULL);
if (retVal)
{
fprintf(stderr, "pthread_join error %d\n", retVal);
exit(1);
}
printf("main run successfully\n");
return 0;
}
This program has been compiled and run as root. When run, it program fails at the call to pthread_create, returning EPERM.
Changing the thread to SCHED_RR scheduling has no effect - EPERM still returned by pthread_create.
Changing the thread to SCHED_OTHER scheduling and its priority to 0 allows the program to run without error.
The man page for pthread_create () says that EPERM indicates that " [t]he caller does not have appropriate permission to set the required scheduling parameters or scheduling policy." Shouldn't root be able to specify SCHED_FIFO or SCHED_RR? I've stripped out the code that creates a thread into a small program that does only that.
The pthread_setschedparam () function sets the scheduling policy and parameters of the thread thread . policy specifies the new scheduling policy for thread. The supported values for policy, and their semantics, are described in sched (7) .
In Linux threads run concurrently and are scheduled by the kernel asynchronously and hence the kernel interrupts a threads to allow another to execute from time to time. When a program is invoked, a new process is created and the process will have a single thread.
POSIX.1 also documents an ENOTSUP ("attempt was made to set the policy or scheduling parameters to an unsupported value") error for pthread_setschedparam (). POSIX.1-2001, POSIX.1-2008.
Surprisingly, I ran into the same problem as the OP almost 10 years later: CentOS 7.6, spawning a realtime thread, root user, ulimit -r says "unlimited", yet the thread creation fails returning EPERM. It turned out the failure is caused by the following clause in Linux kernel:
kernel/sched/core.c
if (user) {
#ifdef CONFIG_RT_GROUP_SCHED
/*
* Do not allow realtime tasks into groups that have
no runtime
* assigned.
*/
if (rt_bandwidth_enabled() && rt_policy(policy) &&
task_group(p)->rt_bandwidth.rt_runtime == 0 &&
!task_group_is_autogroup(task_group(p))) {
task_rq_unlock(rq, p, &flags);
return -EPERM;
}
#endif
Given that, and Linux cgroup documentation https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt, and CONFIG_RT_GROUP_SCHED documentation https://www.kernel.org/doc/Documentation/scheduler/sched-rt-group.txt, the problem is resolved by adding the current shell to the existing cgroup with realtime scheduling info:
cd /sys/fs/cgroup/cpu
echo $$ > tasks
Then running the executable spawning a realtime thread from the current shell the thread creation succeeds.
Run the program as root user. Because we are messing with scheduling (its for FIFO and RR). you're messing also (by implication) with relative priorities, and that only root can do.
Running above program normally, pthread_create() returns EPERM, but as root user is works fine.
For more info visit: http://www.linuxforums.org/forum/programming-scripting/111359-pthread-error.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With