From 9d099b501a8c590317b4935f4a944ee8b58fcc34 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Fri, 9 Oct 2020 13:26:07 -0700 Subject: [PATCH 1/2] mailbox: msm_qmp: Enhance debug logging There are an increasing amount of reports where the tx timeout is being asserted. Add logging to mark the enter and exit of the qmp worker thread in ipc logs to correlate with the rx interrupts. Change-Id: Ie24ab7ac761b16abfeeef78bbb3907e781b6f79d Signed-off-by: Chris Lew --- drivers/mailbox/msm_qmp.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/mailbox/msm_qmp.c b/drivers/mailbox/msm_qmp.c index 2085986fa194..6084e34ac439 100644 --- a/drivers/mailbox/msm_qmp.c +++ b/drivers/mailbox/msm_qmp.c @@ -215,6 +215,8 @@ struct qmp_device { */ static void send_irq(struct qmp_device *mdev) { + int ret; + /* * Any data associated with this event must be visable to the remote * before the interrupt is triggered @@ -222,8 +224,11 @@ static void send_irq(struct qmp_device *mdev) wmb(); if (mdev->mbox_chan) { - mbox_send_message(mdev->mbox_chan, NULL); + ret = mbox_send_message(mdev->mbox_chan, NULL); mbox_client_txdone(mdev->mbox_chan, 0); + + if (ret < 0) + QMP_ERR(mdev->ilc, "failed to trigger ipcc irq %d\n", ret); } else { writel_relaxed(mdev->irq_mask, mdev->tx_irq_reg); } @@ -527,6 +532,7 @@ static irqreturn_t qmp_irq_handler(int irq, void *priv) kthread_queue_work(&mdev->kworker, &mdev->kwork); mdev->rx_irq_count++; + QMP_INFO(mdev->ilc, "Queued rx worker count:%d\n", mdev->rx_irq_count); return IRQ_HANDLED; } @@ -542,9 +548,12 @@ static void __qmp_rx_worker(struct qmp_mbox *mbox) struct qmp_device *mdev = mbox->mdev; unsigned long flags; + QMP_INFO(mdev->ilc, "Enter rx worker state:%d\n", mbox->local_state); memcpy_fromio(&desc, mbox->desc, sizeof(desc)); - if (desc.magic != QMP_MAGIC) + if (desc.magic != QMP_MAGIC) { + QMP_ERR(mdev->ilc, "wrong magic 0x:%x\n", desc.magic); return; + } mutex_lock(&mbox->state_lock); switch (mbox->local_state) { @@ -660,6 +669,7 @@ static void __qmp_rx_worker(struct qmp_mbox *mbox) default: QMP_ERR(mdev->ilc, "Local Channel State corrupted\n"); } + QMP_INFO(mdev->ilc, "Exit rx worker state:%d\n", mbox->local_state); mutex_unlock(&mbox->state_lock); } From f2197a20e8f7109c9b5035d5c640d3fbd4bc6a16 Mon Sep 17 00:00:00 2001 From: Chris Lew Date: Fri, 6 Nov 2020 14:37:02 -0800 Subject: [PATCH 2/2] soc: qcom: smp2p: Add memory barrier for irq_pending There is a very tight race where the irq_retrigger function is run on one cpu and the actual retrigger softirq is running on a second cpu. When this happens, there may be a chance that the second cpu will not see the updated irq_pending value from first cpu. Add a memory barrier to ensure that irq_pending is read correctly. Change-Id: I3dd185decc4f050bd57c0b6558f417ead2a3aa5a Signed-off-by: Chris Lew --- drivers/soc/qcom/smp2p.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index 468de2dddfdb..f87af11fde98 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -270,6 +270,9 @@ static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p) status = val ^ entry->last_value; entry->last_value = val; + + /* Ensure irq_pending is read correctly */ + mb(); status |= *entry->irq_pending; SMP2P_INFO("%d:\t%s: status:%0lx val:%0x\n", @@ -391,6 +394,11 @@ static int smp2p_retrigger_irq(struct irq_data *irqd) SMP2P_INFO("%d: %s: %lu\n", entry->smp2p->remote_pid, entry->name, irq); set_bit(irq, entry->irq_pending); + /* Ensure irq_pending is visible to all cpus that retried interrupt + * can run on + */ + mb(); + return 0; }