Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] ASoC: SOF: Intel: Harden the IPC4 low level sequencing
@ 2022-10-18 12:40 Peter Ujfalusi
  2022-10-18 12:40 ` [PATCH 1/4] ASoC: SOF: ipc4: Log the tx message before sending it Peter Ujfalusi
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Peter Ujfalusi @ 2022-10-18 12:40 UTC (permalink / raw)
  To: lgirdwood, broonie
  Cc: alsa-devel, rander.wang, pierre-louis.bossart, kai.vehmanen,
	ranjani.sridharan

Hi,

The IPC4 use of doorbell registers leaves some corner cases not well defined
and the 'correct sequences' are subjective in a sense.
The DSP doorbell registers are used as separate and independent channels and
the sequences for host -> DSP -> host (reply) can be racy.

For example:
The ACKing of a received message can happen before the firmware sends the reply
or it can as well happen after the reply has been sent and received by the host.
Both can be considered 'correct sequences' but they need different handling.

This series will allow the kernel to service any interpretation of the
sequencing on the firmware side.

Regards,
Peter
---
Peter Ujfalusi (4):
  ASoC: SOF: ipc4: Log the tx message before sending it
  ASoC: SOF: Intel: ipc4: Read the interrupt reason registers at the
    same time
  ASoC: SOF: Intel: ipc4: Wait for channel to be free before sending a
    message
  ASoC: SOF: Intel: ipc4: Ack a received reply or notification
    separately

 sound/soc/sof/intel/cnl.c     | 26 ++++++++++++++++++++++----
 sound/soc/sof/intel/hda-ipc.c | 27 +++++++++++++++++++++++----
 sound/soc/sof/intel/hda.c     | 11 +++++++++++
 sound/soc/sof/intel/hda.h     |  9 +++++++++
 sound/soc/sof/intel/mtl.c     | 24 +++++++++++++++++++++---
 sound/soc/sof/ipc4.c          |  4 ++--
 6 files changed, 88 insertions(+), 13 deletions(-)

-- 
2.38.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] ASoC: SOF: ipc4: Log the tx message before sending it
  2022-10-18 12:40 [PATCH 0/4] ASoC: SOF: Intel: Harden the IPC4 low level sequencing Peter Ujfalusi
@ 2022-10-18 12:40 ` Peter Ujfalusi
  2022-10-18 12:40 ` [PATCH 2/4] ASoC: SOF: Intel: ipc4: Read the interrupt reason registers at the same time Peter Ujfalusi
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Peter Ujfalusi @ 2022-10-18 12:40 UTC (permalink / raw)
  To: lgirdwood, broonie
  Cc: alsa-devel, rander.wang, pierre-louis.bossart, kai.vehmanen,
	ranjani.sridharan

It makes more sense to log the message before it is sent to the DSP.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
---
 sound/soc/sof/ipc4.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c
index 6eaa18e27e5a..3c9b8692984a 100644
--- a/sound/soc/sof/ipc4.c
+++ b/sound/soc/sof/ipc4.c
@@ -342,6 +342,8 @@ static int ipc4_tx_msg_unlocked(struct snd_sof_ipc *ipc,
 	if (msg_bytes > ipc->max_payload_size || reply_bytes > ipc->max_payload_size)
 		return -EINVAL;
 
+	sof_ipc4_log_header(sdev->dev, "ipc tx      ", msg_data, true);
+
 	ret = sof_ipc_send_msg(sdev, msg_data, msg_bytes, reply_bytes);
 	if (ret) {
 		dev_err_ratelimited(sdev->dev,
@@ -350,8 +352,6 @@ static int ipc4_tx_msg_unlocked(struct snd_sof_ipc *ipc,
 		return ret;
 	}
 
-	sof_ipc4_log_header(sdev->dev, "ipc tx      ", msg_data, true);
-
 	/* now wait for completion */
 	return ipc4_wait_tx_done(ipc, reply_data);
 }
-- 
2.38.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] ASoC: SOF: Intel: ipc4: Read the interrupt reason registers at the same time
  2022-10-18 12:40 [PATCH 0/4] ASoC: SOF: Intel: Harden the IPC4 low level sequencing Peter Ujfalusi
  2022-10-18 12:40 ` [PATCH 1/4] ASoC: SOF: ipc4: Log the tx message before sending it Peter Ujfalusi
