Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling
@ 2022-09-19 12:10 Pierre-Louis Bossart
  2022-09-19 12:10 ` [PATCH 1/8] ALSA: hda: make snd_hdac_stream_clear() static Pierre-Louis Bossart
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Pierre-Louis Bossart @ 2022-09-19 12:10 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, Cezary Rojewski, broonie, Pierre-Louis Bossart

This sound/hda/ext library is a confusing magic black box that very
few understand. It needn't be that way, we can document/simplify and
make the code clearer.

Pierre-Louis Bossart (8):
  ALSA: hda: make snd_hdac_stream_clear() static
  ALSA: hda: document state machine for hdac_streams
  ALSA: hda: ext: make snd_hdac_ext_stream_init() static
  ALSA: hda: Use hdac_ext prefix in snd_hdac_stream_free_all() for
    clarity
  ALSA: hda: add snd_hdac_stop_streams() helper
  ALSA: hda: ext: simplify logic for stream assignment
  ALSA: hda: ext: fix locking in stream_release
  ALSA: hda: ext: remove always-true conditions on host and link release

 include/sound/hdaudio.h         |  3 +-
 include/sound/hdaudio_ext.h     |  5 +--
 sound/hda/ext/hdac_ext_stream.c | 34 +++++++--------
 sound/hda/hdac_stream.c         | 74 +++++++++++++++++++++++++++++----
 sound/pci/hda/hda_controller.c  |  4 +-
 sound/soc/intel/avs/core.c      |  4 +-
 sound/soc/intel/skylake/skl.c   |  2 +-
 7 files changed, 87 insertions(+), 39 deletions(-)

-- 
2.34.1


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

* [PATCH 1/8] ALSA: hda: make snd_hdac_stream_clear() static
  2022-09-19 12:10 [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Pierre-Louis Bossart
@ 2022-09-19 12:10 ` Pierre-Louis Bossart
  2022-09-19 12:10 ` [PATCH 2/8] ALSA: hda: document state machine for hdac_streams Pierre-Louis Bossart
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Pierre-Louis Bossart @ 2022-09-19 12:10 UTC (permalink / raw)
  To: alsa-devel
  Cc: Cezary Rojewski, Kai Vehmanen, tiwai, Bard Liao,
	Pierre-Louis Bossart, broonie, Péter Ujfalusi

This helper has no users outside of hdac_stream.c. External users
should only use snd_hdac_stream_start() and snd_hdac_stream_stop().

No functional change beyond making the function static and removing
the symbol export.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 include/sound/hdaudio.h | 1 -
 sound/hda/hdac_stream.c | 5 ++---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 6e74aeafeda41..24c731e53ccb6 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -561,7 +561,6 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev);
 int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
 				unsigned int format_val);
 void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start);
-void snd_hdac_stream_clear(struct hdac_stream *azx_dev);
 void snd_hdac_stream_stop(struct hdac_stream *azx_dev);
 void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus);
 void snd_hdac_stream_reset(struct hdac_stream *azx_dev);
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index bdf6d4db67694..2dbde3d1cf683 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -112,10 +112,10 @@ void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start)
 EXPORT_SYMBOL_GPL(snd_hdac_stream_start);
 
 /**
- * snd_hdac_stream_clear - stop a stream DMA
+ * snd_hdac_stream_clear - helper to clear stream registers and stop DMA transfers
  * @azx_dev: HD-audio core stream to stop
  */
-void snd_hdac_stream_clear(struct hdac_stream *azx_dev)
+static void snd_hdac_stream_clear(struct hdac_stream *azx_dev)
 {
 	snd_hdac_stream_updateb(azx_dev, SD_CTL,
 				SD_CTL_DMA_START | SD_INT_MASK, 0);
@@ -124,7 +124,6 @@ void snd_hdac_stream_clear(struct hdac_stream *azx_dev)
 		snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0);
 	azx_dev->running = false;
 }
-EXPORT_SYMBOL_GPL(snd_hdac_stream_clear);
 
 /**
  * snd_hdac_stream_stop - stop a stream
-- 
2.34.1


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

* [PATCH 2/8] ALSA: hda: document state machine for hdac_streams
  2022-09-19 12:10 [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Pierre-Louis Bossart
  2022-09-19 12:10 ` [PATCH 1/8] ALSA: hda: make snd_hdac_stream_clear() static Pierre-Louis Bossart
