Commit aa6b36a6 authored by Raphael Defosseux's avatar Raphael Defosseux

[RHEL8][CONTAINER] Runtime check when creating pThreads

It looks like :
  - when running on a Fedora-host
  - with generic kernel
  - in a container
  - even in privileged mode

That is not enough and priority/schedule settings is not allowed.

So at runtime, we check and in case, we don't set up priorities.
Signed-off-by: default avatarRaphael Defosseux <raphael.defosseux@eurecom.fr>
parent c19ba39e
...@@ -96,6 +96,51 @@ static void read_pipe(int p, char *b, int size) { ...@@ -96,6 +96,51 @@ static void read_pipe(int p, char *b, int size) {
} }
} }
static int baseRunTimeCommand(char* cmd) {
FILE *fp;
size_t retSize = 0;
fp = popen(cmd, "r");
memset(cmd, 1, 200);
retSize = fread(cmd, 1, 200, fp);
fclose(fp);
if (retSize == 0) {
return 0;
}
return atoi(cmd);
}
int checkIfFedoraDistribution(void) {
char cmd[200];
memset(cmd, 1, 200);
sprintf(cmd, "cat /etc/os-release | grep ID_LIKE | grep -ic fedora || true");
return baseRunTimeCommand(cmd);
}
int checkIfGenericKernelOnFedora(void) {
char cmd[200];
memset(cmd, 1, 200);
sprintf(cmd, "uname -a | grep -c rt || true");
return (1 - baseRunTimeCommand(cmd));
}
int checkIfInsideContainer(void) {
char cmd[200];
int res = 0;
memset(cmd, 1, 200);
sprintf(cmd, "cat /proc/self/cgroup | egrep -c 'libpod|podman|kubepods' || true");
res = baseRunTimeCommand(cmd);
if (res > 0)
return 1;
else
return 0;
}
/********************************************************************/ /********************************************************************/
/* background process */ /* background process */
/********************************************************************/ /********************************************************************/
...@@ -200,29 +245,38 @@ void start_background_system(void) { ...@@ -200,29 +245,38 @@ void start_background_system(void) {
void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority){ void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority){
pthread_attr_t attr; pthread_attr_t attr;
int ret; int ret;
int settingPriority = 1;
ret=pthread_attr_init(&attr); ret=pthread_attr_init(&attr);
AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno); AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
ret=pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); ret=pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno); AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
ret=pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); ret=pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno); AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
ret=pthread_attr_setschedpolicy(&attr, SCHED_OAI); if (checkIfFedoraDistribution())
AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno); if (checkIfGenericKernelOnFedora())
if(priority<sched_get_priority_min(SCHED_OAI) || priority>sched_get_priority_max(SCHED_FIFO)) { if (checkIfInsideContainer())
LOG_E(TMR,"Prio not possible: %d, min is %d, max: %d, forced in the range\n", settingPriority = 0;
priority,
sched_get_priority_min(SCHED_OAI), if (settingPriority) {
sched_get_priority_max(SCHED_OAI)); ret=pthread_attr_setschedpolicy(&attr, SCHED_OAI);
if(priority<sched_get_priority_min(SCHED_OAI)) AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
priority=sched_get_priority_min(SCHED_OAI); if(priority<sched_get_priority_min(SCHED_OAI) || priority>sched_get_priority_max(SCHED_FIFO)) {
if(priority>sched_get_priority_max(SCHED_OAI)) LOG_E(TMR,"Prio not possible: %d, min is %d, max: %d, forced in the range\n",
priority=sched_get_priority_max(SCHED_OAI); priority,
sched_get_priority_min(SCHED_OAI),
sched_get_priority_max(SCHED_OAI));
if(priority<sched_get_priority_min(SCHED_OAI))
priority=sched_get_priority_min(SCHED_OAI);
if(priority>sched_get_priority_max(SCHED_OAI))
priority=sched_get_priority_max(SCHED_OAI);
}
AssertFatal(priority<=sched_get_priority_max(SCHED_OAI),"");
struct sched_param sparam={0};
sparam.sched_priority = priority;
ret=pthread_attr_setschedparam(&attr, &sparam);
AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
} }
AssertFatal(priority<=sched_get_priority_max(SCHED_OAI),"");
struct sched_param sparam={0};
sparam.sched_priority = priority;
ret=pthread_attr_setschedparam(&attr, &sparam);
AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
ret=pthread_create(t, &attr, func, param); ret=pthread_create(t, &attr, func, param);
AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno); AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
......
...@@ -58,6 +58,14 @@ void thread_top_init(char *thread_name, ...@@ -58,6 +58,14 @@ void thread_top_init(char *thread_name,
uint64_t deadline, uint64_t deadline,
uint64_t period); uint64_t period);
/****************************************************
* Functions to check system at runtime.
****************************************************/
int checkIfFedoraDistribution(void);
int checkIfGenericKernelOnFedora(void);
int checkIfInsideContainer(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "lte-softmodem.h" #include "lte-softmodem.h"
#include "rt_wrapper.h" #include "rt_wrapper.h"
#include "system.h"
#include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac.h"
#include "RRC/LTE/rrc_extern.h" #include "RRC/LTE/rrc_extern.h"
...@@ -230,14 +231,23 @@ void init_thread(int sched_runtime, ...@@ -230,14 +231,23 @@ void init_thread(int sched_runtime,
} }
#else #else
int settingPriority = 1;
if (CPU_COUNT(cpuset) > 0) if (checkIfFedoraDistribution())
AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), ""); if (checkIfGenericKernelOnFedora())
if (checkIfInsideContainer())
settingPriority = 0;
if (settingPriority) {
if (CPU_COUNT(cpuset) > 0)
AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), "");
struct sched_param sp;
sp.sched_priority = sched_fifo;
AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0,
"Can't set thread priority, Are you root?\n");
}
struct sched_param sp;
sp.sched_priority = sched_fifo;
AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0,
"Can't set thread priority, Are you root?\n");
/* Check the actual affinity mask assigned to the thread */ /* Check the actual affinity mask assigned to the thread */
cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE); cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE);
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <getopt.h> #include <getopt.h>
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include "rt_wrapper.h" #include "rt_wrapper.h"
#include "system.h"
#include <errno.h> #include <errno.h>
#include <common/utils/msc/msc.h> #include <common/utils/msc/msc.h>
...@@ -294,6 +295,7 @@ void thread_top_init(char *thread_name, ...@@ -294,6 +295,7 @@ void thread_top_init(char *thread_name,
struct sched_param sparam; struct sched_param sparam;
char cpu_affinity[1024]; char cpu_affinity[1024];
cpu_set_t cpuset; cpu_set_t cpuset;
int settingPriority = 1;
/* Set affinity mask to include CPUs 2 to MAX_CPUS */ /* Set affinity mask to include CPUs 2 to MAX_CPUS */
/* CPU 0 is reserved for UHD threads */ /* CPU 0 is reserved for UHD threads */
...@@ -340,30 +342,37 @@ void thread_top_init(char *thread_name, ...@@ -340,30 +342,37 @@ void thread_top_init(char *thread_name,
} }
} }
memset(&sparam, 0, sizeof(sparam)); if (checkIfFedoraDistribution())
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO); if (checkIfGenericKernelOnFedora())
policy = SCHED_FIFO ; if (checkIfInsideContainer())
settingPriority = 0;
if (settingPriority) {
memset(&sparam, 0, sizeof(sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
policy = SCHED_FIFO;
s = pthread_setschedparam(pthread_self(), policy, &sparam); s = pthread_setschedparam(pthread_self(), policy, &sparam);
if (s != 0) { if (s != 0) {
perror("pthread_setschedparam : "); perror("pthread_setschedparam : ");
exit_fun("Error setting thread priority"); exit_fun("Error setting thread priority");
} }
s = pthread_getschedparam(pthread_self(), &policy, &sparam); s = pthread_getschedparam(pthread_self(), &policy, &sparam);
if (s != 0) { if (s != 0) {
perror("pthread_getschedparam : "); perror("pthread_getschedparam : ");
exit_fun("Error getting thread priority"); exit_fun("Error getting thread priority");
} }
pthread_setname_np(pthread_self(), thread_name); pthread_setname_np(pthread_self(), thread_name);
LOG_I(HW, "[SCHED][eNB] %s started on CPU %d, sched_policy = %s , priority = %d, CPU Affinity=%s \n",thread_name,sched_getcpu(), LOG_I(HW, "[SCHED][eNB] %s started on CPU %d, sched_policy = %s , priority = %d, CPU Affinity=%s \n",thread_name,sched_getcpu(),
(policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" : (policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" : (policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???", "???",
sparam.sched_priority, cpu_affinity ); sparam.sched_priority, cpu_affinity );
}
#endif //LOW_LATENCY #endif //LOW_LATENCY
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment