For ADSP, only a limited number of FastRPC context banks (CBs) are available. Each CB supports a single session, which means only a few processes can run on ADSP simultaneously. If all sessions are consumed by fastrpc daemons, no session remains available when a user application starts, causing the application to fail.
To address this limitation, a Device Tree change was used till now: qcom,nsessions = <5>; However, feedback from the upstream community indicated that this change should not be made in the Device Tree. Instead, it was recommended to handle this as a driver-level change. Instead of duplicating sessions inline during fastrpc_cb_probe() using the qcom,nsessions DT property, defer duplication until after of_platform_populate() returns in fastrpc_rpmsg_probe(), at which point all compute-CB child nodes have been probed and the session array is fully populated. For the ADSP domain, append FASTRPC_DUP_SESSIONS (4) copies of the last probed session once of_platform_populate() succeeds. This keeps the per-CB probe path simple and ensures duplicates are always derived from a stable, fully-initialised session state. The qcom,nsessions DT property is no longer consumed by the driver; the binding and DT sources are left unchanged. Signed-off-by: Vinayak Katoch <[email protected]> --- drivers/misc/fastrpc.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 1080f9acf70a..46afbae9c234 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -30,6 +30,7 @@ #define CDSP_DOMAIN_ID (3) #define GDSP_DOMAIN_ID (4) #define FASTRPC_MAX_SESSIONS 14 +#define FASTRPC_DUP_SESSIONS 4 #define FASTRPC_MAX_VMIDS 16 #define FASTRPC_ALIGN 128 #define FASTRPC_MAX_FDLIST 16 @@ -2195,7 +2196,6 @@ static int fastrpc_cb_probe(struct platform_device *pdev) struct fastrpc_channel_ctx *cctx; struct fastrpc_session_ctx *sess; struct device *dev = &pdev->dev; - int i, sessions = 0; unsigned long flags; int rc; u32 dma_bits; @@ -2204,8 +2204,6 @@ static int fastrpc_cb_probe(struct platform_device *pdev) if (!cctx) return -EINVAL; - of_property_read_u32(dev->of_node, "qcom,nsessions", &sessions); - spin_lock_irqsave(&cctx->lock, flags); if (cctx->sesscount >= FASTRPC_MAX_SESSIONS) { dev_err(&pdev->dev, "too many sessions\n"); @@ -2225,16 +2223,6 @@ static int fastrpc_cb_probe(struct platform_device *pdev) if (of_property_read_u32(dev->of_node, "reg", &sess->sid)) dev_info(dev, "FastRPC Session ID not specified in DT\n"); - if (sessions > 0) { - struct fastrpc_session_ctx *dup_sess; - - for (i = 1; i < sessions; i++) { - if (cctx->sesscount >= FASTRPC_MAX_SESSIONS) - break; - dup_sess = &cctx->session[cctx->sesscount++]; - memcpy(dup_sess, sess, sizeof(*dup_sess)); - } - } spin_unlock_irqrestore(&cctx->lock, flags); rc = dma_set_mask(dev, DMA_BIT_MASK(dma_bits)); if (rc) { @@ -2445,6 +2433,23 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) if (err) goto err_deregister_fdev; + if (data->domain_id == ADSP_DOMAIN_ID && data->sesscount > 0) { + struct fastrpc_session_ctx *last_sess; + struct fastrpc_session_ctx *dup_sess; + unsigned long flags; + int i; + + spin_lock_irqsave(&data->lock, flags); + last_sess = &data->session[data->sesscount - 1]; + for (i = 0; i < FASTRPC_DUP_SESSIONS; i++) { + if (data->sesscount >= FASTRPC_MAX_SESSIONS) + break; + dup_sess = &data->session[data->sesscount++]; + memcpy(dup_sess, last_sess, sizeof(*dup_sess)); + } + spin_unlock_irqrestore(&data->lock, flags); + } + return 0; err_deregister_fdev: --- base-commit: 97e797263a5e963da3d1e66e743fd518567dfe37 change-id: 20260609-dup-sessions-ea2acaac1994 Best regards, -- Vinayak Katoch <[email protected]>
