git: b7761f1f0830 - main - x86/busdma: Limit reserved pages if low nsegs

From: Colin Percival <cperciva_at_FreeBSD.org>
Date: Sat, 22 Oct 2022 05:48:23 UTC
The branch main has been updated by cperciva:

URL: https://cgit.FreeBSD.org/src/commit/?id=b7761f1f0830fc4b4bd7a1f9f364cfb39b7f4288

commit b7761f1f0830fc4b4bd7a1f9f364cfb39b7f4288
Author:     Colin Percival <cperciva@FreeBSD.org>
AuthorDate: 2022-10-21 18:13:36 +0000
Commit:     Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2022-10-22 05:47:33 +0000

    x86/busdma: Limit reserved pages if low nsegs
    
    When bus_dmamap_create is called, if bouncing might be required we
    reserve enough pages for a maximum-length request, subject to the
    MAX_BPAGES constraint (32 MB on amd64; 32 MB or 2 MB on i386
    depending on the amount of RAM).
    
    Since pages used for bouncing are typically non-consecutive, each
    bounced page will typically constitute a busdma segment; as such, we
    are unlikely to ever successfully use more pages than the nsegments
    limit.  Limit the number of pages reserved to nsegments.
    
    On FreeBSD/Firecracker, this reduces bounce page memory consumption
    from 32 MB to 512 kB, making VMs with 128 MB of RAM usable.
    
    Reviewed by:    imp, mav
    Sponsored by:   https://www.patreon.com/cperciva
    Differential Revision:  https://reviews.freebsd.org/D37082
---
 sys/x86/x86/busdma_bounce.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/x86/x86/busdma_bounce.c b/sys/x86/x86/busdma_bounce.c
index faed4b7353cc..cf919c01ca64 100644
--- a/sys/x86/x86/busdma_bounce.c
+++ b/sys/x86/x86/busdma_bounce.c
@@ -325,6 +325,7 @@ bounce_bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
 		if ((dmat->bounce_flags & BUS_DMA_MIN_ALLOC_COMP) == 0 ||
 		    (bz->map_count > 0 && bz->total_bpages < maxpages)) {
 			pages = MAX(atop(dmat->common.maxsize), 1);
+			pages = MIN(dmat->common.nsegments, pages);
 			pages = MIN(maxpages - bz->total_bpages, pages);
 			pages = MAX(pages, 1);
 			if (alloc_bounce_pages(dmat, pages) < pages)