Skip site navigation (1)Skip section navigation (2)
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>