kprof: don't downsample the pc

Kprof rounded the pc to 8 byte boundaries in order to save memory.
With x86 instruction rounding this can lead to some pretty misleading
results.

With the old rounding kpdata was ~680kb for a pc64 kernel, with this
change we use ~5.4M (8x) and considering we only allocate when we
first attach this seems reasonable.
This commit is contained in:
Jacob Moody 2025-01-05 00:26:52 +00:00
parent 4de9d8a511
commit 28465682cf
3 changed files with 5 additions and 11 deletions

View file

@ -24,10 +24,9 @@ The size of the file depends on the size of kernel text.
The first count The first count
holds the total number of clock ticks during profiling; holds the total number of clock ticks during profiling;
the second the number of ticks that occurred while the kernel the second the number of ticks that occurred while the kernel
was running. The rest each hold the number of ticks was running. The rest each hold the number of total ticks
the kernel program counter was within the the kernel spent at any one program counter, indexed by
corresponding 8-byte range of kernel text, starting from the base their offset from the minimum kernel text address.
of kernel text.
.PP .PP
The file The file
.B kpctl .B kpctl

View file

@ -6,7 +6,6 @@
#include "../port/error.h" #include "../port/error.h"
#define LRES 3 /* log of PC resolution */
#define SZ 4 /* sizeof of count cell; well known as 4 */ #define SZ 4 /* sizeof of count cell; well known as 4 */
struct struct
@ -46,7 +45,6 @@ _kproftimer(uintptr pc)
kprof.buf[0] += TK2MS(1); kprof.buf[0] += TK2MS(1);
if(kprof.minpc<=pc && pc<kprof.maxpc){ if(kprof.minpc<=pc && pc<kprof.maxpc){
pc -= kprof.minpc; pc -= kprof.minpc;
pc >>= LRES;
kprof.buf[pc] += TK2MS(1); kprof.buf[pc] += TK2MS(1);
}else }else
kprof.buf[1] += TK2MS(1); kprof.buf[1] += TK2MS(1);
@ -68,7 +66,7 @@ kprofattach(char *spec)
/* allocate when first used */ /* allocate when first used */
kprof.minpc = KTZERO; kprof.minpc = KTZERO;
kprof.maxpc = (uintptr)etext; kprof.maxpc = (uintptr)etext;
kprof.nbuf = (kprof.maxpc-kprof.minpc) >> LRES; kprof.nbuf = kprof.maxpc-kprof.minpc;
n = kprof.nbuf*SZ; n = kprof.nbuf*SZ;
if(kprof.buf == 0) { if(kprof.buf == 0) {
kprof.buf = xalloc(n); kprof.buf = xalloc(n);

View file

@ -3,8 +3,6 @@
#include <bio.h> #include <bio.h>
#include <mach.h> #include <mach.h>
#define PCRES 8
struct COUNTER struct COUNTER
{ {
char *name; /* function name */ char *name; /* function name */
@ -82,7 +80,7 @@ main(int argc, char *argv[])
data = malloc(d->length); data = malloc(d->length);
if(data == 0) if(data == 0)
error(1, "malloc"); error(1, "malloc");
if(read(fd, data, d->length) < 0) if(readn(fd, data, d->length) != d->length)
error(1, "text read"); error(1, "text read");
close(fd); close(fd);
for(i=0; i<n; i++) for(i=0; i<n; i++)
@ -112,7 +110,6 @@ main(int argc, char *argv[])
if (!textsym(&s, i)) /* get next symbol */ if (!textsym(&s, i)) /* get next symbol */
break; break;
s.value -= tbase; s.value -= tbase;
s.value /= PCRES;
sum = 0; sum = 0;
while (j < n && j < s.value) while (j < n && j < s.value)
sum += data[j++]; sum += data[j++];