On 11/27/2025 9:07 PM, Stefan Roese wrote:
Testing on our ZynqMP platform has shown, that some R5 messages might
get dropped under high CPU load. This patch creates a new high-prio
workqueue which is now used instead of the default system workqueue.
With this change we don't experience these message drops any more.

Signed-off-by: Stefan Roese <[email protected]>
Cc: Tanmay Shah <[email protected]>
Cc: Mathieu Poirier <[email protected]>
---
  drivers/remoteproc/xlnx_r5_remoteproc.c | 21 ++++++++++++++++++++-
  1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c 
b/drivers/remoteproc/xlnx_r5_remoteproc.c
index feca6de68da28..459373901c973 100644
--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -16,6 +16,7 @@
  #include <linux/of_reserved_mem.h>
  #include <linux/platform_device.h>
  #include <linux/remoteproc.h>
+#include <linux/workqueue.h>
#include "remoteproc_internal.h" @@ -116,6 +117,7 @@ struct zynqmp_r5_cluster {
        enum  zynqmp_r5_cluster_mode mode;
        int core_count;
        struct zynqmp_r5_core **r5_cores;
+       struct workqueue_struct *workqueue;
  };
/**
@@ -174,10 +176,18 @@ static void handle_event_notified(struct work_struct 
*work)
  static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void *msg)
  {
        struct zynqmp_ipi_message *ipi_msg, *buf_msg;
+       struct zynqmp_r5_cluster *cluster;
        struct mbox_info *ipi;
+       struct device *dev;
        size_t len;
ipi = container_of(cl, struct mbox_info, mbox_cl);
+       dev = ipi->r5_core->dev;
+       cluster = dev_get_drvdata(dev->parent);
+       if (!cluster) {
+               dev_err(dev->parent, "Invalid driver data\n");
+               return;
+       }
/* copy data from ipi buffer to r5_core */
        ipi_msg = (struct zynqmp_ipi_message *)msg;
@@ -195,7 +205,7 @@ static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void 
*msg)
        if (mbox_send_message(ipi->rx_chan, NULL) < 0)
                dev_err(cl->dev, "ack failed to mbox rx_chan\n");
- schedule_work(&ipi->mbox_work);
+       queue_work(cluster->workqueue, &ipi->mbox_work);
  }
/**
@@ -1194,12 +1204,21 @@ static int zynqmp_r5_remoteproc_probe(struct 
platform_device *pdev)
                return ret;
        }
+ cluster->workqueue = alloc_workqueue(dev_name(dev),

Hi Stefan,

destroy_workqueue() should also be invoked in zynqmp_r5_cluster_exit() to prevent resource leaks, right?


+                                            WQ_UNBOUND | WQ_HIGHPRI, 0);
+       if (!cluster->workqueue) {
+               dev_err_probe(dev, -ENOMEM, "cannot create workqueue\n");
+               kfree(cluster);
+               return -ENOMEM;
+       }
+
        /* wire in so each core can be cleaned up at driver remove */
        platform_set_drvdata(pdev, cluster);
ret = zynqmp_r5_cluster_init(cluster);
        if (ret) {
                kfree(cluster);
+               destroy_workqueue(cluster->workqueue);

Please adjust the call seq to avoid UAF.

                platform_set_drvdata(pdev, NULL);
                dev_err_probe(dev, ret, "Invalid r5f subsystem device tree\n");
                return ret;


--
Thx and BRs,
Zhongqiu Han

Reply via email to