Skip to content

Commit b8c1c50

Browse files
amurzeaubluca
authored andcommitted
fix PSS graph on recent kernels
It seems the smaps file layout in /proc changed in some kernel version. This commit fix it by: - Using smaps_rollup (available since kernel 4.14) instead of smaps to avoid having to loop over all entries (smaps_rollup being a summary of smaps). - If smaps_rollup is not available (kernel < 4.14), use smaps instead as before and sum all PSS lines. - Searching "Pss:" instead of using hardcoded offsets (which will probably go wrong again in the future). Fixes: #46
1 parent 93609bf commit b8c1c50

1 file changed

Lines changed: 19 additions & 39 deletions

File tree

src/store.c

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
* read() overhead.
5252
*/
5353
static char smaps_buf[4096];
54-
static int skip = 0;
5554

5655
double gettime_ns(void) {
5756
struct timespec n;
@@ -489,55 +488,36 @@ int log_sample(DIR *proc,
489488

490489
/* Pss */
491490
if (!ps->smaps) {
492-
sprintf(filename, "%d/smaps", pid);
491+
/* smaps_rollup was introduced in kernel 4.14 */
492+
sprintf(filename, "%d/smaps_rollup", pid);
493493
fd = openat(procfd, filename, O_RDONLY|O_CLOEXEC);
494+
if (fd < 0) {
495+
sprintf(filename, "%d/smaps", pid);
496+
/* If we can't open smaps_rollup, try with smaps */
497+
fd = openat(procfd, filename, O_RDONLY|O_CLOEXEC);
498+
}
494499
if (fd < 0)
495-
continue;
500+
goto catch_rename;
496501
ps->smaps = fdopen(fd, "re");
497502
if (!ps->smaps) {
498503
close(fd);
499-
continue;
504+
goto catch_rename;
500505
}
501506
setvbuf(ps->smaps, smaps_buf, _IOFBF, sizeof(smaps_buf));
502507
} else {
503508
rewind(ps->smaps);
504509
}
505510

506-
/* test to see if we need to skip another field */
507-
if (skip == 0) {
508-
if (fgets(buf, sizeof(buf), ps->smaps) == NULL) {
509-
continue;
510-
}
511-
if (fread(buf, 1, 28 * 15, ps->smaps) != (28 * 15)) {
512-
continue;
513-
}
514-
if (buf[392] == 'V') {
515-
skip = 2;
516-
}
517-
else {
518-
skip = 1;
519-
}
520-
rewind(ps->smaps);
521-
}
522-
523-
while (1) {
524-
int pss_kb;
525-
526-
/* skip one line, this contains the object mapped. */
527-
if (fgets(buf, sizeof(buf), ps->smaps) == NULL) {
528-
break;
529-
}
530-
/* then there's a 28 char 14 line block */
531-
if (fread(buf, 1, 28 * 14, ps->smaps) != 28 * 14) {
532-
break;
533-
}
534-
pss_kb = atoi(&buf[61]);
535-
ps->sample->pss += pss_kb;
536-
537-
/* skip one more line if this is a newer kernel */
538-
if (skip == 2) {
539-
if (fgets(buf, sizeof(buf), ps->smaps) == NULL)
540-
break;
511+
/* Sum all 'Pss:' lines (this is needed when we are not
512+
* reading smaps_rollup).
513+
* When reading smaps_rollup, only one 'Pss:' entry will be
514+
* present.
515+
*/
516+
ps->sample->pss = 0;
517+
while (fgets(buf, sizeof(buf), ps->smaps) != NULL) {
518+
if(strncmp(buf, "Pss:", 4) == 0) {
519+
/* read the Pss line */
520+
ps->sample->pss += atoi(buf + 4);
541521
}
542522
}
543523

0 commit comments

Comments
 (0)