From nobody Mon Feb 9 09:08:21 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1631D34E767; Wed, 17 Dec 2025 17:17:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765991823; cv=none; b=CJUjnqkhQO7KP/wSzjPOiR9XjTeQC1UTnCi5m1VCVkAM+j8ZXjuOWExT7FxRaH8A9F+sFu7QpI2+ej5nQsfI1ThqB5mPXW3Q5Z0KpbjkNLTTJwqwzsbNT7LuU1a99IqKspQi9waKJlCSD6b/C84b50Ptnm8+DMrdymPe/KAsVGY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765991823; c=relaxed/simple; bh=D9mjfpiYZhHFYL/jxvLs//6LcVyOqBcxPmmPuXGrSWY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=a60xgIm3DQ39F84mXH28szA5amCmdyLtQfum7s+IFp14KV4XypzkkzqTVBs2HNpihjCuGXroBMPjDBPHGOYKCkb9Xb3xceEy3hWlqj3CDYtrFe6STUbGoWKL1jgja7g7OMd8b6PZSycYafeNLn8CygEaimY3YF5uPCuoLwsUpbE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AjK+fk88; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="AjK+fk88" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7CA98C4CEFB; Wed, 17 Dec 2025 17:17:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765991821; bh=D9mjfpiYZhHFYL/jxvLs//6LcVyOqBcxPmmPuXGrSWY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=AjK+fk88KZCB4UdsRj8XqH3SGoIAOPnOEV0WjiBlrYCuy5AKiM+mNs67cBIJxDTbz 9pUAPER1VIdVlksRmWGqk4mXub0QRY/v2d178q3BEMHHR1a/p8F41ipNUaaz9USLlj 1HhkVy8B94SSlLHVUlfxtNqBqd2hxGjqwXnjR6fhR0xXlpn9UDnmgKhK4R3jiUNUr4 uVWIbmrqQ0hIgyR16BIIEechbzEYB+LrHRJeE7T32iCeYo5mYQj/pKCHEu0U3AF1I9 3bYzq9Lr6t2ysZAikkjzi7WGttSpW6lPENOoHMpWTrWBXDT6KRdBP7xPTwco9yOSj4 FB9XCisDBXmOg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69A1DD65C7C; Wed, 17 Dec 2025 17:17:01 +0000 (UTC) From: Manivannan Sadhasivam via B4 Relay Date: Wed, 17 Dec 2025 22:46:51 +0530 Subject: [PATCH 1/2] net: qrtr: Drop the MHI auto_queue feature for IPCR DL channels Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251217-qrtr-fix-v1-1-f6142a3ec9d8@oss.qualcomm.com> References: <20251217-qrtr-fix-v1-0-f6142a3ec9d8@oss.qualcomm.com> In-Reply-To: <20251217-qrtr-fix-v1-0-f6142a3ec9d8@oss.qualcomm.com> To: Jeff Hugo , Carl Vanderlip , Oded Gabbay , Manivannan Sadhasivam , Jeff Johnson , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Greg Kroah-Hartman , Loic Poulain , Maxim Kochetkov Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, mhi@lists.linux.dev, linux-wireless@vger.kernel.org, ath11k@lists.infradead.org, ath12k@lists.infradead.org, netdev@vger.kernel.org, Bjorn Andersson , Johan Hovold , Chris Lew , Manivannan Sadhasivam , stable@vger.kernel.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=20147; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=dQru8emq7l4R6ZFlI2xgYlVfmbAOsm/CMdY/HLWVQI0=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBpQuWLP/zozMrAaXXoQ35wf1LfhQ2+NqmUWzr+U MXSE1CQ7bKJATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaULliwAKCRBVnxHm/pHO 9aFOB/9m311UhCvvsWGsh4mqGvw0rrwy2m7dES2rvKZ4m6GUyrJSxxSiw5yqdiR5FqnXszRuAwi kWCkuv/yOhQJtU8Yc9LDrdHmHTlYIiNlgXuXlJNcHP9fToyFiYOqfOGfoYrJ+2rFcNMr9CYe3ll rWelCHbkz0xPVdK7HmJ1owqek3OnnrElt97DmndpX0gBcNpr3P2wJv9OnJit5BbU6H3KLjIYpjd ytqtH9VS6w1tL1xUu+o6r1rTO+Nsufa48n9RrZo9L1yQqJG5SdLdVvI+XU2/F7so5RcUEgwuqj9 BhPS5TM1KiT8t4793LP8sgOzbkLJmff3790Qssj76FokhDed X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 X-Endpoint-Received: by B4 Relay for manivannan.sadhasivam@oss.qualcomm.com/default with auth_id=461 X-Original-From: Manivannan Sadhasivam Reply-To: manivannan.sadhasivam@oss.qualcomm.com From: Manivannan Sadhasivam MHI stack offers the 'auto_queue' feature, which allows the MHI stack to auto queue the buffers for the RX path (DL channel). Though this feature simplifies the client driver design, it introduces race between the client drivers and the MHI stack. For instance, with auto_queue, the 'dl_callback' for the DL channel may get called before the client driver is fully probed. This means, by the time the dl_callback gets called, the client driver's structures might not be initialized, leading to NULL ptr dereference. Currently, the drivers have to workaround this issue by initializing the internal structures before calling mhi_prepare_for_transfer_autoqueue(). But even so, there is a chance that the client driver's internal code path may call the MHI queue APIs before mhi_prepare_for_transfer_autoqueue() is called, leading to similar NULL ptr dereference. This issue has been reported on the Qcom X1E80100 CRD machines affecting boot. So to properly fix all these races, drop the MHI 'auto_queue' feature altogether and let the client driver (QRTR) manage the RX buffers manually. In the QRTR driver, queue the RX buffers based on the ring length during probe and recycle the buffers in 'dl_callback' once they are consumed. This also warrants removing the setting of 'auto_queue' flag from controller drivers. Currently, this 'auto_queue' feature is only enabled for IPCR DL channel. So only the QRTR client driver requires the modification. Cc: stable@vger.kernel.org Fixes: 227fee5fc99e ("bus: mhi: core: Add an API for auto queueing buffers = for DL channel") Fixes: 68a838b84eff ("net: qrtr: start MHI channel after endpoit creation") Reported-by: Johan Hovold Closes: https://lore.kernel.org/linux-arm-msm/ZyTtVdkCCES0lkl4@hovoldconsul= ting.com Suggested-by: Chris Lew Signed-off-by: Manivannan Sadhasivam Acked-by: Jeff Johnson # drivers/net/wireless/ath/... --- drivers/accel/qaic/mhi_controller.c | 44 ----------------------- drivers/bus/mhi/host/pci_generic.c | 20 ++--------- drivers/net/wireless/ath/ath11k/mhi.c | 4 --- drivers/net/wireless/ath/ath12k/mhi.c | 4 --- net/qrtr/mhi.c | 67 +++++++++++++++++++++++++++++--= ---- 5 files changed, 58 insertions(+), 81 deletions(-) diff --git a/drivers/accel/qaic/mhi_controller.c b/drivers/accel/qaic/mhi_c= ontroller.c index 13a14c6c6168..4d787f77ce41 100644 --- a/drivers/accel/qaic/mhi_controller.c +++ b/drivers/accel/qaic/mhi_controller.c @@ -39,7 +39,6 @@ static const struct mhi_channel_config aic100_channels[] = =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -55,7 +54,6 @@ static const struct mhi_channel_config aic100_channels[] = =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -71,7 +69,6 @@ static const struct mhi_channel_config aic100_channels[] = =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -87,7 +84,6 @@ static const struct mhi_channel_config aic100_channels[] = =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -103,7 +99,6 @@ static const struct mhi_channel_config aic100_channels[]= =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -119,7 +114,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -135,7 +129,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -151,7 +144,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -167,7 +159,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -183,7 +174,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -199,7 +189,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -215,7 +204,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -231,7 +219,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -247,7 +234,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -263,7 +249,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -279,7 +264,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -295,7 +279,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -311,7 +294,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -327,7 +309,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -343,7 +324,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -359,7 +339,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -375,7 +354,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -391,7 +369,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -407,7 +384,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -423,7 +399,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -439,7 +414,6 @@ static const struct mhi_channel_config aic100_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, .wake_capable =3D false, }, }; @@ -458,7 +432,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -474,7 +447,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -490,7 +462,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -506,7 +477,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -522,7 +492,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -538,7 +507,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -554,7 +522,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -570,7 +537,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -586,7 +552,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -602,7 +567,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -618,7 +582,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -634,7 +597,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -650,7 +612,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -666,7 +627,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -682,7 +642,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -698,7 +657,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -714,7 +672,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, .wake_capable =3D false, }, { @@ -730,7 +687,6 @@ static const struct mhi_channel_config aic200_channels[= ] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, .wake_capable =3D false, }, }; diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_= generic.c index e3bc737313a2..0884a384b77f 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -94,22 +94,6 @@ struct mhi_pci_dev_info { .doorbell_mode_switch =3D false, \ } =20 -#define MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(ch_num, ch_name, el_count, ev_ring= ) \ - { \ - .num =3D ch_num, \ - .name =3D ch_name, \ - .num_elements =3D el_count, \ - .event_ring =3D ev_ring, \ - .dir =3D DMA_FROM_DEVICE, \ - .ee_mask =3D BIT(MHI_EE_AMSS), \ - .pollcfg =3D 0, \ - .doorbell =3D MHI_DB_BRST_DISABLE, \ - .lpm_notify =3D false, \ - .offload_channel =3D false, \ - .doorbell_mode_switch =3D false, \ - .auto_queue =3D true, \ - } - #define MHI_EVENT_CONFIG_CTRL(ev_ring, el_count) \ { \ .num_elements =3D el_count, \ @@ -329,7 +313,7 @@ static const struct mhi_channel_config modem_qcom_v1_mh= i_channels[] =3D { MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0), MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0), MHI_CHANNEL_CONFIG_UL(20, "IPCR", 8, 0), - MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 8, 0), + MHI_CHANNEL_CONFIG_DL(21, "IPCR", 8, 0), MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0), MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0), MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 64, 2), @@ -762,7 +746,7 @@ static const struct mhi_channel_config mhi_telit_fn980_= hw_v1_channels[] =3D { MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0), MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0), MHI_CHANNEL_CONFIG_UL(20, "IPCR", 16, 0), - MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 16, 0), + MHI_CHANNEL_CONFIG_DL(21, "IPCR", 16, 0), MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 1), MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 2), }; diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/a= th/ath11k/mhi.c index acd76e9392d3..d2c44f7f9b62 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -34,7 +34,6 @@ static const struct mhi_channel_config ath11k_mhi_channel= s_qca6390[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, }, { .num =3D 21, @@ -48,7 +47,6 @@ static const struct mhi_channel_config ath11k_mhi_channel= s_qca6390[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, }, }; =20 @@ -99,7 +97,6 @@ static const struct mhi_channel_config ath11k_mhi_channel= s_qcn9074[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, }, { .num =3D 21, @@ -113,7 +110,6 @@ static const struct mhi_channel_config ath11k_mhi_chann= els_qcn9074[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, }, }; =20 diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/a= th/ath12k/mhi.c index 08f44baf182a..2dbdb95ae7be 100644 --- a/drivers/net/wireless/ath/ath12k/mhi.c +++ b/drivers/net/wireless/ath/ath12k/mhi.c @@ -31,7 +31,6 @@ static const struct mhi_channel_config ath12k_mhi_channel= s_qcn9274[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, }, { .num =3D 21, @@ -45,7 +44,6 @@ static const struct mhi_channel_config ath12k_mhi_channel= s_qcn9274[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, }, }; =20 @@ -96,7 +94,6 @@ static const struct mhi_channel_config ath12k_mhi_channel= s_wcn7850[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D false, }, { .num =3D 21, @@ -110,7 +107,6 @@ static const struct mhi_channel_config ath12k_mhi_chann= els_wcn7850[] =3D { .lpm_notify =3D false, .offload_channel =3D false, .doorbell_mode_switch =3D false, - .auto_queue =3D true, }, }; =20 diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c index 69f53625a049..0b4d181ea747 100644 --- a/net/qrtr/mhi.c +++ b/net/qrtr/mhi.c @@ -24,13 +24,25 @@ static void qcom_mhi_qrtr_dl_callback(struct mhi_device= *mhi_dev, struct qrtr_mhi_dev *qdev =3D dev_get_drvdata(&mhi_dev->dev); int rc; =20 - if (!qdev || mhi_res->transaction_status) + if (!qdev || (mhi_res->transaction_status && mhi_res->transaction_status = !=3D -ENOTCONN)) return; =20 + /* Channel got reset. So just free the buffer */ + if (mhi_res->transaction_status =3D=3D -ENOTCONN) { + devm_kfree(&mhi_dev->dev, mhi_res->buf_addr); + return; + } + rc =3D qrtr_endpoint_post(&qdev->ep, mhi_res->buf_addr, mhi_res->bytes_xferd); if (rc =3D=3D -EINVAL) dev_err(qdev->dev, "invalid ipcrouter packet\n"); + + /* Done with the buffer, now recycle it for future use */ + rc =3D mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, mhi_res->buf_addr, + mhi_dev->mhi_cntrl->buffer_len, MHI_EOT); + if (rc) + dev_err(&mhi_dev->dev, "Failed to recycle the buffer: %d\n", rc); } =20 /* From QRTR to MHI */ @@ -72,6 +84,27 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, = struct sk_buff *skb) return rc; } =20 +static int qcom_mhi_qrtr_queue_dl_buffers(struct mhi_device *mhi_dev) +{ + void *buf; + int ret; + + while (!mhi_queue_is_full(mhi_dev, DMA_FROM_DEVICE)) { + buf =3D devm_kmalloc(&mhi_dev->dev, mhi_dev->mhi_cntrl->buffer_len, GFP_= KERNEL); + if (!buf) + return -ENOMEM; + + ret =3D mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, buf, mhi_dev->mhi_cntrl-= >buffer_len, + MHI_EOT); + if (ret) { + dev_err(&mhi_dev->dev, "Failed to queue buffer: %d\n", ret); + return ret; + } + } + + return 0; +} + static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id) { @@ -87,20 +120,30 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_= dev, qdev->ep.xmit =3D qcom_mhi_qrtr_send; =20 dev_set_drvdata(&mhi_dev->dev, qdev); - rc =3D qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO); - if (rc) - return rc; =20 /* start channels */ - rc =3D mhi_prepare_for_transfer_autoqueue(mhi_dev); - if (rc) { - qrtr_endpoint_unregister(&qdev->ep); + rc =3D mhi_prepare_for_transfer(mhi_dev); + if (rc) return rc; - } + + rc =3D qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO); + if (rc) + goto err_unprepare; + + rc =3D qcom_mhi_qrtr_queue_dl_buffers(mhi_dev); + if (rc) + goto err_unregister; =20 dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n"); =20 return 0; + +err_unregister: + qrtr_endpoint_unregister(&qdev->ep); +err_unprepare: + mhi_unprepare_from_transfer(mhi_dev); + + return rc; } =20 static void qcom_mhi_qrtr_remove(struct mhi_device *mhi_dev) @@ -151,11 +194,13 @@ static int __maybe_unused qcom_mhi_qrtr_pm_resume_ear= ly(struct device *dev) if (state =3D=3D MHI_STATE_M3) return 0; =20 - rc =3D mhi_prepare_for_transfer_autoqueue(mhi_dev); - if (rc) + rc =3D mhi_prepare_for_transfer(mhi_dev); + if (rc) { dev_err(dev, "failed to prepare for autoqueue transfer %d\n", rc); + return rc; + } =20 - return rc; + return qcom_mhi_qrtr_queue_dl_buffers(mhi_dev); } =20 static const struct dev_pm_ops qcom_mhi_qrtr_pm_ops =3D { --=20 2.48.1 From nobody Mon Feb 9 09:08:21 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C58AD34D4E3; Wed, 17 Dec 2025 17:17:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765991821; cv=none; b=TSKKSH1iyBtnCpk8BYRY07ME2HC3fCN5kGfl3kPxHs9hhh+xcKmaUHIYbJ49h7ndvi8xEx1QTHes85QT7XRNjc7T+dzg+raB81wVq48KczR9aRLjMf7kEI8bUHuW0kM60ZwJq9kQ+6STyxPi77wi9X5KfRNfWITCYjHBko4VXCk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765991821; c=relaxed/simple; bh=AD7dDXAD3itkjdYA9TfORuuV9wOhDa/AZUPfi5Hae9k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KhXdXDPH+BAvzHv9QW/qPxEdO/T9Tg9aUqurGdAE2SIjB58qGmxo12mLUCyKd/HOpYlFCILIxFWCRW+9wswoat6cwTi6iAzMzZ6s8SHVXnVWjJKxg4zIbWkii2Iy6AvkhUe9syBM+IuvXVR1Zblw+PKVGyEW+PbHNvlLOMiSCoc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ppv9FTuW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ppv9FTuW" Received: by smtp.kernel.org (Postfix) with ESMTPS id 8CEB6C19421; Wed, 17 Dec 2025 17:17:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765991821; bh=AD7dDXAD3itkjdYA9TfORuuV9wOhDa/AZUPfi5Hae9k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=ppv9FTuWEHdNKSoznW2U69F+f/KnzH91SZNCxEErTRR1CUqHGWGh32PIpm3SAA8Y0 dol7hmh3gMleLRiECS98M48jEoWvrA1HfLm7LWPAWi1g5yN6xZwqYrxTorabcRTkM5 RPzTj2w9GKDBT4EGQDRe99d/bdVB4O+Lo8u/eFQWLFLf6p2fnE5Y3+b5BHp8dVnz+g K7kgeVSMmW37lHg9Vjm2rpEhq/UtoKBauSgTlBa46GYVi2q1dEVbOflfpbJCbsDGrQ KDd7J1dj56t77HsDCa9X50CdMLzcXAOgBTDzrtrJHUnJKvUXfY28BmLoTtXYs585Oz wZH32/DEmyPXg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7DFD2D65C7D; Wed, 17 Dec 2025 17:17:01 +0000 (UTC) From: Manivannan Sadhasivam via B4 Relay Date: Wed, 17 Dec 2025 22:46:52 +0530 Subject: [PATCH 2/2] bus: mhi: host: Drop the auto_queue support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251217-qrtr-fix-v1-2-f6142a3ec9d8@oss.qualcomm.com> References: <20251217-qrtr-fix-v1-0-f6142a3ec9d8@oss.qualcomm.com> In-Reply-To: <20251217-qrtr-fix-v1-0-f6142a3ec9d8@oss.qualcomm.com> To: Jeff Hugo , Carl Vanderlip , Oded Gabbay , Manivannan Sadhasivam , Jeff Johnson , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Greg Kroah-Hartman , Loic Poulain , Maxim Kochetkov Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, mhi@lists.linux.dev, linux-wireless@vger.kernel.org, ath11k@lists.infradead.org, ath12k@lists.infradead.org, netdev@vger.kernel.org, Bjorn Andersson , Johan Hovold , Chris Lew , Manivannan Sadhasivam X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7752; i=manivannan.sadhasivam@oss.qualcomm.com; h=from:subject:message-id; bh=VV1/Ikl0OH6lDMHohEMkdP14WyebiuRyo/ktlKpfYQ0=; b=owEBbQGS/pANAwAKAVWfEeb+kc71AcsmYgBpQuWLymmyGTbV8eF0fjUIB0p3YI1DhyQBE4klb 8kCicS1Oa2JATMEAAEKAB0WIQRnpUMqgUjL2KRYJ5dVnxHm/pHO9QUCaULliwAKCRBVnxHm/pHO 9f8NB/4pb1tI5jOjRcvH7nqMIvhr0IshwN2BGFpgymF6Pqg2ovOgSWiITOPGtpgeDwuTeuMofNq VJ+zsH8/hmSDmNuIfbb1uRzu3xNiBI50/5Knqw99RFdVu5wer7HL+F9AsG/4tuh7igH/VofxnoJ 7JaDGbVyajrKnkuLP7A0/kKjCFTc+eWFeWWWZnIHgq/2k2tp8G2raOmrquJSqExOMYt9CIhm89p m4oHnZgqmlWMm9dg8glTibgBM1xYkOfgk99G5XczRPLbt5q5fPVG+fPGghyJc5IvpMBVGfW2u0l O8fcUyy/ZqUf3iCP/Tu5EBZc5GzfGRIpRrq2Gl+h8CCjmaLr X-Developer-Key: i=manivannan.sadhasivam@oss.qualcomm.com; a=openpgp; fpr=C668AEC3C3188E4C611465E7488550E901166008 X-Endpoint-Received: by B4 Relay for manivannan.sadhasivam@oss.qualcomm.com/default with auth_id=461 X-Original-From: Manivannan Sadhasivam Reply-To: manivannan.sadhasivam@oss.qualcomm.com From: Manivannan Sadhasivam Now that the only user of the 'auto_queue' feature, (QRTR) has been converted to manage the buffers on its own, drop the code related to it. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Loic Poulain --- drivers/bus/mhi/host/init.c | 10 ----- drivers/bus/mhi/host/internal.h | 3 -- drivers/bus/mhi/host/main.c | 81 +------------------------------------= ---- include/linux/mhi.h | 14 ------- 4 files changed, 2 insertions(+), 106 deletions(-) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 099be8dd1900..b020a6489c07 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -841,18 +841,8 @@ static int parse_ch_cfg(struct mhi_controller *mhi_cnt= rl, mhi_chan->lpm_notify =3D ch_cfg->lpm_notify; mhi_chan->offload_ch =3D ch_cfg->offload_channel; mhi_chan->db_cfg.reset_req =3D ch_cfg->doorbell_mode_switch; - mhi_chan->pre_alloc =3D ch_cfg->auto_queue; mhi_chan->wake_capable =3D ch_cfg->wake_capable; =20 - /* - * If MHI host allocates buffers, then the channel direction - * should be DMA_FROM_DEVICE - */ - if (mhi_chan->pre_alloc && mhi_chan->dir !=3D DMA_FROM_DEVICE) { - dev_err(dev, "Invalid channel configuration\n"); - goto error_chan_cfg; - } - /* * Bi-directional and direction less channel must be an * offload channel diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/interna= l.h index 7937bb1f742c..7b0ee5e3a12d 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -286,7 +286,6 @@ struct mhi_chan { bool lpm_notify; bool configured; bool offload_ch; - bool pre_alloc; bool wake_capable; }; =20 @@ -389,8 +388,6 @@ int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, struct image_info *img_info); void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl); =20 -/* Automatically allocate and queue inbound buffers */ -#define MHI_CH_INBOUND_ALLOC_BUFS BIT(0) int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan); void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl, diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 861551274319..53c0ffe30070 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -664,23 +664,6 @@ static int parse_xfer_event(struct mhi_controller *mhi= _cntrl, mhi_cntrl->runtime_put(mhi_cntrl); } =20 - /* - * Recycle the buffer if buffer is pre-allocated, - * if there is an error, not much we can do apart - * from dropping the packet - */ - if (mhi_chan->pre_alloc) { - if (mhi_queue_buf(mhi_chan->mhi_dev, - mhi_chan->dir, - buf_info->cb_buf, - buf_info->len, MHI_EOT)) { - dev_err(dev, - "Error recycling buffer for chan:%d\n", - mhi_chan->chan); - kfree(buf_info->cb_buf); - } - } - read_lock_bh(&mhi_chan->lock); } break; @@ -1177,17 +1160,12 @@ static int mhi_queue(struct mhi_device *mhi_dev, st= ruct mhi_buf_info *buf_info, int mhi_queue_skb(struct mhi_device *mhi_dev, enum dma_data_direction dir, struct sk_buff *skb, size_t len, enum mhi_flags mflags) { - struct mhi_chan *mhi_chan =3D (dir =3D=3D DMA_TO_DEVICE) ? mhi_dev->ul_ch= an : - mhi_dev->dl_chan; struct mhi_buf_info buf_info =3D { }; =20 buf_info.v_addr =3D skb->data; buf_info.cb_buf =3D skb; buf_info.len =3D len; =20 - if (unlikely(mhi_chan->pre_alloc)) - return -EINVAL; - return mhi_queue(mhi_dev, &buf_info, dir, mflags); } EXPORT_SYMBOL_GPL(mhi_queue_skb); @@ -1472,45 +1450,6 @@ static int mhi_prepare_channel(struct mhi_controller= *mhi_cntrl, if (ret) goto error_pm_state; =20 - if (mhi_chan->dir =3D=3D DMA_FROM_DEVICE) - mhi_chan->pre_alloc =3D !!(flags & MHI_CH_INBOUND_ALLOC_BUFS); - - /* Pre-allocate buffer for xfer ring */ - if (mhi_chan->pre_alloc) { - int nr_el =3D get_nr_avail_ring_elements(mhi_cntrl, - &mhi_chan->tre_ring); - size_t len =3D mhi_cntrl->buffer_len; - - while (nr_el--) { - void *buf; - struct mhi_buf_info info =3D { }; - - buf =3D kmalloc(len, GFP_KERNEL); - if (!buf) { - ret =3D -ENOMEM; - goto error_pre_alloc; - } - - /* Prepare transfer descriptors */ - info.v_addr =3D buf; - info.cb_buf =3D buf; - info.len =3D len; - ret =3D mhi_gen_tre(mhi_cntrl, mhi_chan, &info, MHI_EOT); - if (ret) { - kfree(buf); - goto error_pre_alloc; - } - } - - read_lock_bh(&mhi_cntrl->pm_lock); - if (MHI_DB_ACCESS_VALID(mhi_cntrl)) { - read_lock_irq(&mhi_chan->lock); - mhi_ring_chan_db(mhi_cntrl, mhi_chan); - read_unlock_irq(&mhi_chan->lock); - } - read_unlock_bh(&mhi_cntrl->pm_lock); - } - mutex_unlock(&mhi_chan->mutex); =20 return 0; @@ -1522,12 +1461,6 @@ static int mhi_prepare_channel(struct mhi_controller= *mhi_cntrl, error_init_chan: mutex_unlock(&mhi_chan->mutex); =20 - return ret; - -error_pre_alloc: - mutex_unlock(&mhi_chan->mutex); - mhi_unprepare_channel(mhi_cntrl, mhi_chan); - return ret; } =20 @@ -1600,12 +1533,8 @@ static void mhi_reset_data_chan(struct mhi_controlle= r *mhi_cntrl, mhi_del_ring_element(mhi_cntrl, buf_ring); mhi_del_ring_element(mhi_cntrl, tre_ring); =20 - if (mhi_chan->pre_alloc) { - kfree(buf_info->cb_buf); - } else { - result.buf_addr =3D buf_info->cb_buf; - mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); - } + result.buf_addr =3D buf_info->cb_buf; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); } } =20 @@ -1666,12 +1595,6 @@ int mhi_prepare_for_transfer(struct mhi_device *mhi_= dev) } EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer); =20 -int mhi_prepare_for_transfer_autoqueue(struct mhi_device *mhi_dev) -{ - return __mhi_prepare_for_transfer(mhi_dev, MHI_CH_INBOUND_ALLOC_BUFS); -} -EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer_autoqueue); - void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) { struct mhi_controller *mhi_cntrl =3D mhi_dev->mhi_cntrl; diff --git a/include/linux/mhi.h b/include/linux/mhi.h index dd372b0123a6..88ccb3e14f48 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -215,7 +215,6 @@ enum mhi_db_brst_mode { * @lpm_notify: The channel master requires low power mode notifications * @offload_channel: The client manages the channel completely * @doorbell_mode_switch: Channel switches to doorbell mode on M0 transiti= on - * @auto_queue: Framework will automatically queue buffers for DL traffic * @wake-capable: Channel capable of waking up the system */ struct mhi_channel_config { @@ -232,7 +231,6 @@ struct mhi_channel_config { bool lpm_notify; bool offload_channel; bool doorbell_mode_switch; - bool auto_queue; bool wake_capable; }; =20 @@ -743,18 +741,6 @@ void mhi_device_put(struct mhi_device *mhi_dev); */ int mhi_prepare_for_transfer(struct mhi_device *mhi_dev); =20 -/** - * mhi_prepare_for_transfer_autoqueue - Setup UL and DL channels with auto= queue - * buffers for DL traffic - * @mhi_dev: Device associated with the channels - * - * Allocate and initialize the channel context and also issue the START ch= annel - * command to both channels. Channels can be started only if both host and - * device execution environments match and channels are in a DISABLED stat= e. - * The MHI core will automatically allocate and queue buffers for the DL t= raffic. - */ -int mhi_prepare_for_transfer_autoqueue(struct mhi_device *mhi_dev); - /** * mhi_unprepare_from_transfer - Reset UL and DL channels for data transfe= r. * Issue the RESET channel command and let t= he --=20 2.48.1