Download raw body.
dt: Continue read(2) from last read CPU ring
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
dt: Continue read(2) from last read CPU ring