Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Nov 2008 18:49:57 -0500
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-hackers@freebsd.org
Cc:        Patrick =?iso-8859-1?q?Lamaizi=E8re?= <patfbsd@davenulle.org>
Subject:   Re: problem with bus_dmamap_load_uio
Message-ID:  <200811031849.57232.jhb@freebsd.org>
In-Reply-To: <20081103215021.0412b7b2@baby-jane-lamaiziere-net.local>
References:  <20081103215021.0412b7b2@baby-jane-lamaiziere-net.local>

next in thread | previous in thread | raw e-mail | index | archive | help
On Monday 03 November 2008 03:50:21 pm Patrick Lamaizi=E8re wrote:
> Hello,
>=20
> (8-Current/i386)
>=20
> I've got a problem with bus_dmamap_load_uio(9). I want to use it to
> map an uio for DMA with the Geode security block (glxsb(4)).
>=20
> It works, i can make milions of crypto operations with cryptotest.
>=20
> But when (i guess, i'm not sure) the free memory becomes low,
> bus_dmamap_load_uio() fails with errno =3D=3D EFBIG.
>=20
> I can reproduce the problem by running "periodic daily", "dd
> if=3D/dev/zero of=3Dfoo", ...
>=20
> By sample i run into problems with Mem: 33M Active, 310M Inact, 82M
> Wired, 60M Buf, 69M Free.
>=20
> When it fails the uio is :
> uio_segflg =3D UIO_SYSSPACE
> uio_iovcnt =3D 1,=20
> totlen =3D 16384 (the total length for iov)
> uio_resid =3D 16384
>=20
> (i've got some failure with size between 4000 and 16384)
>=20
> I don't understand why bus_dmamap_load_uio() cannot load the uio. Also
> when it fails, i copy the uio into a buffer and then a
> bus_dmamap_load() of the buffer always works.
>=20
> The dma tag is allocated with:
>=20
> bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),/* parent */
>  16, 0,                   /* alignments, bounds */
>  BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
>  BUS_SPACE_MAXADDR,       /* highaddr */
>  NULL, NULL,              /* filter, filterarg */
>  16384,                   /* maxsize */
>  1,                       /* nsegments */
>  16384,                   /* maxsegsize */
>  BUS_DMA_ALLOCNOW,        /* flags */
>  NULL, NULL,              /* lockfunc, lockarg */
>  &sc->sc_dmat);
>=20
> The dma map is created just before the bus_dmamap_load_uio() and
> destroyed later.
>=20
> (source : http://user.lamaiziere.net/patrick/glxsb.c , see
> glxsb_crypto_encdec() ).
>=20
> I'm trying to understand and fix this problem for several days, so any
> idea will be very cool...

Your dma tag only allows a single scatter/gather entry (nsegments).  What i=
s=20
happening is that under memory pressure, the virtual buffer in userland is=
=20
not built from physically contiguous pages, so you would need multiple s/g=
=20
entries to describe the buffer.  Hence EFBIG.  If your hardware can handle=
=20
multiple s/g entries, then just increase 'nsegments' and handle the multipl=
e=20
segments in your callback routine.

=2D-=20
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200811031849.57232.jhb>