[PATCH V3 15/16] i3c: mipi-i3c-hci: Consolidate DMA ring allocation

Frank Li Frank.li at nxp.com
Tue May 12 11:15:02 PDT 2026


On Mon, May 04, 2026 at 02:33:51PM +0300, Adrian Hunter wrote:
> dma_alloc_coherent() allocates memory in whole pages, which can waste
> space when command and response queues are allocated separately.
>
> Allocate the DMA command and response queues from a single coherent
> allocation instead, while preserving the required 4-byte alignment.
>
> This reduces memory overhead without changing behavior.
>
> Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
> ---
>
>
> Changes in V3:
>
> 	None
>
> Changes in V2:
>
> 	Check for failed allocation before assignments to avoid doing
> 	arithmetic with NULL pointers
>
>
>  drivers/i3c/master/mipi-i3c-hci/dma.c | 24 +++++++++++-------------
>  1 file changed, 11 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c
> index 6440302c63ca..4029d4d9e784 100644
> --- a/drivers/i3c/master/mipi-i3c-hci/dma.c
> +++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
> @@ -186,14 +186,12 @@ static void hci_dma_free(void *data)
>  	for (int i = 0; i < rings->total; i++) {
>  		rh = &rings->headers[i];
>
> -		if (rh->xfer)
> -			dma_free_coherent(rings->sysdev,
> -					  rh->xfer_struct_sz * rh->xfer_entries,
> -					  rh->xfer, rh->xfer_dma);
> -		if (rh->resp)
> -			dma_free_coherent(rings->sysdev,
> -					  rh->resp_struct_sz * rh->xfer_entries,
> -					  rh->resp, rh->resp_dma);
> +		if (rh->xfer) {
> +			size_t sz = round_up(rh->xfer_struct_sz * rh->xfer_entries, 4);
> +
> +			sz += rh->resp_struct_sz * rh->xfer_entries;
> +			dma_free_coherent(rings->sysdev, sz, rh->xfer, rh->xfer_dma);

Good cleanup. can you save sz into rh when alloc it?

Frank

> +		}
>  		kfree(rh->src_xfers);
>  		if (rh->ibi_status)
>  			dma_free_coherent(rings->sysdev,
> @@ -359,18 +357,18 @@ static int hci_dma_init(struct i3c_hci *hci)
>  		dev_dbg(&hci->master.dev,
>  			"xfer_struct_sz = %d, resp_struct_sz = %d",
>  			rh->xfer_struct_sz, rh->resp_struct_sz);
> -		xfers_sz = rh->xfer_struct_sz * rh->xfer_entries;
> +		xfers_sz = round_up(rh->xfer_struct_sz * rh->xfer_entries, 4);
>  		resps_sz = rh->resp_struct_sz * rh->xfer_entries;
>
> -		rh->xfer = dma_alloc_coherent(rings->sysdev, xfers_sz,
> +		rh->xfer = dma_alloc_coherent(rings->sysdev, xfers_sz + resps_sz,
>  					      &rh->xfer_dma, GFP_KERNEL);
> -		rh->resp = dma_alloc_coherent(rings->sysdev, resps_sz,
> -					      &rh->resp_dma, GFP_KERNEL);
>  		rh->src_xfers =
>  			kzalloc_objs(*rh->src_xfers, rh->xfer_entries);
>  		ret = -ENOMEM;
> -		if (!rh->xfer || !rh->resp || !rh->src_xfers)
> +		if (!rh->xfer || !rh->src_xfers)
>  			goto err_out;
> +		rh->resp = rh->xfer + xfers_sz;
> +		rh->resp_dma = rh->xfer_dma + xfers_sz;
>
>  		/* IBIs */
>
> --
> 2.51.0
>



More information about the linux-i3c mailing list