Linux: Use /proc/*/smaps_rollup for improved PSS parsing speed

This commit is contained in:
Alexander Schlarb 2018-10-16 20:08:23 +02:00
parent fc0bf546c3
commit 078c2ddde5
2 changed files with 18 additions and 3 deletions

View File

@ -89,6 +89,7 @@ typedef struct LinuxProcessList_ {
CPUData* cpus; CPUData* cpus;
TtyDriver* ttyDrivers; TtyDriver* ttyDrivers;
bool haveSmapsRollup;
#ifdef HAVE_DELAYACCT #ifdef HAVE_DELAYACCT
struct nl_sock *netlink_socket; struct nl_sock *netlink_socket;
@ -240,8 +241,17 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui
LinuxProcessList_initNetlinkSocket(this); LinuxProcessList_initNetlinkSocket(this);
#endif #endif
// Check for /proc/*/smaps_rollup availability (improves smaps parsing speed, Linux 4.14+)
FILE* file = fopen(PROCDIR "/self/smaps_rollup", "r");
if(file != NULL) {
this->haveSmapsRollup = true;
fclose(file);
} else {
this->haveSmapsRollup = false;
}
// Update CPU count: // Update CPU count:
FILE* file = fopen(PROCSTATFILE, "r"); file = fopen(PROCSTATFILE, "r");
if (file == NULL) { if (file == NULL) {
CRT_fatalError("Cannot open " PROCSTATFILE); CRT_fatalError("Cannot open " PROCSTATFILE);
} }
@ -486,7 +496,7 @@ static bool LinuxProcessList_readStatmFile(LinuxProcess* process, const char* di
return (errno == 0); return (errno == 0);
} }
static bool LinuxProcessList_readSmapsFile(LinuxProcess* process, const char* dirname, const char* name) { static bool LinuxProcessList_readSmapsFile(LinuxProcess* process, const char* dirname, const char* name, bool haveSmapsRollup) {
//http://elixir.free-electrons.com/linux/v4.10/source/fs/proc/task_mmu.c#L719 //http://elixir.free-electrons.com/linux/v4.10/source/fs/proc/task_mmu.c#L719
//kernel will return data in chunks of size PAGE_SIZE or less. //kernel will return data in chunks of size PAGE_SIZE or less.
@ -494,7 +504,11 @@ static bool LinuxProcessList_readSmapsFile(LinuxProcess* process, const char* di
char *start,*end; char *start,*end;
ssize_t nread=0; ssize_t nread=0;
int tmp=0; int tmp=0;
if(haveSmapsRollup) {// only available in Linux 4.14+
snprintf(buffer, MAX_NAME, "%s/%s/smaps_rollup", dirname, name);
} else {
snprintf(buffer, MAX_NAME, "%s/%s/smaps", dirname, name); snprintf(buffer, MAX_NAME, "%s/%s/smaps", dirname, name);
}
int fd = open(buffer, O_RDONLY); int fd = open(buffer, O_RDONLY);
if (fd == -1) if (fd == -1)
return false; return false;
@ -872,7 +886,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
// Read smaps file of each process only every second pass to improve performance // Read smaps file of each process only every second pass to improve performance
static int smaps_flag = 0; static int smaps_flag = 0;
if ((pid & 1) == smaps_flag){ if ((pid & 1) == smaps_flag){
LinuxProcessList_readSmapsFile(lp, dirname, name); LinuxProcessList_readSmapsFile(lp, dirname, name, this->haveSmapsRollup);
} }
if (pid == 1) { if (pid == 1) {
smaps_flag = !smaps_flag; smaps_flag = !smaps_flag;

View File

@ -62,6 +62,7 @@ typedef struct LinuxProcessList_ {
CPUData* cpus; CPUData* cpus;
TtyDriver* ttyDrivers; TtyDriver* ttyDrivers;
bool haveSmapsRollup;
#ifdef HAVE_DELAYACCT #ifdef HAVE_DELAYACCT
struct nl_sock *netlink_socket; struct nl_sock *netlink_socket;