Index | Thread | Search

From:
Christian Ludwig <cludwig@genua.de>
Subject:
dt: Continue read(2) from last read CPU ring
To:
<tech@openbsd.org>
Date:
Sun, 15 Sep 2024 21:42:08 +0200

Download raw body.

Thread
Hi,

on top of the diff to use one ringbuffer per CPU in dt(4) ([1]), we can
easily reduce starvation of buffers for higher CPUs.

[1] https://marc.info/?l=openbsd-tech&m=172606806422278

When btrace continues reading events from busy ringbuffers, it always
starts reading the first buffers. But it might never reach the later
ones if the first ones fill up quickly.

Remeber the position and continue from the last ringbuffer that we read
before.

So long,


 - Christian

---
 sys/dev/dt/dt_dev.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sys/dev/dt/dt_dev.c b/sys/dev/dt/dt_dev.c
index 8adb165662e6..c0357239b98e 100644
--- a/sys/dev/dt/dt_dev.c
+++ b/sys/dev/dt/dt_dev.c
@@ -111,6 +111,7 @@ struct dt_ringbuf {
  *  Locks used to protect struct members in this file:
  *	a	atomic
  *	K	kernel lock
+ *	r	owned by read(2) proc
  *	I	invariant after initialization
  */
 struct dt_softc {
@@ -124,6 +125,7 @@ struct dt_softc {
 	unsigned int		 ds_evtcnt;	/* [a] # of readable evts */
 
 	struct dt_ringbuf	 ds_ring[MAXCPUS]; /* [I] event rings */
+	unsigned int		 ds_lastcpu;	/* [r] last CPU ring read(2). */
 
 	/* Counters */
 	unsigned int		 ds_readevt;	/* [a] # of events read */
@@ -220,6 +222,7 @@ dtopen(dev_t dev, int flags, int mode, struct proc *p)
 	sc->ds_unit = unit;
 	sc->ds_pid = p->p_p->ps_pid;
 	TAILQ_INIT(&sc->ds_pcbs);
+	sc->ds_lastcpu = 0;
 	sc->ds_evtcnt = 0;
 	sc->ds_readevt = 0;
 	sc->ds_dropevt = 0;
@@ -290,7 +293,7 @@ dtread(dev_t dev, struct uio *uio, int flags)
 	KERNEL_ASSERT_LOCKED();
 	for (i = 0; i < ncpusfound; i++) {
 		count = 0;
-		dr = &sc->ds_ring[i];
+		dr = &sc->ds_ring[(sc->ds_lastcpu + i) % ncpusfound];
 		error = dt_ring_copy(dr, uio, max, &count, &dropped);
 		if (error && count == 0)
 			break;
@@ -300,6 +303,7 @@ dtread(dev_t dev, struct uio *uio, int flags)
 		if (max == 0)
 			break;
 	}
+	sc->ds_lastcpu += i % ncpusfound;
 
 	atomic_add_int(&sc->ds_readevt, read);
 	atomic_add_int(&sc->ds_dropevt, dropped);
-- 
2.34.1