@ 2022-10-18 12:40 ` Peter Ujfalusi
  2022-10-18 12:40 ` [PATCH 3/4] ASoC: SOF: Intel: ipc4: Wait for channel to be free before sending a message Peter Ujfalusi
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Peter Ujfalusi @ 2022-10-18 12:40 UTC (permalink / raw)
  To: lgirdwood, broonie
  Cc: alsa-devel, rander.wang, pierre-louis.bossart, kai.vehmanen,
	ranjani.sridharan

Read both registers as the first step in the interrupt handler to make
sure that we are handling the event which triggered the interrupt.

The delayed reading of the target request register might reflect incorrect
information about the reason why the interrupt was risen.

Note also that the IPC3 interrupt handler is implemented in this way also.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
---
 sound/soc/sof/intel/cnl.c     | 2 +-
 sound/soc/sof/intel/hda-ipc.c | 3 ++-
 sound/soc/sof/intel/mtl.c     | 2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index 19d0b1909bfd..2f2bcde42759 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -41,6 +41,7 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
 	u32 hipcida, hipctdr;
 
 	hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDA);
+	hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDR);
 	if (hipcida & CNL_DSP_REG_HIPCIDA_DONE) {
 		/* DSP received the message */
 		snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR,
@@ -51,7 +52,6 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
 		ipc_irq = true;
 	}
 
-	hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDR);
 	if (hipctdr & CNL_DSP_REG_HIPCTDR_BUSY) {
 		/* Message from DSP (reply or notification) */
 		u32 hipctdd = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c
index 9b3667c705e4..4118532faf3f 100644
--- a/sound/soc/sof/intel/hda-ipc.c
+++ b/sound/soc/sof/intel/hda-ipc.c
@@ -126,6 +126,8 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
 	u32 hipcie, hipct;
 
 	hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCIE);
+	hipct = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCT);
+
 	if (hipcie & HDA_DSP_REG_HIPCIE_DONE) {
 		/* DSP received the message */
 		snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCCTL,
@@ -135,7 +137,6 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
 		ipc_irq = true;
 	}
 
-	hipct = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCT);
 	if (hipct & HDA_DSP_REG_HIPCT_BUSY) {
 		/* Message from DSP (reply or notification) */
 		u32 hipcte = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c
index 10298532816f..a9b31b31a4e4 100644
--- a/sound/soc/sof/intel/mtl.c
+++ b/sound/soc/sof/intel/mtl.c
@@ -497,6 +497,7 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
 	u32 hipctdr;
 
 	hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA);
+	hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR);
 
 	/* reply message from DSP */
 	if (hipcida & MTL_DSP_REG_HFIPCXIDA_DONE) {
@@ -509,7 +510,6 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
 		ipc_irq = true;
 	}
 
-	hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR);
 	if (hipctdr & MTL_DSP_REG_HFIPCXTDR_BUSY) {
 		/* Message from DSP (reply or notification) */
 		u32 extension = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDDY);
-- 
2.38.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] ASoC: SOF: Intel: ipc4: Wait for channel to be free before sending a message
  2022-10-18 12:40 [PATCH 0/4] ASoC: SOF: Intel: Harden the IPC4 low level sequencing Peter Ujfalusi
  2022-10-18 12:40 ` [PATCH 1/4] ASoC: SOF: ipc4: Log the tx message before sending it Peter Ujfalusi
  2022-10-18 12:40 ` [PATCH 2/4] ASoC: SOF: Intel: ipc4: Read the interrupt reason registers at the same time Peter Ujfalusi
