Skip to content

Commit 1728bb3

Browse files
committed
FROMLIST: misc: fastrpc: Enable poll mode for specific devices
Some devices, such as Talos, do not support poll mode, and it is not appropriate to force all devices to start in poll mode in the fastrpc driver. In case poll timeout happens, the call will fallback to normal RPC mode. Poll mode can be enabled by user by using FASTRPC_IOCTL_SET_OPTION ioctl request with FASTRPC_POLL_MODE request id. Link: https://lore.kernel.org/all/20260424095903.1622565-5-ekansh.gupta@oss.qualcomm.com/ Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
1 parent b0d4b96 commit 1728bb3

2 files changed

Lines changed: 93 additions & 23 deletions

File tree

drivers/misc/fastrpc.c

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ struct fastrpc_invoke_ctx {
260260
bool is_work_done;
261261
/* response flags from remote processor */
262262
enum fastrpc_response_flags rsp_flags;
263+
/* process updates poll memory instead of glink response */
264+
bool is_polled;
263265
struct kref refcount;
264266
struct list_head node; /* list of ctxs */
265267
struct completion work;
@@ -304,6 +306,7 @@ struct fastrpc_channel_ctx {
304306
bool secure;
305307
bool unsigned_support;
306308
u64 dma_mask;
309+
bool poll_mode_supported;
307310
};
308311

309312
struct fastrpc_device {
@@ -325,6 +328,8 @@ struct fastrpc_user {
325328
int client_id;
326329
int pd;
327330
bool is_secure_dev;
331+
/* Flags poll mode state */
332+
bool poll_mode;
328333
/* Lock for lists */
329334
spinlock_t lock;
330335
/* lock for allocations */
@@ -1289,28 +1294,15 @@ static int fastrpc_wait_for_completion(struct fastrpc_invoke_ctx *ctx,
12891294
{
12901295
int err;
12911296

1292-
do {
1293-
switch (ctx->rsp_flags) {
1294-
case NORMAL_RESPONSE:
1295-
err = fastrpc_wait_for_response(ctx, kernel);
1296-
if (err || ctx->is_work_done)
1297-
return err;
1298-
break;
1299-
case POLL_MODE:
1300-
err = poll_for_remote_response(ctx);
1301-
/* If polling timed out, move to normal response mode */
1302-
if (err)
1303-
ctx->rsp_flags = NORMAL_RESPONSE;
1304-
break;
1305-
default:
1306-
err = -EBADR;
1307-
dev_dbg(ctx->fl->sctx->dev,
1308-
"unsupported response type:0x%x\n", ctx->rsp_flags);
1309-
break;
1310-
}
1311-
} while (!ctx->is_work_done);
1297+
if (ctx->is_polled) {
1298+
err = poll_for_remote_response(ctx);
1299+
if (!err)
1300+
return 0;
1301+
/* If polling timed out or failed, move to normal response mode */
1302+
ctx->is_polled = false;
1303+
}
13121304

1313-
return err;
1305+
return fastrpc_wait_for_response(ctx, kernel);
13141306
}
13151307

13161308
static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel,
@@ -1348,8 +1340,13 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel,
13481340
if (err)
13491341
goto bail;
13501342

1351-
if (handle > FASTRPC_MAX_STATIC_HANDLE && fl->pd == USER_PD)
1352-
ctx->rsp_flags = POLL_MODE;
1343+
/*
1344+
* Set message context as polled if the call is for a user PD
1345+
* dynamic module and user has enabled poll mode.
1346+
*/
1347+
if (handle > FASTRPC_MAX_STATIC_HANDLE && fl->pd == USER_PD &&
1348+
fl->poll_mode)
1349+
ctx->is_polled = true;
13531350

13541351
err = fastrpc_wait_for_completion(ctx, kernel);
13551352
if (err)
@@ -1894,6 +1891,33 @@ static int fastrpc_get_info_from_kernel(struct fastrpc_ioctl_capability *cap,
18941891
return 0;
18951892
}
18961893

1894+
static int fastrpc_set_option(struct fastrpc_user *fl, char __user *argp)
1895+
{
1896+
struct fastrpc_ioctl_set_option opt = { 0 };
1897+
int i;
1898+
1899+
if (copy_from_user(&opt, argp, sizeof(opt)))
1900+
return -EFAULT;
1901+
1902+
for (i = 0; i < ARRAY_SIZE(opt.reserved); i++) {
1903+
if (opt.reserved[i] != 0)
1904+
return -EINVAL;
1905+
}
1906+
1907+
if (opt.request_id != FASTRPC_POLL_MODE)
1908+
return -EINVAL;
1909+
1910+
if (opt.value) {
1911+
if (!fl->cctx->poll_mode_supported)
1912+
return -EOPNOTSUPP;
1913+
fl->poll_mode = true;
1914+
} else {
1915+
fl->poll_mode = false;
1916+
}
1917+
1918+
return 0;
1919+
}
1920+
18971921
static int fastrpc_get_dsp_info(struct fastrpc_user *fl, char __user *argp)
18981922
{
18991923
struct fastrpc_ioctl_capability cap = {0};
@@ -2257,6 +2281,9 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd,
22572281
case FASTRPC_IOCTL_MEM_UNMAP:
22582282
err = fastrpc_req_mem_unmap(fl, argp);
22592283
break;
2284+
case FASTRPC_IOCTL_SET_OPTION:
2285+
err = fastrpc_set_option(fl, argp);
2286+
break;
22602287
case FASTRPC_IOCTL_GET_DSP_INFO:
22612288
err = fastrpc_get_dsp_info(fl, argp);
22622289
break;
@@ -2403,6 +2430,21 @@ static int fastrpc_get_domain_id(const char *domain)
24032430
return -EINVAL;
24042431
}
24052432

2433+
/*
2434+
* Exception list for legacy platforms whose DSP firmware supports
2435+
* FastRPC polling mode.
2436+
*
2437+
* NOTE: This list is intentionally closed.
2438+
* Do NOT add new platforms here. New SoCs must advertise polling mode
2439+
* support via their soc_data.
2440+
*/
2441+
2442+
static const char *const fastrpc_poll_supported_machines[] = {
2443+
"qcom,milos", "qcom,qcs8300", "qcom,sa8775p", "qcom,sar2130p",
2444+
"qcom,sm8450", "qcom,sm8550", "qcom,sm8650", "qcom,sm8750",
2445+
"qcom,x1e80100", "qcom,x1p42100", NULL,
2446+
};
2447+
24062448
static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
24072449
{
24082450
struct device *rdev = &rpdev->dev;
@@ -2474,6 +2516,9 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
24742516
secure_dsp = !(of_property_read_bool(rdev->of_node, "qcom,non-secure-domain"));
24752517
data->secure = secure_dsp;
24762518

2519+
data->poll_mode_supported =
2520+
of_machine_compatible_match(fastrpc_poll_supported_machines);
2521+
24772522
switch (domain_id) {
24782523
case ADSP_DOMAIN_ID:
24792524
case MDSP_DOMAIN_ID:

include/uapi/misc/fastrpc.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define FASTRPC_IOCTL_INIT_CREATE_STATIC _IOWR('R', 9, struct fastrpc_init_create_static)
1717
#define FASTRPC_IOCTL_MEM_MAP _IOWR('R', 10, struct fastrpc_mem_map)
1818
#define FASTRPC_IOCTL_MEM_UNMAP _IOWR('R', 11, struct fastrpc_mem_unmap)
19+
#define FASTRPC_IOCTL_SET_OPTION _IOWR('R', 12, struct fastrpc_ioctl_set_option)
1920
#define FASTRPC_IOCTL_GET_DSP_INFO _IOWR('R', 13, struct fastrpc_ioctl_capability)
2021

2122
/**
@@ -67,6 +68,24 @@ enum fastrpc_proc_attr {
6768
/* Fastrpc attribute for memory protection of buffers */
6869
#define FASTRPC_ATTR_SECUREMAP (1)
6970

71+
/**
72+
* FASTRPC_POLL_MODE - Enable/disable poll mode for FastRPC invocations
73+
*
74+
* Poll mode is an optimization that allows the CPU to poll shared memory
75+
* for completion instead of waiting for an interrupt-based response.
76+
* This reduces latency for fast-completing operations.
77+
*
78+
* Restrictions:
79+
* - Only supported for USER_PD (User Protection Domain)
80+
* - Only applies to dynamic modules (handle > 20)
81+
* - Static modules always use interrupt-based completion
82+
*
83+
* Values:
84+
* - 0: Disable poll mode (use interrupt-based completion)
85+
* - 1: Enable poll mode (poll shared memory for completion)
86+
*/
87+
#define FASTRPC_POLL_MODE (1)
88+
7089
struct fastrpc_invoke_args {
7190
__u64 ptr;
7291
__u64 length;
@@ -133,6 +152,12 @@ struct fastrpc_mem_unmap {
133152
__s32 reserved[5];
134153
};
135154

155+
struct fastrpc_ioctl_set_option {
156+
__u32 request_id; /* Request type (e.g., FASTRPC_POLL_MODE) */
157+
__u32 value; /* Request-specific value */
158+
__s32 reserved[6];
159+
};
160+
136161
struct fastrpc_ioctl_capability {
137162
__u32 unused; /* deprecated, ignored by the kernel */
138163
__u32 attribute_id;

0 commit comments

Comments
 (0)