All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Cc: Linux-ALSA <alsa-devel@alsa-project.org>,
	Mark Brown <broonie@kernel.org>, Simon <horms@verge.net.au>
Subject: Re: [PATCH 1/3] ALSA: add snd_card_disconnect_sync()
Date: Wed, 11 Oct 2017 09:33:34 +0200	[thread overview]
Message-ID: <s5hfuaqi1f5.wl-tiwai@suse.de> (raw)
In-Reply-To: <87d15up5ac.wl%kuninori.morimoto.gx@renesas.com>

On Wed, 11 Oct 2017 08:36:13 +0200,
Kuninori Morimoto wrote:
> 
> 
> From: Takashi Iwai <tiwai@suse.de>
> 
> In case of user unbind ALSA driver during playbacking/capturing,
> each driver needs to stop and remove it correctly. One note here is
> that we can't cancel from remove function in such case, becasue
> unbind operation doesn't check return value from remove function.
> So, we *must* stop and remove in this case.
> 
> For this purpose, we need to sync (= wait) until the all top-level
> operations are canceled at remove function.
> For example, snd_card_free() processes the isconnection procedure at

disconnection

> first, then waits for the completion. That's how the hot-unplug works
> safely. It's implemented, at least, in the top-level driver removal.
> 
> Now for the lower level driver, we need a similar strategy. Notify to
> the toplevel for hot-unplug (disconnect in ALSA), and sync with the
> stop operation, then continue the rest of its own remove procedure.
> 
> This patch adds snd_card_disconnect_sync(), and driver can use it from
> remove function.
> 
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> ---
> Takashi-san
> 
> I created this patch and its git-log, but please fixup it
> if needed.

I would split this again to two patches, one for adding
snd_card_disconnect_sync(), and another for adding snd_pcm_stop() call
at snd_pcm_dev_disconnect().

Basically the latter is for the drivers that don't handle the PCM stop
at disconnection explicitly, and it's not mandatory when the driver's
pcm dev_disconnect callback handles it.

Also, since these changes are about ALSA core, and at least the
PCM-stop one is intrusive and may have influences on the behavior of
other drivers, I'd like to test with usb-audio before landing to ASoC
world.  Once when confirmed, I'll publish a persistent branch
containing these API changes and let Mark pull it.

More comments below:

> 
>  include/sound/core.h |  2 ++
>  sound/core/init.c    | 18 ++++++++++++++++++
>  sound/core/pcm.c     |  4 ++++
>  3 files changed, 24 insertions(+)
> 
> diff --git a/include/sound/core.h b/include/sound/core.h
> index 4104a9d..5f181b8 100644
> --- a/include/sound/core.h
> +++ b/include/sound/core.h
> @@ -133,6 +133,7 @@ struct snd_card {
>  	struct device card_dev;		/* cardX object for sysfs */
>  	const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */
>  	bool registered;		/* card_dev is registered? */
> +	wait_queue_head_t remove_sleep;
>  
>  #ifdef CONFIG_PM
>  	unsigned int power_state;	/* power state */
> @@ -240,6 +241,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
>  		 struct snd_card **card_ret);
>  
>  int snd_card_disconnect(struct snd_card *card);
> +void snd_card_disconnect_sync(struct snd_card *card);
>  int snd_card_free(struct snd_card *card);
>  int snd_card_free_when_closed(struct snd_card *card);
>  void snd_card_set_id(struct snd_card *card, const char *id);
> diff --git a/sound/core/init.c b/sound/core/init.c
> index 32ebe2f..f7f7050 100644
> --- a/sound/core/init.c
> +++ b/sound/core/init.c
> @@ -255,6 +255,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
>  #ifdef CONFIG_PM
>  	init_waitqueue_head(&card->power_sleep);
>  #endif
> +	init_waitqueue_head(&card->remove_sleep);
>  
>  	device_initialize(&card->card_dev);
>  	card->card_dev.parent = parent;
> @@ -452,6 +453,21 @@ int snd_card_disconnect(struct snd_card *card)
>  }
>  EXPORT_SYMBOL(snd_card_disconnect);
>  
> +void snd_card_disconnect_sync(struct snd_card *card)

We need the documentation for the public API function.

> +{
> +	DECLARE_COMPLETION(comp);

This completion isn't used here, no?

> +
> +	if (snd_card_disconnect(card) < 0)
> +		return;

OK, we should bail out here, but since we can't handle the error, it's
better to warn explicitly.  Not necessarily WARN_ON() but give a fat
error message.


thanks,

Takashi

> +
> +	spin_lock_irq(&card->files_lock);
> +	wait_event_lock_irq(card->remove_sleep,
> +			    list_empty(&card->files_list),
> +			    card->files_lock);
> +	spin_unlock_irq(&card->files_lock);
> +}
> +EXPORT_SYMBOL_GPL(snd_card_disconnect_sync);
> +
>  static int snd_card_do_free(struct snd_card *card)
>  {
>  #if IS_ENABLED(CONFIG_SND_MIXER_OSS)
> @@ -957,6 +973,8 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
>  			break;
>  		}
>  	}
> +	if (list_empty(&card->files_list))
> +		wake_up_all(&card->remove_sleep);
>  	spin_unlock(&card->files_lock);
>  	if (!found) {
>  		dev_err(card->dev, "card file remove problem (%p)\n", file);
> diff --git a/sound/core/pcm.c b/sound/core/pcm.c
> index 7eadb7f..054e47a 100644
> --- a/sound/core/pcm.c
> +++ b/sound/core/pcm.c
> @@ -1152,6 +1152,10 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
>  		for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) {
>  			snd_pcm_stream_lock_irq(substream);
>  			if (substream->runtime) {
> +				if (snd_pcm_running(substream))
> +					snd_pcm_stop(substream,
> +						     SNDRV_PCM_STATE_DISCONNECTED);
> +				/* to be sure, set the state unconditionally */
>  				substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
>  				wake_up(&substream->runtime->sleep);
>  				wake_up(&substream->runtime->tsleep);
> -- 
> 1.9.1
> 

  reply	other threads:[~2017-10-11  7:33 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-11  6:33 [PATCH 0/3] ALSA: add snd_card_disconnect_sync() Kuninori Morimoto
2017-10-11  6:36 ` [PATCH 1/3] " Kuninori Morimoto
2017-10-11  7:33   ` Takashi Iwai [this message]
2017-10-11  7:51     ` Kuninori Morimoto
2017-10-11  6:37 ` [PATCH 2/3] ASoC: add snd_soc_card_disconnect_sync() Kuninori Morimoto
2017-10-11  8:42   ` Mark Brown
2017-10-11  8:47     ` Kuninori Morimoto
2017-10-11  6:37 ` [PATCH 3/3] ASoC: rsnd: call snd_soc_card_disconnect_sync() when remove Kuninori Morimoto
2017-10-11  6:56   ` Kuninori Morimoto

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=s5hfuaqi1f5.wl-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=horms@verge.net.au \
    --cc=kuninori.morimoto.gx@renesas.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.