summaryrefslogtreecommitdiff
path: root/drivers/firmware/arm_ffa
diff options
context:
space:
mode:
authorSudeep Holla <sudeep.holla@arm.com>2024-04-24 14:16:40 +0100
committerSudeep Holla <sudeep.holla@arm.com>2024-04-25 12:27:55 +0100
commit3a3e2b83e8059679e92be4273c601ea21e105a89 (patch)
treec7b61f05be21bfc1695280be0f7191a0570f3b08 /drivers/firmware/arm_ffa
parentddfade88f49d49b04930ae006ab0974eb547529c (diff)
firmware: arm_ffa: Avoid queuing work when running on the worker queue
Currently notif_pcpu_irq_work_fn() may get queued from the work that is already running on the 'notif_pcpu_wq' workqueue. This may add unnecessary delays and could be avoided if the work is called directly instead. This change removes queuing of the work when already running on the 'notif_pcpu_wq' workqueue thereby removing any possible delays in that path. Link: https://lore.kernel.org/r/20240424131640.706870-1-sudeep.holla@arm.com Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Diffstat (limited to 'drivers/firmware/arm_ffa')
-rw-r--r--drivers/firmware/arm_ffa/driver.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index b29496cac2af..78abde20ab01 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1146,7 +1146,7 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
}
}
-static void notif_pcpu_irq_work_fn(struct work_struct *work)
+static void notif_get_and_handle(void *unused)
{
int rc;
struct ffa_notify_bitmaps bitmaps;
@@ -1169,10 +1169,17 @@ ffa_self_notif_handle(u16 vcpu, bool is_per_vcpu, void *cb_data)
struct ffa_drv_info *info = cb_data;
if (!is_per_vcpu)
- notif_pcpu_irq_work_fn(&info->notif_pcpu_work);
+ notif_get_and_handle(info);
else
- queue_work_on(vcpu, info->notif_pcpu_wq,
- &info->notif_pcpu_work);
+ smp_call_function_single(vcpu, notif_get_and_handle, info, 0);
+}
+
+static void notif_pcpu_irq_work_fn(struct work_struct *work)
+{
+ struct ffa_drv_info *info = container_of(work, struct ffa_drv_info,
+ notif_pcpu_work);
+
+ ffa_self_notif_handle(smp_processor_id(), true, info);
}
static const struct ffa_info_ops ffa_drv_info_ops = {
@@ -1345,8 +1352,10 @@ static irqreturn_t ffa_sched_recv_irq_handler(int irq, void *irq_data)
static irqreturn_t notif_pend_irq_handler(int irq, void *irq_data)
{
struct ffa_pcpu_irq *pcpu = irq_data;
+ struct ffa_drv_info *info = pcpu->info;
- ffa_self_notif_handle(smp_processor_id(), true, pcpu->info);
+ queue_work_on(smp_processor_id(), info->notif_pcpu_wq,
+ &info->notif_pcpu_work);
return IRQ_HANDLED;
}