Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 May 2018 08:10:29 -0600
From:      Warner Losh <imp@bsdimp.com>
To:        Pratyush Yadav <pratyush@freebsd.org>
Cc:        "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>, Akshay Jaggi <jaggi@freebsd.org>, Edward Napierala <trasz@freebsd.org>
Subject:   Re: Why is there no bus_dmamap_load_sg()?
Message-ID:  <CANCZdfrt6eCVx3MAO=qLM5gXjSbx4hzGXQdePHgtktjFKWJA8g@mail.gmail.com>
In-Reply-To: <CA%2BX=3TK_v2Sby0fP57XB2T2WQpJ6mebE4doF6AiVJNHYHxPU8A@mail.gmail.com>
References:  <CA%2BX=3TK_v2Sby0fP57XB2T2WQpJ6mebE4doF6AiVJNHYHxPU8A@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, May 26, 2018 at 3:07 AM, Pratyush Yadav <pratyush@freebsd.org>
wrote:

> I was looking at the man page and I notice the function
> bus_dmamap_load_mbuf_sg() which directly returns the segment array to
> the client. But a similar variant of bus_dmamap_load() is missing.
> This variant would be useful to me and help me in my work.
>
> Is there a reason the sg variant was only implemented for mbufs?
>
> I was looking at the code in sys/kern/subr_bus_dma.c and a
> bus_dmamap_load_sg() does not look too difficult to implement. Is it
> ok if I submit a patch implementing it?
>

The biggest reason is because of the failure modes. If there's not
sufficient memory or other resources to honor the request, we defer until
there is such memory / resources and then call the callback. There's no
convenient hook the drivers can connect to so they can retry the allocation
when memory becomes available (busdma has one since eventually a request
will complete and unload). The original port was for CAM SIMs which had
stringent requirements to always make progress on I/Os to avoid deadlock.
Rather than put this tricky code in all the CAM SIMs, it's centralized to
retry as soon and as robustly as it can.

Network drivers, however, don't have such requirements and often don't
care. If they can't load a map, they can put the packet back on the
transmit queue (or whatever), set a flag and return without putting it into
the NIC's buffer rings. Eventually, a packet will finish transmitting and
there will be a chance to send it again (or one of a number of other
events, I'm glossing heavily here). It's a better fit for network drivers
than storage drivers. Since bus_dmamap_load_mbuf* is used only for network
drivers, it makes sense.

So, it would only make sense to add if you can cope with BUS_DMA_NOWAIT
always, and that error handling is simpler than letting busdma call you
back when the shortage is over. Is that the case for your port? Or is it
just because OpenBSD doesn't have this sort of interface (the callback
difference dates back to the initial port to FreeBSD by Justin Gibbs
because it never got folded back into NetBSD for reasons too long, too old
and only half remembered by me for this post)? Can the code you are porting
cope with error returns and retry again later?

Warner



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