From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
To: Clemens Ladisch <clemens@ladisch.de>
Cc: tiwai@suse.de, alsa-devel@alsa-project.org,
ffado-devel@lists.sourceforge.net
Subject: Re: [PATCH 26/29] ALSA: oxfw: Add support AMDTP in-stream
Date: Thu, 20 Nov 2014 19:32:54 +0900 [thread overview]
Message-ID: <546DC356.8010207@sakamocchi.jp> (raw)
In-Reply-To: <54691544.2020501@ladisch.de>
[-- Attachment #1: Type: text/plain, Size: 1392 bytes --]
Hi Clemens,
On Nov 17 2014 06:21, Clemens Ladisch wrote:
> Takashi Sakamoto wrote:
>> +++ b/sound/firewire/oxfw/oxfw-stream.c
>> +int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw,
>> + struct amdtp_stream *stream,
>> + unsigned int rate, unsigned int pcm_channels)
>> +{
>> ...
>> + if (atomic_read(substreams) == 0)
>> + goto end;
>> +
>> mutex_lock(&oxfw->mutex);
>
> What happens if hw_free is called between the calls to atomic_read() and
> mutex_lock()?
In the worst case, the codes after the mutex_lock() manage to start
duplex streams with released resources, then it causes kernel panic.
This is a bug. I should have move atmic_read() to the critical section...
> And why are the substreams counters atomic?
> Can't they just be normal variables accessed from inside the mutex?
Just for my convinience. I didn't want to write many
mutex_lock()/mutex_unlock() because wrong coding of them causes-dead
lock, then push them inner stream.c. This idea is good except for
reference couters, so I added atomic_t.
An attached patch achieves your idea over my patchset. Handling
reference counter is easy to understand (because it's arithmetric
operation) but I don't like much mutex_lock()/mutex_unlock().
Can I request you to explain about the advantages of your idea?
Regards
Takashi Sakamoto
o-takashi@sakamocchi.jp
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-dice-use-mutex-only-instead-of-atomic_t-to-handle-cr.patch --]
[-- Type: text/x-diff; name="0001-dice-use-mutex-only-instead-of-atomic_t-to-handle-cr.patch", Size: 9361 bytes --]
From 3e9968a4063f7b5d2977970821f34d5df3b70c57 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Thu, 20 Nov 2014 10:28:08 +0900
Subject: [PATCH] dice: use mutex only instead of atomic_t to handle critical
section easily
Dice driver has some critical sections. Some of them are protected by atomic_t
and the others are protected by mutex. But they can be merged.
Originally, I added atomic_t for a reference counter to enclose
mutex_lock()/mutex_unlock() inner -stream.c But it's cumbersome that this
driver uses some mutual primitives for stream handling.
This commit obsoletes atomic_t and use mutex only.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
sound/firewire/dice/dice-midi.c | 16 ++++++++++++----
sound/firewire/dice/dice-pcm.c | 30 ++++++++++++++++++++++++------
sound/firewire/dice/dice-stream.c | 29 +++++++----------------------
sound/firewire/dice/dice.c | 4 ++++
sound/firewire/dice/dice.h | 2 +-
5 files changed, 48 insertions(+), 33 deletions(-)
diff --git a/sound/firewire/dice/dice-midi.c b/sound/firewire/dice/dice-midi.c
index 4f4eae7..74cd3b3 100644
--- a/sound/firewire/dice/dice-midi.c
+++ b/sound/firewire/dice/dice-midi.c
@@ -16,8 +16,10 @@ static int capture_open(struct snd_rawmidi_substream *substream)
if (err < 0)
goto end;
- atomic_inc(&dice->substreams_counter);
+ mutex_lock(&dice->mutex);
+ dice->substreams_counter++;
err = snd_dice_stream_start_duplex(dice, 0);
+ mutex_unlock(&dice->mutex);
if (err < 0)
snd_dice_stream_lock_release(dice);
end:
@@ -33,8 +35,10 @@ static int playback_open(struct snd_rawmidi_substream *substream)
if (err < 0)
goto end;
- atomic_inc(&dice->substreams_counter);
+ mutex_lock(&dice->mutex);
+ dice->substreams_counter++;
err = snd_dice_stream_start_duplex(dice, 0);
+ mutex_unlock(&dice->mutex);
if (err < 0)
snd_dice_stream_lock_release(dice);
end:
@@ -45,8 +49,10 @@ static int capture_close(struct snd_rawmidi_substream *substream)
{
struct snd_dice *dice = substream->rmidi->private_data;
- atomic_dec(&dice->substreams_counter);
+ mutex_lock(&dice->mutex);
+ dice->substreams_counter--;
snd_dice_stream_stop_duplex(dice);
+ mutex_unlock(&dice->mutex);
snd_dice_stream_lock_release(dice);
return 0;
@@ -56,8 +62,10 @@ static int playback_close(struct snd_rawmidi_substream *substream)
{
struct snd_dice *dice = substream->rmidi->private_data;
- atomic_dec(&dice->substreams_counter);
+ mutex_lock(&dice->mutex);
+ dice->substreams_counter--;
snd_dice_stream_stop_duplex(dice);
+ mutex_unlock(&dice->mutex);
snd_dice_stream_lock_release(dice);
return 0;
diff --git a/sound/firewire/dice/dice-pcm.c b/sound/firewire/dice/dice-pcm.c
index 3427a21..f777145 100644
--- a/sound/firewire/dice/dice-pcm.c
+++ b/sound/firewire/dice/dice-pcm.c
@@ -231,8 +231,11 @@ static int capture_hw_params(struct snd_pcm_substream *substream,
{
struct snd_dice *dice = substream->private_data;
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
- atomic_inc(&dice->substreams_counter);
+ if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
+ mutex_lock(&dice->mutex);
+ dice->substreams_counter++;
+ mutex_unlock(&dice->mutex);
+ }
amdtp_stream_set_pcm_format(&dice->tx_stream,
params_format(hw_params));
@@ -245,8 +248,11 @@ static int playback_hw_params(struct snd_pcm_substream *substream,
{
struct snd_dice *dice = substream->private_data;
- if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
- atomic_inc(&dice->substreams_counter);
+ if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
+ mutex_lock(&dice->mutex);
+ dice->substreams_counter++;
+ mutex_unlock(&dice->mutex);
+ }
amdtp_stream_set_pcm_format(&dice->rx_stream,
params_format(hw_params));
@@ -259,11 +265,15 @@ static int capture_hw_free(struct snd_pcm_substream *substream)
{
struct snd_dice *dice = substream->private_data;
+ mutex_lock(&dice->mutex);
+
if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
- atomic_dec(&dice->substreams_counter);
+ dice->substreams_counter--;
snd_dice_stream_stop_duplex(dice);
+ mutex_unlock(&dice->mutex);
+
return snd_pcm_lib_free_vmalloc_buffer(substream);
}
@@ -271,11 +281,15 @@ static int playback_hw_free(struct snd_pcm_substream *substream)
{
struct snd_dice *dice = substream->private_data;
+ mutex_lock(&dice->mutex);
+
if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
- atomic_dec(&dice->substreams_counter);
+ dice->substreams_counter--;
snd_dice_stream_stop_duplex(dice);
+ mutex_unlock(&dice->mutex);
+
return snd_pcm_lib_free_vmalloc_buffer(substream);
}
@@ -284,7 +298,9 @@ static int capture_prepare(struct snd_pcm_substream *substream)
struct snd_dice *dice = substream->private_data;
int err;
+ mutex_lock(&dice->mutex);
err = snd_dice_stream_start_duplex(dice, substream->runtime->rate);
+ mutex_unlock(&dice->mutex);
if (err >= 0)
amdtp_stream_pcm_prepare(&dice->tx_stream);
@@ -295,7 +311,9 @@ static int playback_prepare(struct snd_pcm_substream *substream)
struct snd_dice *dice = substream->private_data;
int err;
+ mutex_lock(&dice->mutex);
err = snd_dice_stream_start_duplex(dice, substream->runtime->rate);
+ mutex_unlock(&dice->mutex);
if (err >= 0)
amdtp_stream_pcm_prepare(&dice->rx_stream);
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index 37d1aab..edb6777 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -193,11 +193,9 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)
enum cip_flags sync_mode;
int err = 0;
- if (atomic_read(&dice->substreams_counter) == 0)
+ if (dice->substreams_counter == 0)
goto end;
- mutex_lock(&dice->mutex);
-
err = get_sync_mode(dice, &sync_mode);
if (err < 0)
goto end;
@@ -271,23 +269,18 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)
}
}
end:
- mutex_unlock(&dice->mutex);
return err;
}
void snd_dice_stream_stop_duplex(struct snd_dice *dice)
{
- if (atomic_read(&dice->substreams_counter) > 0)
+ if (dice->substreams_counter > 0)
return;
- mutex_lock(&dice->mutex);
-
snd_dice_transaction_clear_enable(dice);
stop_stream(dice, &dice->tx_stream);
stop_stream(dice, &dice->rx_stream);
-
- mutex_unlock(&dice->mutex);
}
static int init_stream(struct snd_dice *dice, struct amdtp_stream *stream)
@@ -332,7 +325,7 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice)
{
int err;
- atomic_set(&dice->substreams_counter, 0);
+ dice->substreams_counter = 0;
err = init_stream(dice, &dice->tx_stream);
if (err < 0)
@@ -345,8 +338,6 @@ end:
void snd_dice_stream_destroy_duplex(struct snd_dice *dice)
{
- mutex_lock(&dice->mutex);
-
snd_dice_transaction_clear_enable(dice);
stop_stream(dice, &dice->tx_stream);
@@ -355,13 +346,14 @@ void snd_dice_stream_destroy_duplex(struct snd_dice *dice)
stop_stream(dice, &dice->rx_stream);
destroy_stream(dice, &dice->rx_stream);
- atomic_set(&dice->substreams_counter, 0);
-
- mutex_unlock(&dice->mutex);
+ dice->substreams_counter = 0;
}
void snd_dice_stream_update_duplex(struct snd_dice *dice)
{
+ /* The enable register becomes initialized, then streams are stopped. */
+ dice->global_enabled = false;
+
/*
* On a bus reset, the DICE firmware disables streaming and then goes
* off contemplating its own navel for hundreds of milliseconds before
@@ -370,18 +362,11 @@ void snd_dice_stream_update_duplex(struct snd_dice *dice)
* to stop so that the application can restart them in an orderly
* manner.
*/
- mutex_lock(&dice->mutex);
-
- /* The enable register becomes initialized, then streams are stopped. */
- dice->global_enabled = false;
-
stop_stream(dice, &dice->rx_stream);
stop_stream(dice, &dice->tx_stream);
fw_iso_resources_update(&dice->rx_resources);
fw_iso_resources_update(&dice->tx_resources);
-
- mutex_unlock(&dice->mutex);
}
static void dice_lock_changed(struct snd_dice *dice)
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index b6b2c92..2a5605f 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -316,10 +316,14 @@ static void dice_update(struct fw_unit *unit)
{
struct snd_dice *dice = dev_get_drvdata(&unit->device);
+ mutex_lock(&dice->mutex);
+
/* The handler address register becomes initialized. */
snd_dice_transaction_reinit(dice);
snd_dice_stream_update_duplex(dice);
+
+ mutex_unlock(&dice->mutex);
}
#define DICE_INTERFACE 0x000001
diff --git a/sound/firewire/dice/dice.h b/sound/firewire/dice/dice.h
index 40552ca..d8b721c 100644
--- a/sound/firewire/dice/dice.h
+++ b/sound/firewire/dice/dice.h
@@ -77,7 +77,7 @@ struct snd_dice {
struct amdtp_stream rx_stream;
bool global_enabled;
struct completion clock_accepted;
- atomic_t substreams_counter;
+ unsigned int substreams_counter;
};
enum snd_dice_addr_type {
--
2.1.0
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
next prev parent reply other threads:[~2014-11-20 10:33 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-26 13:03 [PATCH 00/29 v2] ALSA: Enhancement for existed FireWire drivers Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 01/29] ALSA: dice: Rename structure and its members Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 02/29] ALSA: dice: Move file to its own directory Takashi Sakamoto
2014-11-18 12:57 ` Clemens Ladisch
2014-11-18 15:29 ` Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 03/29] ALSA: dice: Split transaction functionality into a file Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 04/29] ALSA: dice: Split stream " Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 05/29] ALSA: dice: Split PCM " Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 06/29] ALSA: dice: Split hwdep " Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 07/29] ALSA: dice: Split proc interface " Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 08/29] ALSA: dice: Add new functions for constraints of PCM parameters Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 09/29] ALSA: dice: Change the way to start stream Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 10/29] ALSA: dice: Add support for duplex streams with synchronization Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 11/29] ALSA: dice: Support for non SYT-Match sampling clock source mode Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 12/29] ALSA: dice: Add support for capturing PCM samples Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 13/29] ALSA: dice: Add support for MIDI capture/playback Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 14/29] ALSA: dice: remove experimental state Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 15/29] ALSA: speakers: Rename to oxfw and rename some members Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 16/29] ALSA: oxfw: Move to its own directory Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 17/29] ALSA: oxfw: Split stream functionality to a new file and add a header file Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 18/29] ALSA: oxfw: Split PCM functionality to a new file Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 19/29] ALSA: oxfw: Split control " Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 20/29] ALSA: oxfw: Change the way to name card Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 21/29] ALSA: oxfw: Add support for AV/C stream format command to get/set supported stream formation Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 22/29] ALSA: oxfw: Change the way to make PCM rules/constraints Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 23/29] ALSA: oxfw: Add proc interface for debugging purpose Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 24/29] ALSA: oxfw: Change the way to start stream Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 25/29] ALSA: oxfw: Add support for Behringer/Mackie devices Takashi Sakamoto
2014-11-16 20:57 ` Clemens Ladisch
2014-11-18 15:24 ` Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 26/29] ALSA: oxfw: Add support AMDTP in-stream Takashi Sakamoto
2014-11-16 21:21 ` Clemens Ladisch
2014-11-20 10:32 ` Takashi Sakamoto [this message]
2014-11-24 1:03 ` Takashi Sakamoto
2014-11-24 13:54 ` Clemens Ladisch
[not found] ` <54746395.4070807@sakamocchi.jp>
2014-11-25 12:04 ` Clemens Ladisch
2014-11-25 22:41 ` Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 27/29] ALSA: oxfw: add support for capturing PCM samples Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 28/29] ALSA: oxfw: Add support for capture/playback MIDI messages Takashi Sakamoto
2014-10-26 13:03 ` [PATCH 29/29] ALSA: oxfw: Add hwdep interface Takashi Sakamoto
2014-10-26 13:29 ` [PATCH] hwdep: add OXFW driver support Takashi Sakamoto
2014-10-26 13:43 ` [PATCH alsa-lib] " Takashi Sakamoto
2014-10-26 16:51 ` [PATCH 00/29 v2] ALSA: Enhancement for existed FireWire drivers Stefan Richter
2014-11-14 10:50 ` Takashi Iwai
2014-11-14 12:08 ` Clemens Ladisch
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=546DC356.8010207@sakamocchi.jp \
--to=o-takashi@sakamocchi.jp \
--cc=alsa-devel@alsa-project.org \
--cc=clemens@ladisch.de \
--cc=ffado-devel@lists.sourceforge.net \
--cc=tiwai@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox