Skip to content

bcm23835-sdhost driver causes swiotlb allocation errors on Pi 4 #6589

Closed
@P33M

Description

@P33M

Describe the bug

With this overlay

/dts-v1/;
/plugin/;

/ {
	compatible = "brcm,bcm2711";
	fragment@0 {
		target = <&sdhost>;
		frag0: __overlay__ {
			pinctrl-names = "default";
			pinctrl-0 = <&sdhost_pins>;
			bus-width = <4>;
			brcm,overclock-50 = <0>;
			brcm,pio-limit = <1>;
			status = "okay";
		};
	};

	fragment@1 {
		target = <&gpio>;
		__overlay__ {
			sdhost_pins: sdhost_pins {
				brcm,pins = <22 23 24 25 26 27>;
				brcm,function = <4 4 4 4 4 4>; /* ALT0: SD0 */
				brcm,pull = <0 2 2 2 2 2>; /* pull up all except clk */
			};
		};
	};

	__overrides__ {
		overclock_50 = <&frag0>,"brcm,overclock-50:0";
		force_pio = <&frag0>,"brcm,force-pio?";
		pio_limit = <&frag0>,"brcm,pio-limit:0";
		debug = <&frag0>,"brcm,debug?";
	};
};

used on a Pi 4, and an SD card connected to gpio 22-27, any appreciable IO results in:

[   46.291378] bcm2835-dma fe007000.dma-controller: swiotlb buffer is full (sz: 524276 bytes), total 32768 (slots), used 0 (slots)
[   46.313899] bcm2835-dma fe007000.dma-controller: swiotlb buffer is full (sz: 524276 bytes), total 32768 (slots), used 0 (slots)
[   46.336214] bcm2835-dma fe007000.dma-controller: swiotlb buffer is full (sz: 524276 bytes), total 32768 (slots), used 0 (slots)
[   46.446096] bcm2835-dma fe007000.dma-controller: swiotlb buffer is full (sz: 524276 bytes), total 32768 (slots), used 0 (slots)
[   46.468661] bcm2835-dma fe007000.dma-controller: swiotlb buffer is full (sz: 524276 bytes), total 32768 (slots), used 0 (slots)
[   46.490984] bcm2835-dma fe007000.dma-controller: swiotlb buffer is full (sz: 524276 bytes), total 32768 (slots), used 0 (slots)
[   46.491013] I/O error, dev mmcblk2, sector 8192 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 2
[   46.512839] I/O error, dev mmcblk2, sector 9216 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 2
[   46.556441] bcm2835-dma fe007000.dma-controller: swiotlb buffer is full (sz: 524276 bytes), total 32768 (slots), used 0 (slots)
[   46.579009] bcm2835-dma fe007000.dma-controller: swiotlb buffer is full (sz: 524276 bytes), total 32768 (slots), used 0 (slots)
[   46.689279] bcm2835-dma fe007000.dma-controller: swiotlb buffer is full (sz: 524276 bytes), total 32768 (slots), used 0 (slots)
[   46.711121] I/O error, dev mmcblk2, sector 10240 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 2
[   46.754038] bcm2835-dma fe007000.dma-controller: swiotlb buffer is full (sz: 524276 bytes), total 32768 (slots), used 0 (slots)
[   46.908680] I/O error, dev mmcblk2, sector 11264 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 2
[   47.106815] I/O error, dev mmcblk2, sector 12288 op 0x0:(READ) flags 0x80700 phys_seg 30 prio class 2
[   47.304901] I/O error, dev mmcblk2, sector 13312 op 0x0:(READ) flags 0x80700 phys_seg 2 prio class 2
[   47.502801] I/O error, dev mmcblk2, sector 14336 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 2
[   47.700807] I/O error, dev mmcblk2, sector 15360 op 0x0:(READ) flags 0x80700 phys_seg 2 prio class 2
[   47.899218] I/O error, dev mmcblk2, sector 16384 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 2
[   48.097484] I/O error, dev mmcblk2, sector 17408 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 2

This also appears to leak swiotlb allocations as other peripherals requiring bounce buffers can't make forward progress (i.e. mmc0). A sentinel count on dma_map_sg / dma_unmap_sg pairings increases quickly.

This patch applied to the downstream variant of the driver prevents allocation errors. Several other changes have been made to the upstream driver around various other kernel API calls in the meantime.

git show d4dd9bccf4854cc6ed853b2b73d5afd8707cff20
commit d4dd9bccf4854cc6ed853b2b73d5afd8707cff20
Author: Stefan Wahren <[email protected]>
Date:   Sat Aug 24 08:31:04 2019 +0200

    mmc: bcm2835: Take SWIOTLB memory size limitation into account

    Make sure the sdhost driver doesn't use requests bigger than SWIOTLB
    can handle.

    Signed-off-by: Stefan Wahren <[email protected]>
    Signed-off-by: Ulf Hansson <[email protected]>

diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index e1b7757c48fe..7c30d79a9fdd 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -1314,7 +1314,7 @@ static int bcm2835_add_host(struct bcm2835_host *host)
        }

        mmc->max_segs = 128;
-       mmc->max_req_size = 524288;
+       mmc->max_req_size = min_t(size_t, 524288, dma_max_mapping_size(dev));
        mmc->max_seg_size = mmc->max_req_size;
        mmc->max_blk_size = 1024;
        mmc->max_blk_count =  65535;

Steps to reproduce the behaviour

dd if=/dev/mmcblk2 of=/dev/null bs=8M status=progress

Device (s)

Raspberry Pi 4 Mod. B

System

Linux foresee 6.6.69-v8+ #7 SMP PREEMPT Wed Jan 8 10:20:58 GMT 2025 aarch64 GNU/Linux - top of rpi-6.6.y

Logs

No response

Additional context

git log ../drivers/mmc/host/bcm2835.c vs git log ../drivers/mmc/host/bcm2835-sdhost.c

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions