On Mon, Jun 19, 2023 at 05:40:04PM -0500, Scott Cheloha wrote: > This patch moves the profil(2)- and GPROF-specific parts of > statclock() out into their own dedicated clock interrupts. > > Test instructions will follow in a reply to this mail. This needs > testing on every platform. Please reply with dmesgs and results. > Non-amd64 results are greatly appreciated. > > [...]
Okay, here are the instructions. The profclock() piece should have no negative interactions with suspend/resume or hibernate/unhibernate, so even if you don't want to actively test the patch, passively testing the patch by leaving it applied to the kernel on your daily driver will help. That said, I want to stress the following: Suspend/resume and hibernate/unhibernate are NOT compatible with GPROF profiling. I assume there are many untested interactions between the two. Make sure to STOP all kernel profiling before attempting to suspend or hibernate your machine. Otherwise I expect it will hang. GPROF is a kernel compile-time option. If you don't enable it, you have nothing to worry about. -- To actively test either the profclock or the GPROF parts, first do the following: 1. Download and apply the work-in-progress moncontrol/gprof patch. The patch will make it much easier to test the profclock() parts. I sent the patch to tech@ recently: From: Scott Cheloha <scottcheloha () gmail ! com> Date: Mon, 19 Jun 2023 03:25:37 +0000 Subject: moncontrol(3), gprof(1): write, read gmon profiling data via utrace(2) Or get it from a list archive: $ PATCH_URL='https://marc.info/?l=openbsd-tech&m=168714523619637&q=raw' $ PATCH_PATH=/tmp/moncontrol-gprof-utrace.patch2 $ ftp -o $PATCH_PATH $PATCH_URL $ cd /usr/src $ patch -C < $PATCH_PATH && patch < $PATCH_PATH 2. Rebuild and reinstall both libc and gprof(1). $ cd /usr/src/lib/libc && doas make clean && doas make && doas make install $ cd /usr/src/usr.bin/gprof && doas make clean && doas make && doas make install -- To test the profclock() parts: 1. In one terminal, start systat(1). We'll use it to observe the clock interrupt rate. Note the baseline clock interrupt rate. It is usually about ((Number-of-online-CPUs) x 200). $ systat vmstat 2 2. Check your kernel's profhz. It's normally 1000, though there are exceptions. $ sysctl -n kern.clockrate tick = 10000, hz = 100, profhz = 1000, stathz = 100 ^^^^^^^^^^^^^ 3. In a second terminal, build a profiling binary, then run it with ktrace(1) to capture the profiling data. I will use md5(1) here because it is easy to eyeball-test. $ cd /usr/src/bin/md5 $ doas make clean $ doas make CFLAGS=-pg LDFLAGS='-pg -static' $ command time ktrace -f ktrace.md5.out1 -tu obj/md5 -ttt 4. Observe the clock interrupt rate in the first terminal. When the profiled process is onproc, the rate should increase by the profhz value from step (2). For example, if your baseline rate is ~1600 and your kernel's profhz is 1000, the rate should increase to ~2600. The md5(1) time trial is mostly userspace computation. On an otherwise idle system the clock interrupt rate should *stay* at that increased rate until the program exits. When the program exits, the clock interrupt rate should immediately return to the baseline rate from step (1). 5. Check the results with your patched gprof(1). If you're familiar with gprof(1)'s output, check that the output is reasonable. $ gprof obj/md5 ktrace.md5.out1 | less -- To test the GPROF part: 1. Build and install a GPROF kernel. This is briefly described in options(4). In short: first add the following to conf/GENERIC: makeoptions PROF="-pg" option GPROF Second: remake your kernel config. Last: clean, rebuild, install, and reboot. 2. After rebooting, you can double-check you're running a GPROF kernel by looking for "Profiling kernel" in your dmesg. $ dmesg | fgrep 'Profiling kernel' Profiling kernel, textsize=33858968 [ffffffff80000000..ffffffff8204a598] 3. In one terminal start systat(1) as described above for the profclock() testing in steps (1) and (2). Note the baseline interrupt rate, note your kernel's profhz value, etc. 4. In a second terminal, profile a CPU with kgmon(8). I'm going to use CPU 2 in this example. $ command time doas ksh -c "kgmon -c 2 -b && sleep 10 ; doas kgmon -c 2 -h -pr" kgmon: kernel profiling is running for cpu 2. kgmon: kernel profiling is off for cpu 2. 10.089 real 0.000 user 0.060 sys 4. Observe the clock interrupt rate in the first terminal. The rate should increase by the profhz value from step (2). For example, if your baseline rate is ~1600 and your kernel's profhz is 1000, the rate should increase to ~2600. A profiled CPU is always "running", so the clock interrupt rate should remain at that elevated value until profiling is stopped with kgmon(8). Once profiling has stopped, the clock interrupt rate should immediately return to the baseline rate from step (2). 5. Check the results with your patched gprof(1). Note that you need to use the '-g' flag to tell the patched gprof(1) that the input profiling file is raw gmon data. If you're familiar with GPROF kernel profiling, skim the output to see if it is reasonable. $ doas gprof -g /bsd.booted gmon-02.out | less