@ 2022-09-19 12:10 ` Pierre-Louis Bossart
  2022-09-19 12:10 ` [PATCH 3/8] ALSA: hda: ext: make snd_hdac_ext_stream_init() static Pierre-Louis Bossart
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Pierre-Louis Bossart @ 2022-09-19 12:10 UTC (permalink / raw)
  To: alsa-devel
  Cc: Cezary Rojewski, Kai Vehmanen, tiwai, Bard Liao,
	Pierre-Louis Bossart, broonie, Péter Ujfalusi

The code in this library is far from self-explanatory, hopefully this
state diagram reverse-engineered from the code will help others
understand the expected transitions.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/hda/hdac_stream.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index 2dbde3d1cf683..2e98f5fd50e54 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -13,6 +13,39 @@
 #include <sound/hda_register.h>
 #include "trace.h"
 
+/*
+ * the hdac_stream library is intended to be used with the following
+ * transitions. The states are not formally defined in the code but loosely
+ * inspired by boolean variables. Note that the 'prepared' field is not used
+ * in this library but by the callers during the hw_params/prepare transitions
+ *
+ *			   |
+ *	stream_init()	   |
+ *			   v
+ *			+--+-------+
+ *			|  unused  |
+ *			+--+----+--+
+ *			   |    ^
+ *	stream_assign()	   | 	|    stream_release()
+ *			   v	|
+ *			+--+----+--+
+ *			|  opened  |
+ *			+--+----+--+
+ *			   |    ^
+ *	stream_reset()	   |    |
+ *	stream_setup()	   |	|    stream_cleanup()
+ *			   v	|
+ *			+--+----+--+
+ *			| prepared |
+ *			+--+----+--+
+ *			   |    ^
+ *	stream_start()	   | 	|    stream_stop()
+ *			   v	|
+ *			+--+----+--+
+ *			|  running |
+ *			+----------+
+ */
+
 /**
  * snd_hdac_get_stream_stripe_ctl - get stripe control value
  * @bus: HD-audio core bus
-- 
2.34.1


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

* [PATCH 3/8] ALSA: hda: ext: make snd_hdac_ext_stream_init() static
  2022-09-19 12:10 [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Pierre-Louis Bossart
  2022-09-19 12:10 ` [PATCH 1/8] ALSA: hda: make snd_hdac_stream_clear() static Pierre-Louis Bossart
  2022-09-19 12:10 ` [PATCH 2/8] ALSA: hda: document state machine for hdac_streams Pierre-Louis Bossart
@ 2022-09-19 12:10 ` Pierre-Louis Bossart
  2022-09-19 12:10 ` [PATCH 4/8] ALSA: hda: Use hdac_ext prefix in snd_hdac_stream_free_all() for clarity Pierre-Louis Bossart
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Pierre-Louis Bossart @ 2022-09-19 12:10 UTC (permalink / raw)
  To: alsa-devel
  Cc: Cezary Rojewski, Kai Vehmanen, tiwai, Bard Liao,
	Pierre-Louis Bossart, broonie, Péter Ujfalusi

There are no external users of this helper, move to static and remove
sympol export. No functionality change.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 include/sound/hdaudio_ext.h     | 3 ---
 sound/hda/ext/hdac_ext_stream.c | 7 +++----
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
index 07231f0b93b50..4a4bd1d88612f 100644
--- a/include/sound/hdaudio_ext.h
+++ b/include/sound/hdaudio_ext.h
@@ -77,9 +77,6 @@ struct hdac_ext_stream {
 #define stream_to_hdac_ext_stream(s) \
 	container_of(s, struct hdac_ext_stream, hstream)
 
-void snd_hdac_ext_stream_init(struct hdac_bus *bus,
-			      struct hdac_ext_stream *hext_stream, int idx,
-			      int direction, int tag);
 int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
 				 int num_stream, int dir);
 void snd_hdac_stream_free_all(struct hdac_bus *bus);
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index d2b5724b463ff..5c665b26f8533 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -26,9 +26,9 @@
  * initialize the stream, if ppcap is enabled then init those and then
  * invoke hdac stream initialization routine
  */
