Initial implementation of applying renice to all process threads

This commit is contained in:
Marc Di Luzio 2019-05-12 20:27:00 +01:00
parent 3ac49385dc
commit f152ea9338

View File

@ -35,8 +35,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include "gamemode.h" #include "gamemode.h"
#include "logging.h" #include "logging.h"
#include <dirent.h>
#include <errno.h> #include <errno.h>
#include <sched.h> #include <sched.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
@ -96,30 +98,53 @@ void game_mode_apply_renice(const GameModeContext *self, const pid_t client, int
renice = 0; renice = 0;
} }
/* Clear errno as -1 is a regitimate return */ /* Open the tasks dir for the client */
errno = 0; char tasks[128];
int prio = getpriority(PRIO_PROCESS, (id_t)client); snprintf(tasks, sizeof(tasks), "/proc/%d/task", client);
if (prio == -1 && errno) { DIR *client_task_dir = opendir(tasks);
/* process has likely ended, only log an error if we were actually trying to set a non-zero if (client_task_dir == NULL) {
* value */ LOG_ERROR("Could not inspect tasks for client [%d]! Skipping ioprio optimisation.\n",
if (errno == ESRCH && renice != 0) client);
LOG_ERROR("getpriority returned ESRCH for process %d\n", client); return;
} else if (prio != expected) { }
/*
* Don't adjust priority if it does not match the expected value /* Iterate for all tasks of client process */
* ie. Another process has changed it, or it began non-standard struct dirent *tid_entry;
*/ while ((tid_entry = readdir(client_task_dir)) != NULL) {
LOG_ERROR("Refused to renice client [%d]: prio was (%d) but we expected (%d)\n", /* Skip . and .. */
client, if (tid_entry->d_name[0] == '.')
prio, continue;
expected);
} else if (setpriority(PRIO_PROCESS, (id_t)client, (int)renice)) { /* task name is the name of the file */
LOG_HINTED(ERROR, int tid = atoi(tid_entry->d_name);
"Failed to renice client [%d], ignoring error condition: %s\n",
" -- Your user may not have permission to do this. Please read the docs\n" /* Clear errno as -1 is a regitimate return */
" -- to learn how to adjust the pam limits.\n", errno = 0;
client, int prio = getpriority(PRIO_PROCESS, (id_t)tid);
strerror(errno)); if (prio == -1 && errno) {
/* process has likely ended, only log an error if we were actually trying to set a
* non-zero value */
if (errno == ESRCH && renice != 0)
LOG_ERROR("getpriority returned ESRCH for process %d\n", tid);
} else if (prio != expected) {
/*
* Don't adjust priority if it does not match the expected value
* ie. Another process has changed it, or it began non-standard
*/
LOG_ERROR("Refused to renice client [%d,%d]: prio was (%d) but we expected (%d)\n",
client,
tid,
prio,
expected);
} else if (setpriority(PRIO_PROCESS, (id_t)client, (int)renice)) {
LOG_HINTED(ERROR,
"Failed to renice client [%d,%d], ignoring error condition: %s\n",
" -- Your user may not have permission to do this. Please read the docs\n"
" -- to learn how to adjust the pam limits.\n",
client,
tid,
strerror(errno));
}
} }
} }