From: Anup Patel <anup.patel@oss.qualcomm.com>
To: Palmer Dabbelt <palmer@dabbelt.com>,
Paul Walmsley <pjw@kernel.org>,
Rahul Pathak <rahul@summations.net>,
Stephen Boyd <sboyd@kernel.org>,
Brian Masney <bmasney+clk@redhat.com>,
Jerome Brunet <jbrunet+clk@baylibre.com>,
Thomas Gleixner <tglx@kernel.org>, Radu Rendec <radu@rendec.net>,
Jassi Brar <jassisinghbrar@gmail.com>
Cc: Himanshu Chauhan <hchauhan@ventanamicro.com>,
Atish Patra <atish.patra@linux.dev>,
Anup Patel <anup@brainfault.org>,
Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com>,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-clk@vger.kernel.org,
Anup Patel <anup.patel@oss.qualcomm.com>
Subject: [PATCH 2/4] RISC-V: Factor-out per-hart MPXY shared-memory acquisition
Date: Wed, 30 Sep 2026 20:32:11 +0530 [thread overview]
Message-ID: <20260930150213.799245-3-anup.patel@oss.qualcomm.com> (raw)
In-Reply-To: <20260930150213.799245-1-anup.patel@oss.qualcomm.com>
From: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com>
Most of the SBI MPXY functions need to access MPXY shared-memory so
they have to acquire underlying host CPU before accessing the MPXY
shared-memory and release the host CPU after the work is done.
Factor-out the above mentioned per-hart MPXY shared-memory and host
CPU acquisition into mpxy_local_get()/put() functions.
Signed-off-by: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com>
Signed-off-by: Anup Patel <anup.patel@oss.qualcomm.com>
---
arch/riscv/kernel/sbi_mpxy.c | 159 ++++++++++++++++++++++-------------
1 file changed, 100 insertions(+), 59 deletions(-)
diff --git a/arch/riscv/kernel/sbi_mpxy.c b/arch/riscv/kernel/sbi_mpxy.c
index 17a2cee21311..b2b34991fd42 100644
--- a/arch/riscv/kernel/sbi_mpxy.c
+++ b/arch/riscv/kernel/sbi_mpxy.c
@@ -40,6 +40,26 @@ static DEFINE_PER_CPU(struct mpxy_local, mpxy_local);
static unsigned long mpxy_shmem_size;
static bool mpxy_shmem_init_done;
+static int mpxy_local_get(struct mpxy_local **out)
+{
+ struct mpxy_local *mpxy;
+
+ get_cpu();
+ mpxy = this_cpu_ptr(&mpxy_local);
+ if (!mpxy->shmem_active) {
+ put_cpu();
+ return -ENODEV;
+ }
+
+ *out = mpxy;
+ return 0;
+}
+
+static void mpxy_local_put(void)
+{
+ put_cpu();
+}
+
unsigned long sbi_mpxy_shmem_size(void)
{
if (!mpxy_shmem_init_done)
@@ -50,53 +70,61 @@ EXPORT_SYMBOL_GPL(sbi_mpxy_shmem_size);
int sbi_mpxy_get_channel_count(u32 *channel_count)
{
- struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
- struct sbi_mpxy_channel_ids_data *sdata = mpxy->shmem;
+ struct sbi_mpxy_channel_ids_data *sdata;
+ struct mpxy_local *mpxy;
u32 remaining, returned;
struct sbiret sret;
+ int rc = 0;
- if (!mpxy->shmem_active)
- return -ENODEV;
if (!channel_count)
return -EINVAL;
- get_cpu();
+ rc = mpxy_local_get(&mpxy);
+ if (rc)
+ return rc;
+ sdata = mpxy->shmem;
/* Get the remaining and returned fields to calculate total */
sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_GET_CHANNEL_IDS,
0, 0, 0, 0, 0, 0);
- if (sret.error)
- goto err_put_cpu;
+ if (sret.error) {
+ rc = sbi_err_map_linux_errno(sret.error);
+ goto out;
+ }
remaining = le32_to_cpu(sdata->remaining);
returned = le32_to_cpu(sdata->returned);
*channel_count = remaining + returned;
-err_put_cpu:
- put_cpu();
- return sbi_err_map_linux_errno(sret.error);
+out:
+ mpxy_local_put();
+ return rc;
}
EXPORT_SYMBOL_GPL(sbi_mpxy_get_channel_count);
int sbi_mpxy_get_channel_ids(u32 channel_count, u32 *channel_ids)
{
- struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
- struct sbi_mpxy_channel_ids_data *sdata = mpxy->shmem;
u32 remaining, returned, count, start_index = 0;
+ struct sbi_mpxy_channel_ids_data *sdata;
+ struct mpxy_local *mpxy;
struct sbiret sret;
+ int rc = 0;
- if (!mpxy->shmem_active)
- return -ENODEV;
if (!channel_count || !channel_ids)
return -EINVAL;
- get_cpu();
+ rc = mpxy_local_get(&mpxy);
+ if (rc)
+ return rc;
+ sdata = mpxy->shmem;
do {
sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_GET_CHANNEL_IDS,
start_index, 0, 0, 0, 0, 0);
- if (sret.error)
- goto err_put_cpu;
+ if (sret.error) {
+ rc = sbi_err_map_linux_errno(sret.error);
+ goto out;
+ }
remaining = le32_to_cpu(sdata->remaining);
returned = le32_to_cpu(sdata->returned);
@@ -107,56 +135,60 @@ int sbi_mpxy_get_channel_ids(u32 channel_count, u32 *channel_ids)
start_index += count;
} while (remaining && start_index < channel_count);
-err_put_cpu:
- put_cpu();
- return sbi_err_map_linux_errno(sret.error);
+out:
+ mpxy_local_put();
+ return rc;
}
EXPORT_SYMBOL_GPL(sbi_mpxy_get_channel_ids);
int sbi_mpxy_read_attrs(u32 channel_id, u32 base_attrid, u32 attr_count,
u32 *attrs_buf)
{
- struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ struct mpxy_local *mpxy;
struct sbiret sret;
+ int rc = 0;
- if (!mpxy->shmem_active)
- return -ENODEV;
if (!attr_count || !attrs_buf)
return -EINVAL;
- get_cpu();
+ rc = mpxy_local_get(&mpxy);
+ if (rc)
+ return rc;
sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_READ_ATTRS,
channel_id, base_attrid, attr_count, 0, 0, 0);
- if (sret.error)
- goto err_put_cpu;
+ if (sret.error) {
+ rc = sbi_err_map_linux_errno(sret.error);
+ goto out;
+ }
memcpy_from_le32(attrs_buf, (__le32 *)mpxy->shmem, attr_count);
-err_put_cpu:
- put_cpu();
- return sbi_err_map_linux_errno(sret.error);
+out:
+ mpxy_local_put();
+ return rc;
}
EXPORT_SYMBOL_GPL(sbi_mpxy_read_attrs);
int sbi_mpxy_write_attrs(u32 channel_id, u32 base_attrid, u32 attr_count,
u32 *attrs_buf)
{
- struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ struct mpxy_local *mpxy;
struct sbiret sret;
+ int rc = 0;
- if (!mpxy->shmem_active)
- return -ENODEV;
if (!attr_count || !attrs_buf)
return -EINVAL;
- get_cpu();
+ rc = mpxy_local_get(&mpxy);
+ if (rc)
+ return rc;
memcpy_to_le32((__le32 *)mpxy->shmem, attrs_buf, attr_count);
sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_WRITE_ATTRS,
channel_id, base_attrid, attr_count, 0, 0, 0);
- put_cpu();
+ mpxy_local_put();
return sbi_err_map_linux_errno(sret.error);
}
EXPORT_SYMBOL_GPL(sbi_mpxy_write_attrs);
@@ -166,16 +198,17 @@ int sbi_mpxy_send_message_with_resp(u32 channel_id, u32 msg_id,
void *rx, unsigned long max_rx_len,
unsigned long *rx_len)
{
- struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ struct mpxy_local *mpxy;
unsigned long rx_bytes;
struct sbiret sret;
+ int rc = 0;
- if (!mpxy->shmem_active)
- return -ENODEV;
if (!tx && tx_len)
return -EINVAL;
- get_cpu();
+ rc = mpxy_local_get(&mpxy);
+ if (rc)
+ return rc;
/* Message protocols allowed to have no data in messages */
if (tx_len)
@@ -186,8 +219,8 @@ int sbi_mpxy_send_message_with_resp(u32 channel_id, u32 msg_id,
if (rx && !sret.error) {
rx_bytes = sret.value;
if (rx_bytes > max_rx_len) {
- put_cpu();
- return -ENOSPC;
+ rc = -ENOSPC;
+ goto out;
}
memcpy(rx, mpxy->shmem, rx_bytes);
@@ -195,23 +228,26 @@ int sbi_mpxy_send_message_with_resp(u32 channel_id, u32 msg_id,
*rx_len = rx_bytes;
}
- put_cpu();
- return sbi_err_map_linux_errno(sret.error);
+ rc = sbi_err_map_linux_errno(sret.error);
+out:
+ mpxy_local_put();
+ return rc;
}
EXPORT_SYMBOL_GPL(sbi_mpxy_send_message_with_resp);
int sbi_mpxy_send_message_without_resp(u32 channel_id, u32 msg_id,
void *tx, unsigned long tx_len)
{
- struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ struct mpxy_local *mpxy;
struct sbiret sret;
+ int rc = 0;
- if (!mpxy->shmem_active)
- return -ENODEV;
if (!tx && tx_len)
return -EINVAL;
- get_cpu();
+ rc = mpxy_local_get(&mpxy);
+ if (rc)
+ return rc;
/* Message protocols allowed to have no data in messages */
if (tx_len)
@@ -220,8 +256,9 @@ int sbi_mpxy_send_message_without_resp(u32 channel_id, u32 msg_id,
sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_SEND_MSG_WITHOUT_RESP,
channel_id, msg_id, tx_len, 0, 0, 0);
- put_cpu();
- return sbi_err_map_linux_errno(sret.error);
+ rc = sbi_err_map_linux_errno(sret.error);
+ mpxy_local_put();
+ return rc;
}
EXPORT_SYMBOL_GPL(sbi_mpxy_send_message_without_resp);
@@ -229,32 +266,36 @@ int sbi_mpxy_get_notifications(u32 channel_id,
struct sbi_mpxy_notification_data *notif_data,
unsigned long *events_data_len)
{
- struct mpxy_local *mpxy = this_cpu_ptr(&mpxy_local);
+ struct mpxy_local *mpxy;
struct sbiret sret;
+ int rc = 0;
- if (!mpxy->shmem_active)
- return -ENODEV;
if (!notif_data || !events_data_len)
return -EINVAL;
- get_cpu();
+ rc = mpxy_local_get(&mpxy);
+ if (rc)
+ return rc;
sret = sbi_ecall(SBI_EXT_MPXY, SBI_EXT_MPXY_GET_NOTIFICATION_EVENTS,
channel_id, 0, 0, 0, 0, 0);
- if (sret.error)
- goto err_put_cpu;
+ if (sret.error) {
+ rc = sbi_err_map_linux_errno(sret.error);
+ goto out;
+ }
if (sret.value < 0 || mpxy_shmem_size < sizeof(*notif_data) ||
sret.value > mpxy_shmem_size - sizeof(*notif_data)) {
- put_cpu();
- return -EOVERFLOW;
+ rc = -EOVERFLOW;
+ goto out;
}
memcpy(notif_data, mpxy->shmem, sret.value + sizeof(*notif_data));
*events_data_len = sret.value;
-err_put_cpu:
- put_cpu();
- return sbi_err_map_linux_errno(sret.error);
+ rc = sbi_err_map_linux_errno(sret.error);
+out:
+ mpxy_local_put();
+ return rc;
}
EXPORT_SYMBOL_GPL(sbi_mpxy_get_notifications);
--
2.43.0
next prev parent reply other threads:[~2026-09-30 15:21 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-30 15:02 [PATCH 0/4] Parallel message send using SBI MPXY Anup Patel
2026-09-30 15:02 ` [PATCH 1/4] RISC-V: Move common MPXY helper routines to arch/riscv Anup Patel
2026-09-30 15:30 ` sashiko-bot
2026-09-30 15:02 ` Anup Patel [this message]
2026-09-30 15:02 ` [PATCH 3/4] mailbox: add direct synchronous send support Anup Patel
2026-09-30 15:02 ` [PATCH 4/4] mailbox: riscv-sbi-mpxy: Move to send_data_sync() for sending messages Anup Patel
2026-09-30 15:38 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260930150213.799245-3-anup.patel@oss.qualcomm.com \
--to=anup.patel@oss.qualcomm.com \
--cc=amirreza.zarrabi@oss.qualcomm.com \
--cc=anup@brainfault.org \
--cc=atish.patra@linux.dev \
--cc=bmasney+clk@redhat.com \
--cc=hchauhan@ventanamicro.com \
--cc=jassisinghbrar@gmail.com \
--cc=jbrunet+clk@baylibre.com \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=radu@rendec.net \
--cc=rahul@summations.net \
--cc=sboyd@kernel.org \
--cc=tglx@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox