diff mbox series

firmware: arm_ffa: Avoid queuing work when running on the worker queue

Message ID 20240424131640.706870-1-sudeep.holla@arm.com (mailing list archive)
State New, archived
Headers show
Series firmware: arm_ffa: Avoid queuing work when running on the worker queue | expand

Commit Message

Sudeep Holla April 24, 2024, 1:16 p.m. UTC
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.

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
---
 drivers/firmware/arm_ffa/driver.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

Comments

Sudeep Holla April 26, 2024, 10:49 a.m. UTC | #1
On Wed, 24 Apr 2024 14:16:40 +0100, Sudeep Holla wrote:
> 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.
>
> [...]

Applied to sudeep.holla/linux (for-linux-next), thanks!

[1/1] firmware: arm_ffa: Avoid queuing work when running on the worker queue
      https://git.kernel.org/sudeep.holla/c/3a3e2b83e805
--
Regards,
Sudeep
diff mbox series

Patch

diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 26968edac5b2..30a48b9398e1 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;
 }