[v7,5/5] misc: fastrpc: Add support to allocate shared context bank
Commit Message
Context banks could be set as a shared one using a DT propery
"qcom,nsessions". The property takes the number of session to
be created of the context bank. This change provides a control
mechanism for user to use shared context banks for light weight
processes. The session is set as shared while its creation and if
a user requests for shared context bank, the same will be allocated
during process initialization.
Signed-off-by: Ekansh Gupta <quic_ekangupt@quicinc.com>
---
Changes in v7:
- Rebase the patch to latest kernel version
drivers/misc/fastrpc.c | 122 ++++++++++++++++++++++++------------
include/uapi/misc/fastrpc.h | 12 ++++
2 files changed, 95 insertions(+), 39 deletions(-)
Comments
On 21/11/2023 09:48, Ekansh Gupta wrote:
> static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp)
> {
> struct fastrpc_enhanced_invoke einv;
> struct fastrpc_invoke_args *args = NULL;
> struct fastrpc_ioctl_multimode_invoke invoke;
> + struct fastrpc_internal_control cp = {0};
> u32 nscalars;
> u64 *perf_kernel;
> int err, i;
> @@ -1938,6 +1975,12 @@ static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp)
> err = fastrpc_internal_invoke(fl, false, &einv);
> kfree(args);
> break;
> + case FASTRPC_INVOKE_CONTROL:
> + if (copy_from_user(&cp, (void __user *)(uintptr_t)invoke.invparam, sizeof(cp)))
> + return -EFAULT;
wow, this struct is not even exposed in a uapi header, how come
userspace knows about this struct?
Every struct that userspace fills in needs to be part of the UAPI headers.
--srini
> +
> + err = fastrpc_internal_control(fl, &cp);
> + break;
> default:
> err = -ENOTTY;
> break;
> @@ -2440,6 +2483,7 @@ static int fastrpc_cb_probe(struct platform_device *pdev)
> if (sessions > 0) {
> struct fastrpc_session_ctx *dup_sess;
>
> + sess->sharedcb = true;
> for (i = 1; i < sessions; i++) {
Hi Ekansh,
kernel test robot noticed the following build warnings:
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Ekansh-Gupta/misc-fastrpc-Add-fastrpc-multimode-invoke-request-support/20231121-175147
base: linus/master
patch link: https://lore.kernel.org/r/20231121094844.5764-6-quic_ekangupt%40quicinc.com
patch subject: [PATCH v7 5/5] misc: fastrpc: Add support to allocate shared context bank
config: arm-randconfig-r081-20231123 (https://download.01.org/0day-ci/archive/20231125/202311250922.W9tgrGT9-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20231125/202311250922.W9tgrGT9-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>
| Closes: https://lore.kernel.org/r/202311250922.W9tgrGT9-lkp@intel.com/
New smatch warnings:
drivers/misc/fastrpc.c:1621 fastrpc_init_create_process() warn: missing unwind goto?
vim +1621 drivers/misc/fastrpc.c
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1576 static int fastrpc_init_create_process(struct fastrpc_user *fl,
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1577 char __user *argp)
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1578 {
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1579 struct fastrpc_init_create init;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1580 struct fastrpc_invoke_args *args;
becdceed7669e5 Ekansh Gupta 2023-11-21 1581 struct fastrpc_enhanced_invoke ioctl;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1582 struct fastrpc_phy_page pages[1];
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1583 struct fastrpc_map *map = NULL;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1584 struct fastrpc_buf *imem = NULL;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1585 int memlen;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1586 int err;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1587 struct {
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1588 int pgid;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1589 u32 namelen;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1590 u32 filelen;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1591 u32 pageslen;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1592 u32 attrs;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1593 u32 siglen;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1594 } inbuf;
7f1f481263c3ce Jeya R 2022-02-14 1595 bool unsigned_module = false;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1596
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1597 args = kcalloc(FASTRPC_CREATE_PROCESS_NARGS, sizeof(*args), GFP_KERNEL);
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1598 if (!args)
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1599 return -ENOMEM;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1600
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1601 if (copy_from_user(&init, argp, sizeof(init))) {
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1602 err = -EFAULT;
b49f6d83e290f1 Thierry Escande 2019-03-07 1603 goto err;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1604 }
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1605
7f1f481263c3ce Jeya R 2022-02-14 1606 if (init.attrs & FASTRPC_MODE_UNSIGNED_MODULE)
7f1f481263c3ce Jeya R 2022-02-14 1607 unsigned_module = true;
7f1f481263c3ce Jeya R 2022-02-14 1608
7f1f481263c3ce Jeya R 2022-02-14 1609 if (is_session_rejected(fl, unsigned_module)) {
7f1f481263c3ce Jeya R 2022-02-14 1610 err = -ECONNREFUSED;
7f1f481263c3ce Jeya R 2022-02-14 1611 goto err;
7f1f481263c3ce Jeya R 2022-02-14 1612 }
7f1f481263c3ce Jeya R 2022-02-14 1613
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1614 if (init.filelen > INIT_FILELEN_MAX) {
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1615 err = -EINVAL;
b49f6d83e290f1 Thierry Escande 2019-03-07 1616 goto err;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1617 }
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1618
92fe4bcba19c31 Ekansh Gupta 2023-11-21 1619 fl->sctx = fastrpc_session_alloc(fl->cctx, fl->sharedcb);
92fe4bcba19c31 Ekansh Gupta 2023-11-21 1620 if (!fl->sctx)
92fe4bcba19c31 Ekansh Gupta 2023-11-21 @1621 return -EBUSY;
Should be "ret = -EBUSY; goto err;".
92fe4bcba19c31 Ekansh Gupta 2023-11-21 1622
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1623 inbuf.pgid = fl->tgid;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1624 inbuf.namelen = strlen(current->comm) + 1;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1625 inbuf.filelen = init.filelen;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1626 inbuf.pageslen = 1;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1627 inbuf.attrs = init.attrs;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1628 inbuf.siglen = init.siglen;
84195d206e1fbd Jonathan Marek 2020-09-08 1629 fl->pd = USER_PD;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1630
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1631 if (init.filelen && init.filefd) {
e90d911906196b Vamsi Krishna Gattupalli 2022-02-14 1632 err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map);
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1633 if (err)
b49f6d83e290f1 Thierry Escande 2019-03-07 1634 goto err;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1635 }
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1636
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1637 memlen = ALIGN(max(INIT_FILELEN_MAX, (int)init.filelen * 4),
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1638 1024 * 1024);
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1639 err = fastrpc_buf_alloc(fl, fl->sctx->dev, memlen,
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1640 &imem);
b49f6d83e290f1 Thierry Escande 2019-03-07 1641 if (err)
b49f6d83e290f1 Thierry Escande 2019-03-07 1642 goto err_alloc;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1643
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1644 fl->init_mem = imem;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1645 args[0].ptr = (u64)(uintptr_t)&inbuf;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1646 args[0].length = sizeof(inbuf);
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1647 args[0].fd = -1;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1648
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1649 args[1].ptr = (u64)(uintptr_t)current->comm;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1650 args[1].length = inbuf.namelen;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1651 args[1].fd = -1;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1652
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1653 args[2].ptr = (u64) init.file;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1654 args[2].length = inbuf.filelen;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1655 args[2].fd = init.filefd;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1656
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1657 pages[0].addr = imem->phys;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1658 pages[0].size = imem->size;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1659
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1660 args[3].ptr = (u64)(uintptr_t) pages;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1661 args[3].length = 1 * sizeof(*pages);
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1662 args[3].fd = -1;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1663
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1664 args[4].ptr = (u64)(uintptr_t)&inbuf.attrs;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1665 args[4].length = sizeof(inbuf.attrs);
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1666 args[4].fd = -1;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1667
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1668 args[5].ptr = (u64)(uintptr_t) &inbuf.siglen;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1669 args[5].length = sizeof(inbuf.siglen);
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1670 args[5].fd = -1;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1671
becdceed7669e5 Ekansh Gupta 2023-11-21 1672 ioctl.inv.handle = FASTRPC_INIT_HANDLE;
becdceed7669e5 Ekansh Gupta 2023-11-21 1673 ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0);
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1674 if (init.attrs)
becdceed7669e5 Ekansh Gupta 2023-11-21 1675 ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 4, 0);
e27748f5c08306 Ekansh Gupta 2023-11-21 1676 ioctl.inv.args = (u64)args;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1677
becdceed7669e5 Ekansh Gupta 2023-11-21 1678 err = fastrpc_internal_invoke(fl, true, &ioctl);
b49f6d83e290f1 Thierry Escande 2019-03-07 1679 if (err)
b49f6d83e290f1 Thierry Escande 2019-03-07 1680 goto err_invoke;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1681
b49f6d83e290f1 Thierry Escande 2019-03-07 1682 kfree(args);
b49f6d83e290f1 Thierry Escande 2019-03-07 1683
b49f6d83e290f1 Thierry Escande 2019-03-07 1684 return 0;
b49f6d83e290f1 Thierry Escande 2019-03-07 1685
b49f6d83e290f1 Thierry Escande 2019-03-07 1686 err_invoke:
b49f6d83e290f1 Thierry Escande 2019-03-07 1687 fl->init_mem = NULL;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1688 fastrpc_buf_free(imem);
b49f6d83e290f1 Thierry Escande 2019-03-07 1689 err_alloc:
b49f6d83e290f1 Thierry Escande 2019-03-07 1690 fastrpc_map_put(map);
b49f6d83e290f1 Thierry Escande 2019-03-07 1691 err:
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1692 kfree(args);
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1693
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1694 return err;
d73f71c7c6ee15 Srinivas Kandagatla 2019-02-08 1695 }
@@ -297,6 +297,7 @@ struct fastrpc_session_ctx {
int sid;
bool used;
bool valid;
+ bool sharedcb;
};
struct fastrpc_channel_ctx {
@@ -344,12 +345,22 @@ struct fastrpc_user {
int tgid;
int pd;
bool is_secure_dev;
+ bool sharedcb;
/* Lock for lists */
spinlock_t lock;
/* lock for allocations */
struct mutex mutex;
};
+struct fastrpc_ctrl_smmu {
+ u32 sharedcb; /* Set to SMMU share context bank */
+};
+
+struct fastrpc_internal_control {
+ u32 req;
+ struct fastrpc_ctrl_smmu smmu;
+};
+
static inline int64_t getnstimediff(struct timespec64 *start)
{
int64_t ns;
@@ -851,6 +862,37 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = {
.release = fastrpc_release,
};
+static struct fastrpc_session_ctx *fastrpc_session_alloc(
+ struct fastrpc_channel_ctx *cctx, bool sharedcb)
+{
+ struct fastrpc_session_ctx *session = NULL;
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&cctx->lock, flags);
+ for (i = 0; i < cctx->sesscount; i++) {
+ if (!cctx->session[i].used && cctx->session[i].valid &&
+ cctx->session[i].sharedcb == sharedcb) {
+ cctx->session[i].used = true;
+ session = &cctx->session[i];
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&cctx->lock, flags);
+
+ return session;
+}
+
+static void fastrpc_session_free(struct fastrpc_channel_ctx *cctx,
+ struct fastrpc_session_ctx *session)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&cctx->lock, flags);
+ session->used = false;
+ spin_unlock_irqrestore(&cctx->lock, flags);
+}
+
static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
u64 len, u32 attr, struct fastrpc_map **ppmap)
{
@@ -1448,6 +1490,10 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
goto err_name;
}
+ fl->sctx = fastrpc_session_alloc(fl->cctx, fl->sharedcb);
+ if (!fl->sctx)
+ return -EBUSY;
+
if (!fl->cctx->remote_heap) {
err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
&fl->cctx->remote_heap);
@@ -1570,6 +1616,10 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl,
goto err;
}
+ fl->sctx = fastrpc_session_alloc(fl->cctx, fl->sharedcb);
+ if (!fl->sctx)
+ return -EBUSY;
+
inbuf.pgid = fl->tgid;
inbuf.namelen = strlen(current->comm) + 1;
inbuf.filelen = init.filelen;
@@ -1644,36 +1694,6 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl,
return err;
}
-static struct fastrpc_session_ctx *fastrpc_session_alloc(
- struct fastrpc_channel_ctx *cctx)
-{
- struct fastrpc_session_ctx *session = NULL;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&cctx->lock, flags);
- for (i = 0; i < cctx->sesscount; i++) {
- if (!cctx->session[i].used && cctx->session[i].valid) {
- cctx->session[i].used = true;
- session = &cctx->session[i];
- break;
- }
- }
- spin_unlock_irqrestore(&cctx->lock, flags);
-
- return session;
-}
-
-static void fastrpc_session_free(struct fastrpc_channel_ctx *cctx,
- struct fastrpc_session_ctx *session)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&cctx->lock, flags);
- session->used = false;
- spin_unlock_irqrestore(&cctx->lock, flags);
-}
-
static void fastrpc_context_list_free(struct fastrpc_user *fl)
{
struct fastrpc_invoke_ctx *ctx, *n;
@@ -1777,15 +1797,6 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
fl->cctx = cctx;
fl->is_secure_dev = fdevice->secure;
- fl->sctx = fastrpc_session_alloc(cctx);
- if (!fl->sctx) {
- dev_err(&cctx->rpdev->dev, "No session available\n");
- mutex_destroy(&fl->mutex);
- kfree(fl);
-
- return -EBUSY;
- }
-
spin_lock_irqsave(&cctx->lock, flags);
list_add_tail(&fl->user, &cctx->users);
spin_unlock_irqrestore(&cctx->lock, flags);
@@ -1844,6 +1855,10 @@ static int fastrpc_init_attach(struct fastrpc_user *fl, int pd)
struct fastrpc_enhanced_invoke ioctl;
int tgid = fl->tgid;
+ fl->sctx = fastrpc_session_alloc(fl->cctx, fl->sharedcb);
+ if (!fl->sctx)
+ return -EBUSY;
+
args[0].ptr = (u64)(uintptr_t) &tgid;
args[0].length = sizeof(tgid);
args[0].fd = -1;
@@ -1890,11 +1905,33 @@ static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp)
return err;
}
+static int fastrpc_internal_control(struct fastrpc_user *fl,
+ struct fastrpc_internal_control *cp)
+{
+ int err = 0;
+
+ if (!fl)
+ return -EBADF;
+ if (!cp)
+ return -EINVAL;
+
+ switch (cp->req) {
+ case FASTRPC_CONTROL_SMMU:
+ fl->sharedcb = cp->smmu.sharedcb;
+ break;
+ default:
+ err = -EBADRQC;
+ break;
+ }
+ return err;
+}
+
static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp)
{
struct fastrpc_enhanced_invoke einv;
struct fastrpc_invoke_args *args = NULL;
struct fastrpc_ioctl_multimode_invoke invoke;
+ struct fastrpc_internal_control cp = {0};
u32 nscalars;
u64 *perf_kernel;
int err, i;
@@ -1938,6 +1975,12 @@ static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp)
err = fastrpc_internal_invoke(fl, false, &einv);
kfree(args);
break;
+ case FASTRPC_INVOKE_CONTROL:
+ if (copy_from_user(&cp, (void __user *)(uintptr_t)invoke.invparam, sizeof(cp)))
+ return -EFAULT;
+
+ err = fastrpc_internal_control(fl, &cp);
+ break;
default:
err = -ENOTTY;
break;
@@ -2440,6 +2483,7 @@ static int fastrpc_cb_probe(struct platform_device *pdev)
if (sessions > 0) {
struct fastrpc_session_ctx *dup_sess;
+ sess->sharedcb = true;
for (i = 1; i < sessions; i++) {
if (cctx->sesscount >= FASTRPC_MAX_SESSIONS)
break;
@@ -166,6 +166,18 @@ struct fastrpc_ioctl_capability {
__u32 reserved[4];
};
+enum fastrpc_control_type {
+ FASTRPC_CONTROL_LATENCY = 1,
+ FASTRPC_CONTROL_SMMU = 2,
+ FASTRPC_CONTROL_KALLOC = 3,
+ FASTRPC_CONTROL_WAKELOCK = 4,
+ FASTRPC_CONTROL_PM = 5,
+ FASTRPC_CONTROL_DSPPROCESS_CLEAN = 6,
+ FASTRPC_CONTROL_RPC_POLL = 7,
+ FASTRPC_CONTROL_ASYNC_WAKE = 8,
+ FASTRPC_CONTROL_NOTIF_WAKE = 9,
+};
+
enum fastrpc_perfkeys {
PERF_COUNT = 0,
PERF_RESERVED1 = 1,