Skip to content

Commit 2a6fd74

Browse files
committed
Fix: scheduling: overhaul the whole thing
- prevent possible lockup when format in proc changes - properly get and handle scheduler policy & prio - on SCHED_RR failing push to the max with SCHED_OTHER
1 parent 030befe commit 2a6fd74

File tree

1 file changed

+44
-12
lines changed

1 file changed

+44
-12
lines changed

src/sbd-common.c

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
#include <pwd.h>
2727
#include <unistd.h>
2828
#include <dirent.h>
29+
#include <sys/time.h>
30+
#include <sys/resource.h>
31+
#include <limits.h>
2932

3033
#ifdef _POSIX_MEMLOCK
3134
# include <sys/mman.h>
@@ -298,7 +301,7 @@ watchdog_populate_list(void)
298301
FILE *file;
299302

300303
snprintf(entry_name, sizeof(entry_name),
301-
SYS_CLASS_WATCHDOG "/%s/dev", entry->d_name);
304+
SYS_CLASS_WATCHDOG "/%s/dev", entry->d_name);
302305
file = fopen(entry_name, "r");
303306
if (file) {
304307
int major, minor;
@@ -667,7 +670,7 @@ static int get_realtime_budget(void)
667670
{
668671
FILE *f;
669672
char fname[PATH_MAX];
670-
int res = -1, lnum = 0;
673+
int res = -1, lnum = 0, num;
671674
char *cgroup = NULL, *namespecs = NULL;
672675

673676
snprintf(fname, PATH_MAX, "/proc/%jd/cgroup", (intmax_t)getpid());
@@ -677,7 +680,8 @@ static int get_realtime_budget(void)
677680
(intmax_t)getpid());
678681
goto exit_res;
679682
}
680-
while( fscanf(f, "%d:%m[^:]:%m[^\n]", &lnum, &namespecs, &cgroup) !=EOF ) {
683+
while( (num = fscanf(f, "%d:%m[^:]:%m[^\n]\n", &lnum,
684+
&namespecs, &cgroup)) !=EOF ) {
681685
if (namespecs && strstr(namespecs, "cpuacct")) {
682686
free(namespecs);
683687
break;
@@ -690,6 +694,11 @@ static int get_realtime_budget(void)
690694
free(namespecs);
691695
namespecs = NULL;
692696
}
697+
/* not to get stuck if format changes */
698+
if ((num < 3) && ((fscanf(f, "%*[^\n]") == EOF) ||
699+
(fscanf(f, "\n") == EOF))) {
700+
break;
701+
}
693702
}
694703
fclose(f);
695704
if (cgroup == NULL) {
@@ -776,15 +785,17 @@ sbd_make_realtime(int priority, int stackgrowK, int heapgrowK)
776785
return;
777786
}
778787

788+
do {
779789
#ifdef SCHED_RR
780790
if (move_to_root_cgroup) {
781791
sbd_move_to_root_cgroup(enforce_moving_to_root_cgroup);
782792
}
783793

784794
{
785-
int pcurrent = 0;
786795
int pmin = sched_get_priority_min(SCHED_RR);
787796
int pmax = sched_get_priority_max(SCHED_RR);
797+
struct sched_param sp;
798+
int pcurrent;
788799

789800
if (priority == 0) {
790801
priority = pmax;
@@ -794,26 +805,47 @@ sbd_make_realtime(int priority, int stackgrowK, int heapgrowK)
794805
priority = pmax;
795806
}
796807

797-
pcurrent = sched_getscheduler(0);
798-
if (pcurrent < 0) {
808+
if (sched_getparam(0, &sp) < 0) {
799809
cl_perror("Unable to get scheduler priority");
800810

801-
} else if(pcurrent < priority) {
802-
struct sched_param sp;
811+
} else if ((pcurrent = sched_getscheduler(0)) < 0) {
812+
cl_perror("Unable to get scheduler policy");
803813

814+
} else if ((pcurrent == SCHED_RR) &&
815+
(sp.sched_priority >= priority)) {
816+
cl_log(LOG_INFO,
817+
"Stay with priority (%d) for policy SCHED_RR",
818+
sp.sched_priority);
819+
break;
820+
} else {
804821
memset(&sp, 0, sizeof(sp));
805822
sp.sched_priority = priority;
806823

807824
if (sched_setscheduler(0, SCHED_RR, &sp) < 0) {
808-
cl_perror("Unable to set scheduler priority to %d", priority);
825+
cl_perror(
826+
"Unable to set scheduler policy to SCHED_RR priority %d",
827+
priority);
809828
} else {
810-
cl_log(LOG_INFO, "Scheduler priority is now %d", priority);
829+
cl_log(LOG_INFO,
830+
"Scheduler policy is now SCHED_RR priority %d",
831+
priority);
832+
break;
811833
}
812834
}
813835
}
814836
#else
815-
cl_log(LOG_ERR, "System does not support updating the scheduler priority");
837+
cl_log(LOG_ERR, "System does not support updating the scheduler policy");
838+
#endif
839+
#ifdef PRIO_PGRP
840+
if (setpriority(PRIO_PGRP, 0, INT_MIN) < 0) {
841+
cl_perror("Unable to raise the scheduler priority");
842+
} else {
843+
cl_log(LOG_INFO, "Scheduler priority raised to the maximum");
844+
}
845+
#else
846+
cl_perror("System does not support setting the scheduler priority");
816847
#endif
848+
} while (0);
817849

818850
sbd_memlock(heapgrowK, stackgrowK);
819851
}
@@ -826,7 +858,7 @@ maximize_priority(void)
826858
return;
827859
}
828860

829-
sbd_make_realtime(0, 256, 256);
861+
sbd_make_realtime(0, 256, 256);
830862

831863
if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(),
832864
IOPRIO_PRIO_VALUE(IOPRIO_CLASS_RT, 1)) != 0) {

0 commit comments

Comments
 (0)