[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <d5be177d-505d-4d72-9d18-913e69c23ea8@app.fastmail.com>
Date: Fri, 04 Jul 2025 12:09:38 +0200
From: "Arnd Bergmann" <arnd@...db.de>
To: "A. Sverdlin" <alexander.sverdlin@...mens.com>,
linux-kernel@...r.kernel.org
Cc: "Greg Kroah-Hartman" <gregkh@...uxfoundation.org>,
"Michael Walle" <mwalle@...nel.org>, "Hui Wang" <hui.wang@...onical.com>,
"Mark Brown" <broonie@...nel.org>
Subject: Re: [PATCH] eeprom: at25: convert to spi-mem API
On Thu, Jul 3, 2025, at 00:28, A. Sverdlin wrote:
> static int at25_ee_read(void *priv, unsigned int offset,
> void *val, size_t count)
> {
> + u8 *bounce __free(kfree) = kmalloc(min(count, io_limit), GFP_KERNEL);
> struct at25_data *at25 = priv;
> char *buf = val;
I see nothing wrong with your patch, but the added bounce buffer
reminds me or a general problem with such buffers in the SPI
layer (and a couple of other places like it).
The problem is that kmalloc() does not take into account the
DMA mask of the device, which can have two suboptimal outcomes:
- on builds without SWIOTLB/IOMMU and an SPI host that has a DMA
mask smaller than RAM, dma_map_sg() fails down the line,
so either the transfer will fail or fall back to MMIO mode
- when SWIOTLB is available, dma_map_sg() will succeed but
require another copy into a second bounce buffer.
There are various drivers that work around the problem by using
GFP_DMA instead of GFP_KERNEL. This should be reliable on all
platforms, but means that the allocation comes from a potentially
really small pool and is more likely to fail. Ideally I think we
should not do that any more at all but find another way to
allocate bounce buffers for SPI transfers. The two ideas I had
were:
a) and a generic interface to ask for a buffer that can be used
by an SPI bus driver for efficient transfers, with the SPI
core code making an informed decision on using either kmalloc()
or dma_alloc_noncoherent() based on the size of the transfer
and the DMA mask.
b) push down the bouncing into the SPI core, so you can just
pass buffers from anywhere (stack, vmalloc, ...) and
ask for the lower parts of the stack to copy these into
an appropriate buffer if necessary. For the spi mem API
I suppose that would require assigning a flag in
spi_mem_op->data.
Arnd
Powered by blists - more mailing lists