diff --git a/deviate.c b/deviate.c index c9ae3c0c..3d3d450c 100644 --- a/deviate.c +++ b/deviate.c @@ -465,6 +465,9 @@ calcdiff(struct tstat *devstat, const struct tstat *curstat, devstat->mem.vmem = curstat->mem.vmem; devstat->mem.rmem = curstat->mem.rmem; devstat->mem.pmem = curstat->mem.pmem; + devstat->mem.panon = curstat->mem.panon; + devstat->mem.pfile = curstat->mem.pfile; + devstat->mem.pshmem = curstat->mem.pshmem; devstat->mem.vdata = curstat->mem.vdata; devstat->mem.vstack = curstat->mem.vstack; devstat->mem.vlibs = curstat->mem.vlibs; diff --git a/man/atop.1 b/man/atop.1 index 3c889128..e31a7fde 100644 --- a/man/atop.1 +++ b/man/atop.1 @@ -2012,6 +2012,18 @@ since the proportional memory size is not part of the standard process accounting record. .PP .TP 9 +.B PANON +The proportional memory size of this process, shares of anonymous pages. +.PP +.TP 9 +.B PFILE +The proportional memory size of this process, shares of file pages. +.PP +.TP 9 +.B PSHMEM +The proportional memory size of this process, shares of shmem pages. +.PP +.TP 9 .B RDDSK The read data transfer issued physically on disk (so reading from the disk cache is not accounted for). diff --git a/parseable.c b/parseable.c index 6c5a8a71..3518e594 100644 --- a/parseable.c +++ b/parseable.c @@ -820,7 +820,8 @@ print_PRM(char *hp, struct sstat *ss, struct tstat *ps, int nact) for (i=0; i < nact; i++, ps++) { printf("%s %d %s %c %u %lld %lld %lld %lld %lld %lld " - "%lld %lld %lld %lld %lld %d %c %lld %lld %d %d %d %d\n", + "%lld %lld %lld %lld %lld %d %c %lld %lld %lld " + "%lld %lld %d %d %d %d\n", hp, ps->gen.pid, spaceformat(ps->gen.name, namout), @@ -841,6 +842,12 @@ print_PRM(char *hp, struct sstat *ss, struct tstat *ps, int nact) ps->gen.isproc ? 'y':'n', ps->mem.pmem == (unsigned long long)-1LL ? 0:ps->mem.pmem, + ps->mem.panon == (unsigned long long)-1LL ? + 0:ps->mem.panon, + ps->mem.pfile == (unsigned long long)-1LL ? + 0:ps->mem.pfile, + ps->mem.pshmem == (unsigned long long)-1LL ? + 0:ps->mem.pshmem, ps->mem.vlock, cgroupv2max(ps->gen.isproc, ps->mem.cgmemmax), cgroupv2max(ps->gen.isproc, ps->mem.cgmemmaxr), diff --git a/photoproc.c b/photoproc.c index 5219f80d..76269ca0 100644 --- a/photoproc.c +++ b/photoproc.c @@ -885,7 +885,7 @@ procsmaps(struct tstat *curtask) { FILE *fp; char line[4096]; - count_t pssval; + count_t pssval, panon, pfile, pshmem; static int procsmaps_firstcall = 1; static char *smapsfile = "smaps"; @@ -908,16 +908,41 @@ procsmaps(struct tstat *curtask) if ( (fp = fopen(smapsfile, "r")) ) { - curtask->mem.pmem = 0; + curtask->mem.pmem = 0; + curtask->mem.panon = 0; + curtask->mem.pfile = 0; + curtask->mem.pshmem = 0; while (fgets(line, sizeof line, fp)) { - if (memcmp(line, "Pss:", 4) != 0) + if (memcmp(line, "Pss:", 4) == 0) + { + // PSS line found to be accumulated + sscanf(line, "Pss: %llu", &pssval); + curtask->mem.pmem += pssval; continue; - - // PSS line found to be accumulated - sscanf(line, "Pss: %llu", &pssval); - curtask->mem.pmem += pssval; + } + if (memcmp(line, "Pss_Anon:", 9) == 0) + { + // proportional shares of anonymous pages + sscanf(line, "Pss_Anon: %llu", &panon); + curtask->mem.panon += panon; + continue; + } + if (memcmp(line, "Pss_File:", 9) == 0) + { + // proportional shares of file pages + sscanf(line, "Pss_File: %llu", &pfile); + curtask->mem.pfile += pfile; + continue; + } + if (memcmp(line, "Pss_Shmem:", 10) == 0) + { + // proportional shares of shmem pages + sscanf(line, "Pss_Shmem: %llu", &pshmem); + curtask->mem.pshmem += pshmem; + continue; + } } /* @@ -930,7 +955,10 @@ procsmaps(struct tstat *curtask) } else { - curtask->mem.pmem = (unsigned long long)-1LL; + curtask->mem.pmem = (unsigned long long)-1LL; + curtask->mem.panon = (unsigned long long)-1LL; + curtask->mem.pfile = (unsigned long long)-1LL; + curtask->mem.pshmem = (unsigned long long)-1LL; } if (! droprootprivs()) diff --git a/photoproc.h b/photoproc.h index b20e2654..d389c326 100644 --- a/photoproc.h +++ b/photoproc.h @@ -109,7 +109,10 @@ struct tstat { count_t vexec; /* virtmem execfile (Kb) */ count_t vmem; /* virtual memory (Kb) */ count_t rmem; /* resident memory (Kb) */ - count_t pmem; /* resident memory (Kb) */ + count_t pmem; /* proportional memory (Kb) */ + count_t panon; /* proportional shares of anonymous pages (Kb) */ + count_t pfile; /* proportional shares of file pages (Kb) */ + count_t pshmem; /* proportional shares of shmem pages (Kb) */ count_t vgrow; /* virtual growth (Kb) */ count_t rgrow; /* resident growth (Kb) */ count_t vdata; /* virtmem data (Kb) */ diff --git a/showgeneric.c b/showgeneric.c index fd49270a..0bf4469d 100644 --- a/showgeneric.c +++ b/showgeneric.c @@ -2542,9 +2542,19 @@ accumulate(struct tstat *curproc, struct tstat *curstat) if (curstat->mem.pmem != -1) { if (curproc->mem.pmem != -1) // no errors? - curstat->mem.pmem += curproc->mem.pmem; + { + curstat->mem.pmem += curproc->mem.pmem; + curstat->mem.panon += curproc->mem.panon; + curstat->mem.pfile += curproc->mem.pfile; + curstat->mem.pshmem += curproc->mem.pshmem; + } else - curstat->mem.pmem = -1; + { + curstat->mem.pmem = -1; + curstat->mem.panon = -1; + curstat->mem.pfile = -1; + curstat->mem.pshmem = -1; + } } curstat->mem.vmem += curproc->mem.vmem; diff --git a/showlinux.c b/showlinux.c index f1de2d29..9b4ef156 100644 --- a/showlinux.c +++ b/showlinux.c @@ -402,6 +402,9 @@ proc_printdef *allprocpdefs[]= &procprt_VSIZE, &procprt_RSIZE, &procprt_PSIZE, + &procprt_PANON, + &procprt_PFILE, + &procprt_PSHMEM, &procprt_VSLIBS, &procprt_VDATA, &procprt_VSTACK, @@ -1265,8 +1268,8 @@ priphead(int curlist, int totlist, char *showtype, char *showorder, make_proc_prints(memprocs, MAXITEMS, "PID:10 TID:3 MINFLT:2 MAJFLT:2 VSTEXT:4 VSLIBS:4 " "VDATA:4 VSTACK:4 LOCKSZ:3 VSIZE:6 RSIZE:7 PSIZE:5 " - "VGROW:7 RGROW:8 SWAPSZ:5 RUID:1 EUID:0 " - "SORTITEM:9 CMD:10", + "PANON:2 PFILE:2 PSHMEM:2 VGROW:7 RGROW:8 SWAPSZ:5 " + "RUID:1 EUID:0 SORTITEM:9 CMD:10", "built-in memprocs"); make_proc_prints(schedprocs, MAXITEMS, diff --git a/showlinux.h b/showlinux.h index f275a82a..70030349 100644 --- a/showlinux.h +++ b/showlinux.h @@ -397,6 +397,9 @@ extern proc_printdef procprt_VSTEXT; extern proc_printdef procprt_VSIZE; extern proc_printdef procprt_RSIZE; extern proc_printdef procprt_PSIZE; +extern proc_printdef procprt_PANON; +extern proc_printdef procprt_PFILE; +extern proc_printdef procprt_PSHMEM; extern proc_printdef procprt_VSLIBS; extern proc_printdef procprt_VDATA; extern proc_printdef procprt_VSTACK; diff --git a/showprocs.c b/showprocs.c index f97628e3..985dd3b3 100644 --- a/showprocs.c +++ b/showprocs.c @@ -83,6 +83,12 @@ char *procprt_RSIZE_a(struct tstat *, int, int); char *procprt_RSIZE_e(struct tstat *, int, int); char *procprt_PSIZE_a(struct tstat *, int, int); char *procprt_PSIZE_e(struct tstat *, int, int); +char *procprt_PANON_a(struct tstat *, int, int); +char *procprt_PANON_e(struct tstat *, int, int); +char *procprt_PFILE_a(struct tstat *, int, int); +char *procprt_PFILE_e(struct tstat *, int, int); +char *procprt_PSHMEM_a(struct tstat *, int, int); +char *procprt_PSHMEM_e(struct tstat *, int, int); char *procprt_VSLIBS_a(struct tstat *, int, int); char *procprt_VSLIBS_e(struct tstat *, int, int); char *procprt_VDATA_a(struct tstat *, int, int); @@ -836,6 +842,69 @@ proc_printdef procprt_PSIZE = { " PSIZE", "PSIZE", procprt_PSIZE_a, procprt_PSIZE_e, 6 }; /***************************************************************/ char * +procprt_PANON_a(struct tstat *curstat, int avgval, int nsecs) +{ + static char buf[10]; + + if (curstat->mem.panon == (unsigned long long)-1LL) + return " ?K"; + + val2memstr(curstat->mem.panon*1024, buf, BFORMAT, 0, 0); + return buf; +} + +char * +procprt_PANON_e(struct tstat *curstat, int avgval, int nsecs) +{ + return " 0K"; +} + +proc_printdef procprt_PANON = + { " PANON", "PANON", procprt_PANON_a, procprt_PANON_e, 6 }; +/***************************************************************/ +char * +procprt_PFILE_a(struct tstat *curstat, int avgval, int nsecs) +{ + static char buf[10]; + + if (curstat->mem.pfile == (unsigned long long)-1LL) + return " ?K"; + + val2memstr(curstat->mem.pfile*1024, buf, BFORMAT, 0, 0); + return buf; +} + +char * +procprt_PFILE_e(struct tstat *curstat, int avgval, int nsecs) +{ + return " 0K"; +} + +proc_printdef procprt_PFILE = + { " PFILE", "PFILE", procprt_PFILE_a, procprt_PFILE_e, 6 }; +/***************************************************************/ +char * +procprt_PSHMEM_a(struct tstat *curstat, int avgval, int nsecs) +{ + static char buf[10]; + + if (curstat->mem.pshmem == (unsigned long long)-1LL) + return " ?K"; + + val2memstr(curstat->mem.pshmem*1024, buf, BFORMAT, 0, 0); + return buf; +} + +char * +procprt_PSHMEM_e(struct tstat *curstat, int avgval, int nsecs) +{ + return " 0K"; +} + +proc_printdef procprt_PSHMEM = + { "PSHMEM", "PSHMEM", procprt_PSHMEM_a, procprt_PSHMEM_e, 6 }; +/***************************************************************/ +char * procprt_VSLIBS_a(struct tstat *curstat, int avgval, int nsecs) { static char buf[10];