@ 2022-10-18 12:40 ` Peter Ujfalusi
  2022-10-18 12:40 ` [PATCH 4/4] ASoC: SOF: Intel: ipc4: Ack a received reply or notification separately Peter Ujfalusi
  2022-10-19 14:18 ` [PATCH 0/4] ASoC: SOF: Intel: Harden the IPC4 low level sequencing Mark Brown
  4 siblings, 0 replies; 6+ messages in thread
From: Peter Ujfalusi @ 2022-10-18 12:40 UTC (permalink / raw)
  To: lgirdwood, broonie
  Cc: alsa-devel, rander.wang, pierre-louis.bossart, kai.vehmanen,
	ranjani.sridharan

Before attempting to send a message to the DSP we need to check if the
downstream BUSY flag has been cleared by the firmware to avoid lost IPC
messages by the firmware.

This is required by a firmware which only acks the received message after
it has sent a reply to the host.
With a bad luck, the host would send a message before the firmware gets to
the clearing the flag and thus losing a message.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
---
 sound/soc/sof/intel/cnl.c     | 17 +++++++++++++++++
 sound/soc/sof/intel/hda-ipc.c | 17 +++++++++++++++++
 sound/soc/sof/intel/hda.c     | 11 +++++++++++
 sound/soc/sof/intel/hda.h     |  9 +++++++++
 sound/soc/sof/intel/mtl.c     | 17 +++++++++++++++++
 5 files changed, 71 insertions(+)

diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index 2f2bcde42759..4bf233787757 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -37,6 +37,7 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
 {
 	struct sof_ipc4_msg notification_data = {{ 0 }};
 	struct snd_sof_dev *sdev = context;
+	bool ack_received = false;
 	bool ipc_irq = false;
 	u32 hipcida, hipctdr;
 
@@ -50,6 +51,7 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
 		cnl_ipc_dsp_done(sdev);
 
 		ipc_irq = true;
+		ack_received = true;
 	}
 
 	if (hipctdr & CNL_DSP_REG_HIPCTDR_BUSY) {
@@ -98,6 +100,13 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
 		/* This interrupt is not shared so no need to return IRQ_NONE. */
 		dev_dbg_ratelimited(sdev->dev, "nothing to do in IPC IRQ thread\n");
 
+	if (ack_received) {
+		struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
+
+		if (hdev->delayed_ipc_tx_msg)
+			cnl_ipc4_send_msg(sdev, hdev->delayed_ipc_tx_msg);
+	}
+
 	return IRQ_HANDLED;
 }
 
@@ -251,8 +260,16 @@ static bool cnl_compact_ipc_compress(struct snd_sof_ipc_msg *msg,
 
 int cnl_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
 {
+	struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
 	struct sof_ipc4_msg *msg_data = msg->msg_data;
 
+	if (hda_ipc4_tx_is_busy(sdev)) {
+		hdev->delayed_ipc_tx_msg = msg;
+		return 0;
+	}
+
+	hdev->delayed_ipc_tx_msg = NULL;
+
 	/* send the message via mailbox */
 	if (msg_data->data_size)
 		sof_mailbox_write(sdev, sdev->host_box.offset, msg_data->data_ptr,
diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c
index 4118532faf3f..b4668c969a29 100644
--- a/sound/soc/sof/intel/hda-ipc.c
+++ b/sound/soc/sof/intel/hda-ipc.c
@@ -69,8 +69,16 @@ int hda_dsp_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
 
 int hda_dsp_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
 {
+	struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
 	struct sof_ipc4_msg *msg_data = msg->msg_data;
 
+	if (hda_ipc4_tx_is_busy(sdev)) {
+		hdev->delayed_ipc_tx_msg = msg;
+		return 0;
+	}
+
+	hdev->delayed_ipc_tx_msg = NULL;
+
 	/* send the message via mailbox */
 	if (msg_data->data_size)
 		sof_mailbox_write(sdev, sdev->host_box.offset, msg_data->data_ptr,
@@ -122,6 +130,7 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
 {
 	struct sof_ipc4_msg notification_data = {{ 0 }};
 	struct snd_sof_dev *sdev = context;
+	bool ack_received = false;
 	bool ipc_irq = false;
 	u32 hipcie, hipct;
 
@@ -135,6 +144,7 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
 		hda_dsp_ipc_dsp_done(sdev);
 
 		ipc_irq = true;
+		ack_received = true;
 	}
 
 	if (hipct & HDA_DSP_REG_HIPCT_BUSY) {
@@ -187,6 +197,13 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
 		/* This interrupt is not shared so no need to return IRQ_NONE. */
 		dev_dbg_ratelimited(sdev->dev, "nothing to do in IPC IRQ thread\n");
 
+	if (ack_received) {
+		struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
+
+		if (hdev->delayed_ipc_tx_msg)
+			hda_dsp_ipc4_send_msg(sdev, hdev->delayed_ipc_tx_msg);
+	}
+
 	return IRQ_HANDLED;
 }
 
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 1188ec51816b..eddd20beea0d 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -681,6 +681,17 @@ void hda_ipc4_dump(struct snd_sof_dev *sdev)
 		hipci, hipcie, hipct, hipcte, hipcctl);
 }
 
+bool hda_ipc4_tx_is_busy(struct snd_sof_dev *sdev)
+{
+	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
+	const struct sof_intel_dsp_desc *chip = hda->desc;
+	u32 val;
+
+	val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, chip->ipc_req);
+
+	return !!(val & chip->ipc_req_mask);
+}
+
 static int hda_init(struct snd_sof_dev *sdev)
 {
 	struct hda_bus *hbus;
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 2ab3c3840b92..65657d145dc2 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -521,6 +521,14 @@ struct sof_intel_hda_dev {
 
 	/* Intel NHLT information */
 	struct nhlt_acpi_table *nhlt;
+
+	/*
+	 * Pointing to the IPC message if immediate sending was not possible
+	 * because the downlink communication channel was BUSY at the time.
+	 * The message will be re-tried when the channel becomes free (the ACK
+	 * is received from the DSP for the previous message)
+	 */
+	struct snd_sof_ipc_msg *delayed_ipc_tx_msg;
 };
 
 static inline struct hdac_bus *sof_to_bus(struct snd_sof_dev *s)
@@ -852,6 +860,7 @@ int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask);
 irqreturn_t cnl_ipc4_irq_thread(int irq, void *context);
 int cnl_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg);
 irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context);
+bool hda_ipc4_tx_is_busy(struct snd_sof_dev *sdev);
 int hda_dsp_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg);
 void hda_ipc4_dump(struct snd_sof_dev *sdev);
 extern struct sdw_intel_ops sdw_callback;
diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c
index a9b31b31a4e4..9d1bc74395e7 100644
--- a/sound/soc/sof/intel/mtl.c
+++ b/sound/soc/sof/intel/mtl.c
@@ -90,8 +90,16 @@ static bool mtl_dsp_check_sdw_irq(struct snd_sof_dev *sdev)
 
 static int mtl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
 {
+	struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
 	struct sof_ipc4_msg *msg_data = msg->msg_data;
 
+	if (hda_ipc4_tx_is_busy(sdev)) {
+		hdev->delayed_ipc_tx_msg = msg;
+		return 0;
+	}
+
+	hdev->delayed_ipc_tx_msg = NULL;
+
 	/* send the message via mailbox */
 	if (msg_data->data_size)
 		sof_mailbox_write(sdev, sdev->host_box.offset, msg_data->data_ptr,
@@ -492,6 +500,7 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
 {
 	struct sof_ipc4_msg notification_data = {{ 0 }};
 	struct snd_sof_dev *sdev = context;
+	bool ack_received = false;
 	bool ipc_irq = false;
 	u32 hipcida;
 	u32 hipctdr;
@@ -508,6 +517,7 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
 		mtl_ipc_dsp_done(sdev);
 
 		ipc_irq = true;
+		ack_received = true;
 	}
 
 	if (hipctdr & MTL_DSP_REG_HFIPCXTDR_BUSY) {
@@ -558,6 +568,13 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
 		dev_dbg_ratelimited(sdev->dev, "nothing to do in IPC IRQ thread\n");
 	}
 
+	if (ack_received) {
+		struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
+
+		if (hdev->delayed_ipc_tx_msg)
+			mtl_ipc_send_msg(sdev, hdev->delayed_ipc_tx_msg);
+	}
+
 	return IRQ_HANDLED;
 }
 
-- 
2.38.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] ASoC: SOF: Intel: ipc4: Ack a received reply or notification separately
  2022-10-18 12:40 [PATCH 0/4] ASoC: SOF: Intel: Harden the IPC4 low level sequencing Peter Ujfalusi
                   ` (2 preceding siblings ...)
  2022-10-18 12:40 ` [PATCH 3/4] ASoC: SOF: Intel: ipc4: Wait for channel to be free before sending a message Peter Ujfalusi
@ 2022-10-18 12:40 ` Peter Ujfalusi
  2022-10-19 14:18 ` [PATCH 0/4] ASoC: SOF: Intel: Harden the IPC4 low level sequencing Mark Brown
  4 siblings, 0 replies; 6+ messages in thread
From: Peter Ujfalusi @ 2022-10-18 12:40 UTC (permalink / raw)
  To: lgirdwood, broonie
  Cc: alsa-devel, rander.wang, pierre-louis.bossart, kai.vehmanen,
	ranjani.sridharan

By acking a received message we tell the DSP that we have processed the
message (reply or notification) and we are open to receive a new one.

The original implementation did this in a common code after the received
message got handled as reply or notification.

With right timing this opens up a small window when we have processed the
reply and let the other thread proceed to send a new message to the DSP,
which is allowed as the DSP is free to receive message.
But when the message is received and processed by the DSP and it wants to
send a reply it will still see that the previous message has not been
acked, so it fails to send a reply. Later the first reply got acked by the
kernel, but it is too late and the in-flight message got a timeout due to
firmware not responding (which it tried, but could not).

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
---
 sound/soc/sof/intel/cnl.c     | 7 ++++---
 sound/soc/sof/intel/hda-ipc.c | 7 ++++---
 sound/soc/sof/intel/mtl.c     | 5 +++--
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index 4bf233787757..da26f0ce9abc 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -72,6 +72,7 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
 				spin_lock_irq(&sdev->ipc_lock);
 
 				snd_sof_ipc_get_reply(sdev);
+				cnl_ipc_host_done(sdev);
 				snd_sof_ipc_reply(sdev, data->primary);
 
 				spin_unlock_irq(&sdev->ipc_lock);
@@ -88,10 +89,10 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context)
 			sdev->ipc->msg.rx_data = &notification_data;
 			snd_sof_ipc_msgs_rx(sdev);
 			sdev->ipc->msg.rx_data = NULL;
-		}
 
-		/* Let DSP know that we have finished processing the message */
-		cnl_ipc_host_done(sdev);
+			/* Let DSP know that we have finished processing the message */
+			cnl_ipc_host_done(sdev);
+		}
 
 		ipc_irq = true;
 	}
diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c
index b4668c969a29..a7c454e03952 100644
--- a/sound/soc/sof/intel/hda-ipc.c
+++ b/sound/soc/sof/intel/hda-ipc.c
@@ -169,6 +169,7 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
 				spin_lock_irq(&sdev->ipc_lock);
 
 				snd_sof_ipc_get_reply(sdev);
+				hda_dsp_ipc_host_done(sdev);
 				snd_sof_ipc_reply(sdev, data->primary);
 
 				spin_unlock_irq(&sdev->ipc_lock);
@@ -185,10 +186,10 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context)
 			sdev->ipc->msg.rx_data = &notification_data;
 			snd_sof_ipc_msgs_rx(sdev);
 			sdev->ipc->msg.rx_data = NULL;
-		}
 
-		/* Let DSP know that we have finished processing the message */
-		hda_dsp_ipc_host_done(sdev);
+			/* Let DSP know that we have finished processing the message */
+			hda_dsp_ipc_host_done(sdev);
+		}
 
 		ipc_irq = true;
 	}
diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c
index 9d1bc74395e7..054b9ab721ff 100644
--- a/sound/soc/sof/intel/mtl.c
+++ b/sound/soc/sof/intel/mtl.c
@@ -540,6 +540,7 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
 				spin_lock_irq(&sdev->ipc_lock);
 
 				snd_sof_ipc_get_reply(sdev);
+				mtl_ipc_host_done(sdev);
 				snd_sof_ipc_reply(sdev, data->primary);
 
 				spin_unlock_irq(&sdev->ipc_lock);
@@ -556,9 +557,9 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context)
 			sdev->ipc->msg.rx_data = &notification_data;
 			snd_sof_ipc_msgs_rx(sdev);
 			sdev->ipc->msg.rx_data = NULL;
-		}
 
-		mtl_ipc_host_done(sdev);
+			mtl_ipc_host_done(sdev);
+		}
 
 		ipc_irq = true;
 	}
-- 
2.38.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] ASoC: SOF: Intel: Harden the IPC4 low level sequencing
  2022-10-18 12:40 [PATCH 0/4] ASoC: SOF: Intel: Harden the IPC4 low level sequencing Peter Ujfalusi
                   ` (3 preceding siblings ...)
  2022-10-18 12:40 ` [PATCH 4/4] ASoC: SOF: Intel: ipc4: Ack a received reply or notification separately Peter Ujfalusi
@ 2022-10-19 14:18 ` Mark Brown
  4 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2022-10-19 14:18 UTC (permalink / raw)
  To: lgirdwood, Peter Ujfalusi
  Cc: pierre-louis.bossart, alsa-devel, ranjani.sridharan, kai.vehmanen,
	rander.wang

