shithub: front

Download patch

ref: 28465682cf7707532583d3a386991b39c683ee1c
parent: 4de9d8a511c1403ef849147e82b54af3bdbd4e3e
author: Jacob Moody <moody@posixcafe.org>
date: Sat Jan 4 19:26:52 EST 2025

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.

--- a/sys/man/3/kprof
+++ b/sys/man/3/kprof
@@ -24,10 +24,9 @@
 The first count
 holds the total number of clock ticks during profiling;
 the second the number of ticks that occurred while the kernel
-was running.  The rest each hold the number of ticks
-the kernel program counter was within the
-corresponding 8-byte range of kernel text, starting from the base
-of kernel text.
+was running.  The rest each hold the number of total ticks
+the kernel spent at any one program counter, indexed by
+their offset from the minimum kernel text address.
 .PP
 The file
 .B kpctl
--- a/sys/src/9/port/devkprof.c
+++ b/sys/src/9/port/devkprof.c
@@ -6,7 +6,6 @@
 #include	"../port/error.h"
 
 
-#define	LRES	3		/* log of PC resolution */
 #define	SZ	4		/* sizeof of count cell; well known as 4 */
 
 struct
@@ -46,7 +45,6 @@
 	kprof.buf[0] += TK2MS(1);
 	if(kprof.minpc<=pc && pc<kprof.maxpc){
 		pc -= kprof.minpc;
-		pc >>= LRES;
 		kprof.buf[pc] += TK2MS(1);
 	}else
 		kprof.buf[1] += TK2MS(1);
@@ -68,7 +66,7 @@
 	/* allocate when first used */
 	kprof.minpc = KTZERO;
 	kprof.maxpc = (uintptr)etext;
-	kprof.nbuf = (kprof.maxpc-kprof.minpc) >> LRES;
+	kprof.nbuf = kprof.maxpc-kprof.minpc;
 	n = kprof.nbuf*SZ;
 	if(kprof.buf == 0) {
 		kprof.buf = xalloc(n);
--- a/sys/src/cmd/kprof.c
+++ b/sys/src/cmd/kprof.c
@@ -3,8 +3,6 @@
 #include <bio.h>
 #include <mach.h>
 
-#define	PCRES	8
-
 struct COUNTER
 {
 	char 	*name;		/* function name */
@@ -82,7 +80,7 @@
 	data = malloc(d->length);
 	if(data == 0)
 		error(1, "malloc");
-	if(read(fd, data, d->length) < 0)
+	if(readn(fd, data, d->length) != d->length)
 		error(1, "text read");
 	close(fd);
 	for(i=0; i<n; i++)
@@ -112,7 +110,6 @@
 		if (!textsym(&s, i))	/* get next symbol */
 			break;
 		s.value -= tbase;
-		s.value /= PCRES;
 		sum = 0;
 		while (j < n && j < s.value)
 			sum += data[j++];
--