-void snd_hdac_ext_stream_init(struct hdac_bus *bus,
-			      struct hdac_ext_stream *hext_stream,
-			      int idx, int direction, int tag)
+static void snd_hdac_ext_stream_init(struct hdac_bus *bus,
+				     struct hdac_ext_stream *hext_stream,
+				     int idx, int direction, int tag)
 {
 	if (bus->ppcap) {
 		hext_stream->pphc_addr = bus->ppcap + AZX_PPHC_BASE +
@@ -56,7 +56,6 @@ void snd_hdac_ext_stream_init(struct hdac_bus *bus,
 	hext_stream->decoupled = false;
 	snd_hdac_stream_init(bus, &hext_stream->hstream, idx, direction, tag);
 }
-EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init);
 
 /**
  * snd_hdac_ext_stream_init_all - create and initialize the stream objects
-- 
2.34.1


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

* [PATCH 4/8] ALSA: hda: Use hdac_ext prefix in snd_hdac_stream_free_all() for clarity
  2022-09-19 12:10 [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Pierre-Louis Bossart
                   ` (2 preceding siblings ...)
  2022-09-19 12:10 ` [PATCH 3/8] ALSA: hda: ext: make snd_hdac_ext_stream_init() static Pierre-Louis Bossart
@ 2022-09-19 12:10 ` Pierre-Louis Bossart
  2022-09-19 12:10 ` [PATCH 5/8] ALSA: hda: add snd_hdac_stop_streams() helper Pierre-Louis Bossart
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Pierre-Louis Bossart @ 2022-09-19 12:10 UTC (permalink / raw)
  To: alsa-devel
  Cc: Cezary Rojewski, Kai Vehmanen, tiwai, Bard Liao,
	Pierre-Louis Bossart, broonie, Péter Ujfalusi

Make sure there's no ambiguity on layering with the appropriate prefix
added.

Pure rename, no functionality changed.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 include/sound/hdaudio_ext.h     | 2 +-
 sound/hda/ext/hdac_ext_stream.c | 6 +++---
 sound/soc/intel/avs/core.c      | 4 ++--
 sound/soc/intel/skylake/skl.c   | 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
index 4a4bd1d88612f..83aed26ab1433 100644
--- a/include/sound/hdaudio_ext.h
+++ b/include/sound/hdaudio_ext.h
@@ -79,7 +79,7 @@ struct hdac_ext_stream {
 
 int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
 				 int num_stream, int dir);
-void snd_hdac_stream_free_all(struct hdac_bus *bus);
+void snd_hdac_ext_stream_free_all(struct hdac_bus *bus);
 void snd_hdac_link_free_all(struct hdac_bus *bus);
 struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus,
 					   struct snd_pcm_substream *substream,
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index 5c665b26f8533..9419abd7fc036 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -87,11 +87,11 @@ int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx,
 EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_init_all);
 
 /**
- * snd_hdac_stream_free_all - free hdac extended stream objects
+ * snd_hdac_ext_stream_free_all - free hdac extended stream objects
  *
  * @bus: HD-audio core bus
  */
-void snd_hdac_stream_free_all(struct hdac_bus *bus)
+void snd_hdac_ext_stream_free_all(struct hdac_bus *bus)
 {
 	struct hdac_stream *s, *_s;
 	struct hdac_ext_stream *hext_stream;
@@ -103,7 +103,7 @@ void snd_hdac_stream_free_all(struct hdac_bus *bus)
 		kfree(hext_stream);
 	}
 }