On Tue, 18 Oct 2022 15:40:04 +0300, Peter Ujfalusi wrote:
> The IPC4 use of doorbell registers leaves some corner cases not well defined
> and the 'correct sequences' are subjective in a sense.
> The DSP doorbell registers are used as separate and independent channels and
> the sequences for host -> DSP -> host (reply) can be racy.
> 
> For example:
> The ACKing of a received message can happen before the firmware sends the reply
> or it can as well happen after the reply has been sent and received by the host.
> Both can be considered 'correct sequences' but they need different handling.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/4] ASoC: SOF: ipc4: Log the tx message before sending it
      commit: 2d91d5715f5f3b24456ede20dbbe967a1d2a0a3e
[2/4] ASoC: SOF: Intel: ipc4: Read the interrupt reason registers at the same time
      commit: c8ed7ce242db83ca2c4e9eab557a88adbae5ef6a
[3/4] ASoC: SOF: Intel: ipc4: Wait for channel to be free before sending a message
      commit: 483e4cdfb502e6bea6b0a226a3ff7c22e60153de
[4/4] ASoC: SOF: Intel: ipc4: Ack a received reply or notification separately
      commit: 010c050fe9ea263e3fc17493822117610a23f662

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-10-19 14:19 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-18 12:40 [PATCH 0/4] ASoC: SOF: Intel: Harden the IPC4 low level sequencing Peter Ujfalusi
2022-10-18 12:40 ` [PATCH 1/4] ASoC: SOF: ipc4: Log the tx message before sending it Peter Ujfalusi
2022-10-18 12:40 ` [PATCH 2/4] ASoC: SOF: Intel: ipc4: Read the interrupt reason registers at the same time Peter Ujfalusi
2022-10-18 12:40 ` [PATCH 3/4] ASoC: SOF: Intel: ipc4: Wait for channel to be free before sending a message Peter Ujfalusi
2022-10-18 12:40 ` [PATCH 4/4] ASoC: SOF: Intel: ipc4: Ack a received reply or notification separately Peter Ujfalusi
2022-10-19 14:18 ` [PATCH 0/4] ASoC: SOF: Intel: Harden the IPC4 low level sequencing Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox