Date: Tue, 26 Sep 2023 19:08:39 +0100 From: Andrew Turner <andrew@fubar.geek.nz> To: John Baldwin <jhb@freebsd.org> Cc: "src-committers@freebsd.org" <src-committers@FreeBSD.org>, "dev-commits-src-all@freebsd.org" <dev-commits-src-all@FreeBSD.org>, "dev-commits-src-main@freebsd.org" <dev-commits-src-main@FreeBSD.org> Subject: Re: git: f1c5a2e3a625 - main - virtio_random: Pipeline fetching the data Message-ID: <8B2042EF-728E-4A8A-8878-640B3097191E@fubar.geek.nz> In-Reply-To: <202309051600.385G0Bmk031832@gitrepo.freebsd.org> References: <202309051600.385G0Bmk031832@gitrepo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Is there a plan to MFC this to 14? Without it I=E2=80=99m seeing 50% CPU = on a dual core arm64 Hetzner VM. Andrew > On 5 Sep 2023, at 17:00, John Baldwin <jhb@freebsd.org> wrote: >=20 > The branch main has been updated by jhb: >=20 > URL: = https://cgit.FreeBSD.org/src/commit/?id=3Df1c5a2e3a625053e2b70d5b1777d849a= 4d9328f2 >=20 > commit f1c5a2e3a625053e2b70d5b1777d849a4d9328f2 > Author: John-Mark Gurney <jmg@FreeBSD.org> > AuthorDate: 2023-09-05 15:59:43 +0000 > Commit: John Baldwin <jhb@FreeBSD.org> > CommitDate: 2023-09-05 15:59:43 +0000 >=20 > virtio_random: Pipeline fetching the data >=20 > Queue an initial fetch of data during attach and after every read > rather than synchronously fetching data and polling for completion. >=20 > If data has not been returned from an previous fetch during read, > just return EAGAIN rather than blocking. >=20 > Co-authored-by: John Baldwin <jhb@FreeBSD.org> >=20 > Reviewed by: markj > Differential Revision: https://reviews.freebsd.org/D41656 > --- > sys/dev/virtio/random/virtio_random.c | 73 = +++++++++++++++++++++-------------- > 1 file changed, 43 insertions(+), 30 deletions(-) >=20 > diff --git a/sys/dev/virtio/random/virtio_random.c = b/sys/dev/virtio/random/virtio_random.c > index c02b5c98cece..d54e2e6b70d4 100644 > --- a/sys/dev/virtio/random/virtio_random.c > +++ b/sys/dev/virtio/random/virtio_random.c > @@ -54,6 +54,8 @@ struct vtrnd_softc { > struct virtqueue *vtrnd_vq; > eventhandler_tag eh; > bool inactive; > + struct sglist *vtrnd_sg; > + uint32_t *vtrnd_value; > }; >=20 > static int vtrnd_modevent(module_t, int, void *); > @@ -67,6 +69,7 @@ static int vtrnd_negotiate_features(struct = vtrnd_softc *); > static int vtrnd_setup_features(struct vtrnd_softc *); > static int vtrnd_alloc_virtqueue(struct vtrnd_softc *); > static int vtrnd_harvest(struct vtrnd_softc *, void *, size_t *); > +static void vtrnd_enqueue(struct vtrnd_softc *sc); > static unsigned vtrnd_read(void *, unsigned); >=20 > #define VTRND_FEATURES 0 > @@ -138,12 +141,17 @@ static int > vtrnd_attach(device_t dev) > { > struct vtrnd_softc *sc, *exp; > + size_t len; > int error; >=20 > sc =3D device_get_softc(dev); > sc->vtrnd_dev =3D dev; > virtio_set_feature_desc(dev, vtrnd_feature_desc); >=20 > + len =3D sizeof(*sc->vtrnd_value) * HARVESTSIZE; > + sc->vtrnd_value =3D malloc_aligned(len, len, M_DEVBUF, = M_WAITOK); > + sc->vtrnd_sg =3D sglist_build(sc->vtrnd_value, len, M_WAITOK); > + > error =3D vtrnd_setup_features(sc); > if (error) { > device_printf(dev, "cannot setup features\n"); > @@ -174,6 +182,8 @@ vtrnd_attach(device_t dev) > sc->inactive =3D false; > random_source_register(&random_vtrnd); >=20 > + vtrnd_enqueue(sc); > + > fail: > if (error) > vtrnd_detach(dev); > @@ -185,6 +195,7 @@ static int > vtrnd_detach(device_t dev) > { > struct vtrnd_softc *sc; > + uint32_t rdlen; >=20 > sc =3D device_get_softc(dev); > KASSERT( > @@ -197,7 +208,13 @@ vtrnd_detach(device_t dev) > sc->eh =3D NULL; > } > random_source_deregister(&random_vtrnd); > + > + /* clear the queue */ > + virtqueue_poll(sc->vtrnd_vq, &rdlen); > + > atomic_store_explicit(&g_vtrnd_softc, NULL, = memory_order_release); > + sglist_free(sc->vtrnd_sg); > + zfree(sc->vtrnd_value, M_DEVBUF); > return (0); > } >=20 > @@ -251,49 +268,45 @@ vtrnd_alloc_virtqueue(struct vtrnd_softc *sc) > return (virtio_alloc_virtqueues(dev, 0, 1, &vq_info)); > } >=20 > +static void > +vtrnd_enqueue(struct vtrnd_softc *sc) > +{ > + struct virtqueue *vq; > + int error __diagused; > + > + vq =3D sc->vtrnd_vq; > + > + KASSERT(virtqueue_empty(vq), ("%s: non-empty queue", __func__)); > + > + error =3D virtqueue_enqueue(vq, sc, sc->vtrnd_sg, 0, 1); > + KASSERT(error =3D=3D 0, ("%s: virtqueue_enqueue returned error: = %d", > + __func__, error)); > + > + virtqueue_notify(vq); > +} > + > static int > vtrnd_harvest(struct vtrnd_softc *sc, void *buf, size_t *sz) > { > - struct sglist_seg segs[1]; > - struct sglist sg; > struct virtqueue *vq; > - uint32_t value[HARVESTSIZE] __aligned(sizeof(uint32_t) * = HARVESTSIZE); > + void *cookie; > uint32_t rdlen; > - int error; > - > - _Static_assert(sizeof(value) < PAGE_SIZE, "sglist assumption"); >=20 > if (sc->inactive) > return (EDEADLK); >=20 > - sglist_init(&sg, 1, segs); > - error =3D sglist_append(&sg, value, *sz); > - if (error !=3D 0) > - panic("%s: sglist_append error=3D%d", __func__, error); > - > vq =3D sc->vtrnd_vq; > - KASSERT(virtqueue_empty(vq), ("%s: non-empty queue", __func__)); > - > - error =3D virtqueue_enqueue(vq, buf, &sg, 0, 1); > - if (error !=3D 0) > - return (error); > - > - /* > - * Poll for the response, but the command is likely already > - * done when we return from the notify. > - */ > - virtqueue_notify(vq); > - virtqueue_poll(vq, &rdlen); >=20 > - if (rdlen > *sz) > - panic("%s: random device wrote %zu bytes beyond end of = provided" > - " buffer %p:%zu", __func__, (size_t)rdlen - *sz, > - (void *)value, *sz); > - else if (rdlen =3D=3D 0) > + cookie =3D virtqueue_dequeue(vq, &rdlen); > + if (cookie =3D=3D NULL) > return (EAGAIN); > + KASSERT(cookie =3D=3D sc, ("%s: cookie mismatch", __func__)); > + > *sz =3D MIN(rdlen, *sz); > - memcpy(buf, value, *sz); > - explicit_bzero(value, *sz); > + memcpy(buf, sc->vtrnd_value, *sz); > + > + vtrnd_enqueue(sc); > + > return (0); > } >=20 >=20
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?8B2042EF-728E-4A8A-8878-640B3097191E>