-EXPORT_SYMBOL_GPL(snd_hdac_stream_free_all);
+EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_free_all);
 
 void snd_hdac_ext_stream_decouple_locked(struct hdac_bus *bus,
 					 struct hdac_ext_stream *hext_stream,
diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
index c50c20fd681a1..bb0719c58ca49 100644
--- a/sound/soc/intel/avs/core.c
+++ b/sound/soc/intel/avs/core.c
@@ -466,7 +466,7 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
 
 err_acquire_irq:
 	snd_hdac_bus_free_stream_pages(bus);
-	snd_hdac_stream_free_all(bus);
+	snd_hdac_ext_stream_free_all(bus);
 err_init_streams:
 	iounmap(adev->dsp_ba);
 err_remap_bar4:
@@ -502,7 +502,7 @@ static void avs_pci_remove(struct pci_dev *pci)
 		snd_hda_codec_unregister(hdac_to_hda_codec(hdev));
 
 	snd_hdac_bus_free_stream_pages(bus);
-	snd_hdac_stream_free_all(bus);
+	snd_hdac_ext_stream_free_all(bus);
 	/* reverse ml_capabilities */
 	snd_hdac_link_free_all(bus);
 	snd_hdac_ext_bus_exit(bus);
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 52a041d6144c9..0122926f9c58b 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -444,7 +444,7 @@ static int skl_free(struct hdac_bus *bus)
 	if (bus->irq >= 0)
 		free_irq(bus->irq, (void *)bus);
 	snd_hdac_bus_free_stream_pages(bus);
-	snd_hdac_stream_free_all(bus);
+	snd_hdac_ext_stream_free_all(bus);
 	snd_hdac_link_free_all(bus);
 
 	if (bus->remap_addr)
-- 
2.34.1


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

* [PATCH 5/8] ALSA: hda: add snd_hdac_stop_streams() helper
  2022-09-19 12:10 [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Pierre-Louis Bossart
                   ` (3 preceding siblings ...)
  2022-09-19 12:10 ` [PATCH 4/8] ALSA: hda: Use hdac_ext prefix in snd_hdac_stream_free_all() for clarity Pierre-Louis Bossart
@ 2022-09-19 12:10 ` Pierre-Louis Bossart
  2022-09-19 12:10 ` [PATCH 6/8] ALSA: hda: ext: simplify logic for stream assignment Pierre-Louis Bossart
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Pierre-Louis Bossart @ 2022-09-19 12:10 UTC (permalink / raw)
  To: alsa-devel
  Cc: Cezary Rojewski, Kai Vehmanen, tiwai, Bard Liao,
	Pierre-Louis Bossart, broonie, Péter Ujfalusi

Minor code reuse, no functionality change.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 include/sound/hdaudio.h        |  1 +
 sound/hda/hdac_stream.c        | 17 ++++++++++++++---
 sound/pci/hda/hda_controller.c |  4 +---
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 24c731e53ccb6..35459d740f008 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -562,6 +562,7 @@ int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
 				unsigned int format_val);
 void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start);
 void snd_hdac_stream_stop(struct hdac_stream *azx_dev);
+void snd_hdac_stop_streams(struct hdac_bus *bus);
 void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus);
 void snd_hdac_stream_reset(struct hdac_stream *azx_dev);
 void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index 2e98f5fd50e54..c056bcc5543d1 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -174,17 +174,28 @@ void snd_hdac_stream_stop(struct hdac_stream *azx_dev)
 }
 EXPORT_SYMBOL_GPL(snd_hdac_stream_stop);
 
+/**
+ * snd_hdac_stop_streams - stop all streams
+ * @bus: HD-audio core bus
+ */
+void snd_hdac_stop_streams(struct hdac_bus *bus)
+{
+	struct hdac_stream *stream;
+
+	list_for_each_entry(stream, &bus->stream_list, list)
+		snd_hdac_stream_stop(stream);
+}
+EXPORT_SYMBOL_GPL(snd_hdac_stop_streams);
+
 /**
  * snd_hdac_stop_streams_and_chip - stop all streams and chip if running
  * @bus: HD-audio core bus
  */
 void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus)
 {
-	struct hdac_stream *stream;
 
 	if (bus->chip_init) {
-		list_for_each_entry(stream, &bus->stream_list, list)
-			snd_hdac_stream_stop(stream);
+		snd_hdac_stop_streams(bus);
 		snd_hdac_bus_stop_chip(bus);
 	}
 }
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 75dcb14ff20ad..0ff286b7b66be 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -1033,10 +1033,8 @@ EXPORT_SYMBOL_GPL(azx_init_chip);
 void azx_stop_all_streams(struct azx *chip)
 {
 	struct hdac_bus *bus = azx_bus(chip);
-	struct hdac_stream *s;
 
-	list_for_each_entry(s, &bus->stream_list, list)
-		snd_hdac_stream_stop(s);
+	snd_hdac_stop_streams(bus);
 }
 EXPORT_SYMBOL_GPL(azx_stop_all_streams);
 
