From patchwork Wed Jan 6 20:27:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shuah Khan X-Patchwork-Id: 7975871 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A58F1BEEE5 for ; Thu, 7 Jan 2016 10:41:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9A8EA201BB for ; Thu, 7 Jan 2016 10:41:13 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 3B3D42012E for ; Thu, 7 Jan 2016 10:41:12 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 3A7BC266651; Thu, 7 Jan 2016 11:41:11 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id 81C3C265990; Thu, 7 Jan 2016 11:28:21 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 6F89C2654E6; Wed, 6 Jan 2016 21:48:48 +0100 (CET) Received: from mailout.easymail.ca (mailout.easymail.ca [64.68.201.169]) by alsa0.perex.cz (Postfix) with ESMTP id B66162654D0 for ; Wed, 6 Jan 2016 21:48:37 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by mailout.easymail.ca (Postfix) with ESMTP id AD041E866; Wed, 6 Jan 2016 15:48:21 -0500 (EST) X-Quarantine-ID: <5tTuugdWl+Be> X-Virus-Scanned: Debian amavisd-new at mailout.easymail.ca X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" Received: from mailout.easymail.ca ([127.0.0.1]) by localhost (easymail-mailout.easydns.vpn [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5tTuugdWl+Be; Wed, 6 Jan 2016 15:48:17 -0500 (EST) Received: from mail.gonehiking.org (c-73-181-52-62.hsd1.co.comcast.net [73.181.52.62]) by mailout.easymail.ca (Postfix) with ESMTPA id C6EC3E761; Wed, 6 Jan 2016 15:48:16 -0500 (EST) Received: from lorien.internal (lorien-wl.internal [192.168.1.40]) by mail.gonehiking.org (Postfix) with ESMTP id A78099F441; Wed, 6 Jan 2016 13:27:38 -0700 (MST) From: Shuah Khan To: mchehab@osg.samsung.com, tiwai@suse.com, clemens@ladisch.de, hans.verkuil@cisco.com, laurent.pinchart@ideasonboard.com, sakari.ailus@linux.intel.com, javier@osg.samsung.com Date: Wed, 6 Jan 2016 13:27:19 -0700 Message-Id: <6787aacbea3c94ba42772928acaf590223e2445b.1452105878.git.shuahkh@osg.samsung.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: References: In-Reply-To: References: X-Mailman-Approved-At: Thu, 07 Jan 2016 11:28:04 +0100 Cc: k.kozlowski@samsung.com, alsa-devel@alsa-project.org, prabhakar.csengg@gmail.com, normalperson@yhbt.net, ricardo.ribalda@gmail.com, elfring@users.sourceforge.net, m.szyprowski@samsung.com, pierre-louis.bossart@linux.intel.com, arnd@arndb.de, corbet@lwn.net, Shuah Khan , crope@iki.fi, linuxbugs@vittgam.net, takamichiho@gmail.com, jh1009.sung@samsung.com, dan.carpenter@oracle.com, linux-media@vger.kernel.org, julian@jusst.de, ricard.wanderlof@axis.com, pawel@osciak.com, misterpib@gmail.com, tvboxspy@gmail.com, linux-kernel@vger.kernel.org, inki.dae@samsung.com, joe@oampo.co.uk, dominic.sacre@gmx.de, chehabrafael@gmail.com, labbott@fedoraproject.org, linux-api@vger.kernel.org, sw0312.kim@samsung.com, ruchandani.tina@gmail.com, gtmkramer@xs4all.nl, kyungmin.park@samsung.com, stefanr@s5r6.in-berlin.de, johan@oljud.se, p.zabel@pengutronix.de, daniel@zonque.org Subject: [alsa-devel] [PATCH 30/31] sound/usb: Check media device unregister progress state X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Change to release media resources for pcm streams and mixer before snd_card_disconnect() is done from usb_audio_disconnect(). The stream and mixer resource release interfaces access managed media resources (device resources) created on the usb device parent. These interfaces should be called before the last put_device() which releases all the device resources. In addition, changed the stream and mixer resource release interfaces to check if media device unregister is in progress and avoid calling Media Controller API to unregister entities and remove devnodes. Media device unregister takes care of all of this. This fixes the the general protection faults while snd-usb-audio was cleaning up media resources for pcm streams and mixers. Signed-off-by: Shuah Khan --- sound/usb/card.c | 8 ++++++-- sound/usb/media.c | 41 +++++++++++++++++++++++++++++++---------- sound/usb/media.h | 4 ++-- sound/usb/stream.c | 1 - 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index e965982..8959ccb 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -608,6 +608,12 @@ static void usb_audio_disconnect(struct usb_interface *intf) */ wait_event(chip->shutdown_wait, !atomic_read(&chip->usage_count)); + + /* release media pcm stream resources */ + media_stream_delete(chip); + /* delete mixer media resources */ + media_mixer_delete(chip); + snd_card_disconnect(card); /* release the pcm resources */ list_for_each_entry(as, &chip->pcm_list, list) { @@ -621,8 +627,6 @@ static void usb_audio_disconnect(struct usb_interface *intf) list_for_each(p, &chip->midi_list) { snd_usbmidi_disconnect(p); } - /* delete mixer media resources */ - media_mixer_delete(chip); /* release mixer resources */ list_for_each_entry(mixer, &chip->mixer_list, list) { snd_usb_mixer_disconnect(mixer); diff --git a/sound/usb/media.c b/sound/usb/media.c index 4f99086..9d29e1d 100644 --- a/sound/usb/media.c +++ b/sound/usb/media.c @@ -98,8 +98,11 @@ void media_device_delete(struct usb_interface *iface) struct usb_device *usbdev = interface_to_usbdev(iface); mdev = media_device_find_devres(&usbdev->dev); - if (mdev && media_devnode_is_registered(&mdev->devnode)) - media_device_unregister(mdev); + if (mdev) { + if (media_devnode_is_registered(&mdev->devnode) && + !media_device_is_unregister_in_progress(mdev)) + media_device_unregister(mdev); + } } static int media_enable_source(struct media_ctl *mctl) @@ -177,7 +180,7 @@ int media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm, return 0; } -void media_stream_delete(struct snd_usb_substream *subs) +static void __media_stream_delete(struct snd_usb_substream *subs) { struct media_ctl *mctl = (struct media_ctl *) subs->media_ctl; @@ -185,7 +188,7 @@ void media_stream_delete(struct snd_usb_substream *subs) struct media_device *mdev; mdev = media_device_find_devres(&subs->dev->dev); - if (mdev) { + if (mdev && !media_device_is_unregister_in_progress(mdev)) { media_devnode_remove(mctl->intf_devnode); media_device_unregister_entity(&mctl->media_entity); media_entity_cleanup(&mctl->media_entity); @@ -195,6 +198,21 @@ void media_stream_delete(struct snd_usb_substream *subs) } } +void media_stream_delete(struct snd_usb_audio *chip) +{ + struct snd_usb_stream *as; + + list_for_each_entry(as, &chip->pcm_list, list) { + struct snd_usb_substream *subs; + int idx; + + for (idx = 0; idx < 2; idx++) { + subs = &as->substream[idx]; + __media_stream_delete(subs); + } + } +} + int media_start_pipeline(struct snd_usb_substream *subs) { struct media_ctl *mctl = (struct media_ctl *) subs->media_ctl; @@ -283,22 +301,25 @@ void media_mixer_delete(struct snd_usb_audio *chip) struct media_device *mdev; mdev = media_device_find_devres(&chip->dev->dev); - if (!mdev) - return; + if (chip->ctl_intf_media_devnode) { + if (mdev && !media_device_is_unregister_in_progress(mdev)) + media_devnode_remove(chip->ctl_intf_media_devnode); + chip->ctl_intf_media_devnode = NULL; + } list_for_each_entry(mixer, &chip->mixer_list, list) { struct media_mixer_ctl *mctl; mctl = (struct media_mixer_ctl *) mixer->media_mixer_ctl; if (!mixer->media_mixer_ctl) continue; - - media_device_unregister_entity(&mctl->media_entity); - media_entity_cleanup(&mctl->media_entity); + if (mdev && !media_device_is_unregister_in_progress(mdev)) { + media_device_unregister_entity(&mctl->media_entity); + media_entity_cleanup(&mctl->media_entity); + } kfree(mctl); mixer->media_mixer_ctl = NULL; } - media_devnode_remove(chip->ctl_intf_media_devnode); } #endif diff --git a/sound/usb/media.h b/sound/usb/media.h index 00884b5..bd1b1ec 100644 --- a/sound/usb/media.h +++ b/sound/usb/media.h @@ -52,7 +52,7 @@ int media_device_create(struct snd_usb_audio *chip, void media_device_delete(struct usb_interface *iface); int media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm, int stream); -void media_stream_delete(struct snd_usb_substream *subs); +void media_stream_delete(struct snd_usb_audio *chip); int media_start_pipeline(struct snd_usb_substream *subs); void media_stop_pipeline(struct snd_usb_substream *subs); int media_mixer_init(struct snd_usb_audio *chip); @@ -65,7 +65,7 @@ static inline void media_device_delete(struct usb_interface *iface) { } static inline int media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm, int stream) { return 0; } -static inline void media_stream_delete(struct snd_usb_substream *subs) { } +static inline void media_stream_delete(struct snd_usb_audio *chip) { } static inline int media_start_pipeline(struct snd_usb_substream *subs) { return 0; } static inline void media_stop_pipeline(struct snd_usb_substream *subs) { } diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 789e515..f96f539 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -53,7 +53,6 @@ static void free_substream(struct snd_usb_substream *subs) kfree(fp); } kfree(subs->rate_list.list); - media_stream_delete(subs); }