-- 
2.34.1


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

* [PATCH 6/8] ALSA: hda: ext: simplify logic for stream assignment
  2022-09-19 12:10 [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Pierre-Louis Bossart
                   ` (4 preceding siblings ...)
  2022-09-19 12:10 ` [PATCH 5/8] ALSA: hda: add snd_hdac_stop_streams() helper Pierre-Louis Bossart
@ 2022-09-19 12:10 ` Pierre-Louis Bossart
  2022-09-19 12:10 ` [PATCH 7/8] ALSA: hda: ext: fix locking in stream_release Pierre-Louis Bossart
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Pierre-Louis Bossart @ 2022-09-19 12:10 UTC (permalink / raw)
  To: alsa-devel
  Cc: Cezary Rojewski, Kai Vehmanen, tiwai, Bard Liao,
	Pierre-Louis Bossart, broonie, Péter Ujfalusi

The logic is needlessly complicated, the basic rule is:

The host streams can be found by checking the 'opened' boolean.
The link streams can be found by checking the 'link_locked' boolean.

Once a stream is found, it can be unconditionally decoupled. The
snd_hdac_ext_stream_decouple_locked() routine will make sure the
register status is modified as needed and the 'decoupled' boolean set.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/hda/ext/hdac_ext_stream.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index 9419abd7fc036..254df9a67bd2b 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -267,19 +267,15 @@ hdac_ext_link_stream_assign(struct hdac_bus *bus,
 		if (hstream->direction != substream->stream)
 			continue;
 
-		/* check if decoupled stream and not in use is available */
-		if (hext_stream->decoupled && !hext_stream->link_locked) {
-			res = hext_stream;
-			break;
-		}
-
+		/* check if link stream is available */
 		if (!hext_stream->link_locked) {
-			snd_hdac_ext_stream_decouple_locked(bus, hext_stream, true);
 			res = hext_stream;
 			break;
 		}
+
 	}
 	if (res) {
+		snd_hdac_ext_stream_decouple_locked(bus, res, true);
 		res->link_locked = 1;
 		res->link_substream = substream;
 	}
@@ -308,13 +304,12 @@ hdac_ext_host_stream_assign(struct hdac_bus *bus,
 			continue;
 
 		if (!hstream->opened) {
-			if (!hext_stream->decoupled)
-				snd_hdac_ext_stream_decouple_locked(bus, hext_stream, true);
 			res = hext_stream;
 			break;
 		}
 	}
 	if (res) {
+		snd_hdac_ext_stream_decouple_locked(bus, res, true);
 		res->hstream.opened = 1;
 		res->hstream.running = 0;
 		res->hstream.substream = substream;
-- 
2.34.1


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

* [PATCH 7/8] ALSA: hda: ext: fix locking in stream_release
  2022-09-19 12:10 [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Pierre-Louis Bossart
                   ` (5 preceding siblings ...)
  2022-09-19 12:10 ` [PATCH 6/8] ALSA: hda: ext: simplify logic for stream assignment Pierre-Louis Bossart
@ 2022-09-19 12:10 ` Pierre-Louis Bossart
  2022-09-19 12:10 ` [PATCH 8/8] ALSA: hda: ext: remove always-true conditions on host and link release Pierre-Louis Bossart
  2022-09-20  6:13 ` [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Takashi Iwai
  8 siblings, 0 replies; 10+ messages in thread
From: Pierre-Louis Bossart @ 2022-09-19 12:10 UTC (permalink / raw)
  To: alsa-devel
  Cc: Cezary Rojewski, Kai Vehmanen, tiwai, Bard Liao,
	Pierre-Louis Bossart, broonie, Péter Ujfalusi

The snd_hdac_ext_stream_release() routine uses the bus reg_lock, but
releases it before calling snd_hdac_stream_release() where the bus
reg_lock is taken again.

This creates a timing window where the link stream release could test
an invalid 'opened' boolean status and fail to recouple the host and
link parts.

Fix by exposing a locked version of snd_hdac_stream_release() and use
it without releasing the spinlock.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 include/sound/hdaudio.h         |  1 +
 sound/hda/ext/hdac_ext_stream.c |  2 +-
 sound/hda/hdac_stream.c         | 19 ++++++++++++++++---
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 35459d740f008..ddff03e546e9f 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -551,6 +551,7 @@ void snd_hdac_stream_init(struct hdac_bus *bus, struct hdac_stream *azx_dev,
 			  int idx, int direction, int tag);
 struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus,
 					   struct snd_pcm_substream *substream);
+void snd_hdac_stream_release_locked(struct hdac_stream *azx_dev);
 void snd_hdac_stream_release(struct hdac_stream *azx_dev);
 struct hdac_stream *snd_hdac_get_stream(struct hdac_bus *bus,
 					int dir, int stream_tag);
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index 254df9a67bd2b..9a2bc7e803dd6 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -384,8 +384,8 @@ void snd_hdac_ext_stream_release(struct hdac_ext_stream *hext_stream, int type)
 		spin_lock_irq(&bus->reg_lock);
 		if (hext_stream->decoupled && !hext_stream->link_locked)
 			snd_hdac_ext_stream_decouple_locked(bus, hext_stream, false);
+		snd_hdac_stream_release_locked(&hext_stream->hstream);
 		spin_unlock_irq(&bus->reg_lock);
-		snd_hdac_stream_release(&hext_stream->hstream);
 		break;
 
 	case HDAC_EXT_STREAM_TYPE_LINK:
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index c056bcc5543d1..1b8be39c38a96 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -365,6 +365,21 @@ struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus,
 }
 EXPORT_SYMBOL_GPL(snd_hdac_stream_assign);
 
+/**
+ * snd_hdac_stream_release_locked - release the assigned stream
+ * @azx_dev: HD-audio core stream to release
+ *
+ * Release the stream that has been assigned by snd_hdac_stream_assign().
+ * The bus->reg_lock needs to be taken at a higher level
+ */
+void snd_hdac_stream_release_locked(struct hdac_stream *azx_dev)
+{
+	azx_dev->opened = 0;
+	azx_dev->running = 0;
+	azx_dev->substream = NULL;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_stream_release_locked);
+
 /**
  * snd_hdac_stream_release - release the assigned stream
  * @azx_dev: HD-audio core stream to release
@@ -376,9 +391,7 @@ void snd_hdac_stream_release(struct hdac_stream *azx_dev)
 	struct hdac_bus *bus = azx_dev->bus;
 
 	spin_lock_irq(&bus->reg_lock);
-	azx_dev->opened = 0;
-	azx_dev->running = 0;
-	azx_dev->substream = NULL;
+	snd_hdac_stream_release_locked(azx_dev);
 	spin_unlock_irq(&bus->reg_lock);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_stream_release);
-- 
2.34.1


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

* [PATCH 8/8] ALSA: hda: ext: remove always-true conditions on host and link release
  2022-09-19 12:10 [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Pierre-Louis Bossart
                   ` (6 preceding siblings ...)
  2022-09-19 12:10 ` [PATCH 7/8] ALSA: hda: ext: fix locking in stream_release Pierre-Louis Bossart
@ 2022-09-19 12:10 ` Pierre-Louis Bossart
  2022-09-20  6:13 ` [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Takashi Iwai
  8 siblings, 0 replies; 10+ messages in thread
From: Pierre-Louis Bossart @ 2022-09-19 12:10 UTC (permalink / raw)
  To: alsa-devel
  Cc: Cezary Rojewski, Kai Vehmanen, tiwai, Bard Liao,
	Pierre-Louis Bossart, broonie, Péter Ujfalusi

By construction a host and link DMA are always decoupled. This
decoupling happens in the assign() phase. There's no point in checking
if the two parts are decoupled, this is by-design always-true.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/hda/ext/hdac_ext_stream.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index 9a2bc7e803dd6..70f3ad71aaf0d 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -382,7 +382,8 @@ void snd_hdac_ext_stream_release(struct hdac_ext_stream *hext_stream, int type)
 
 	case HDAC_EXT_STREAM_TYPE_HOST:
 		spin_lock_irq(&bus->reg_lock);
-		if (hext_stream->decoupled && !hext_stream->link_locked)
+		/* couple link only if not in use */
+		if (!hext_stream->link_locked)
 			snd_hdac_ext_stream_decouple_locked(bus, hext_stream, false);
 		snd_hdac_stream_release_locked(&hext_stream->hstream);
 		spin_unlock_irq(&bus->reg_lock);
@@ -390,7 +391,8 @@ void snd_hdac_ext_stream_release(struct hdac_ext_stream *hext_stream, int type)
 
 	case HDAC_EXT_STREAM_TYPE_LINK:
 		spin_lock_irq(&bus->reg_lock);
-		if (hext_stream->decoupled && !hext_stream->hstream.opened)
+		/* couple host only if not in use */
+		if (!hext_stream->hstream.opened)
 			snd_hdac_ext_stream_decouple_locked(bus, hext_stream, false);
 		hext_stream->link_locked = 0;
 		hext_stream->link_substream = NULL;
-- 
2.34.1


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

* Re: [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling
  2022-09-19 12:10 [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Pierre-Louis Bossart
                   ` (7 preceding siblings ...)
  2022-09-19 12:10 ` [PATCH 8/8] ALSA: hda: ext: remove always-true conditions on host and link release Pierre-Louis Bossart
@ 2022-09-20  6:13 ` Takashi Iwai
  8 siblings, 0 replies; 10+ messages in thread
From: Takashi Iwai @ 2022-09-20  6:13 UTC (permalink / raw)
  To: Pierre-Louis Bossart; +Cc: alsa-devel, broonie, Cezary Rojewski

On Mon, 19 Sep 2022 14:10:33 +0200,
Pierre-Louis Bossart wrote:
> 
> This sound/hda/ext library is a confusing magic black box that very
> few understand. It needn't be that way, we can document/simplify and
> make the code clearer.
> 
> Pierre-Louis Bossart (8):
>   ALSA: hda: make snd_hdac_stream_clear() static
>   ALSA: hda: document state machine for hdac_streams
>   ALSA: hda: ext: make snd_hdac_ext_stream_init() static
>   ALSA: hda: Use hdac_ext prefix in snd_hdac_stream_free_all() for
>     clarity
>   ALSA: hda: add snd_hdac_stop_streams() helper
>   ALSA: hda: ext: simplify logic for stream assignment
>   ALSA: hda: ext: fix locking in stream_release
>   ALSA: hda: ext: remove always-true conditions on host and link release

Applied all patches now.  Thanks.


Takashi

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

end of thread, other threads:[~2022-09-20  6:14 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-19 12:10 [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Pierre-Louis Bossart
2022-09-19 12:10 ` [PATCH 1/8] ALSA: hda: make snd_hdac_stream_clear() static Pierre-Louis Bossart
2022-09-19 12:10 ` [PATCH 2/8] ALSA: hda: document state machine for hdac_streams Pierre-Louis Bossart
2022-09-19 12:10 ` [PATCH 3/8] ALSA: hda: ext: make snd_hdac_ext_stream_init() static Pierre-Louis Bossart
2022-09-19 12:10 ` [PATCH 4/8] ALSA: hda: Use hdac_ext prefix in snd_hdac_stream_free_all() for clarity Pierre-Louis Bossart
2022-09-19 12:10 ` [PATCH 5/8] ALSA: hda: add snd_hdac_stop_streams() helper Pierre-Louis Bossart
2022-09-19 12:10 ` [PATCH 6/8] ALSA: hda: ext: simplify logic for stream assignment Pierre-Louis Bossart
2022-09-19 12:10 ` [PATCH 7/8] ALSA: hda: ext: fix locking in stream_release Pierre-Louis Bossart
2022-09-19 12:10 ` [PATCH 8/8] ALSA: hda: ext: remove always-true conditions on host and link release Pierre-Louis Bossart
2022-09-20  6:13 ` [PATCH 0/8] ALSA: hda: document/simplify hdac_ext handling Takashi Iwai

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