From patchwork Wed Mar 27 16:52:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 10873777 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9447713B5 for ; Wed, 27 Mar 2019 16:53:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7A15728B3E for ; Wed, 27 Mar 2019 16:53:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6D38428CF2; Wed, 27 Mar 2019 16:53:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7F86428B3E for ; Wed, 27 Mar 2019 16:53:18 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id C26899F6; Wed, 27 Mar 2019 17:52:25 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz C26899F6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1553705595; bh=fpEKQWz+UWO7euMrq/H9vJQMni5YsI5T9glSrmfZnUA=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=aDnVcGW3Nrp8w8WF1PcIYD4PqOFwam//CHntzv1vszS2Q27JKiUUZbRxmXW6lqXaL 8B3RsfS3I1uaQiQAxH9BHZxt2fieKzihbfkmzIWzco7+T4fRSNChAy5MwIuw6Xze1P BKQ5mGCmKzZ8NH1q6mOpYBSUM1laW7r/k2Q7v9hY= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 18C08F8961A; Wed, 27 Mar 2019 17:52:25 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 83263F89671; Wed, 27 Mar 2019 17:52:23 +0100 (CET) Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 5DFD2F80C17 for ; Wed, 27 Mar 2019 17:52:19 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 5DFD2F80C17 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id E72B8AF5F for ; Wed, 27 Mar 2019 16:52:18 +0000 (UTC) From: Takashi Iwai To: alsa-devel@alsa-project.org Date: Wed, 27 Mar 2019 17:52:14 +0100 Message-Id: <20190327165217.4240-2-tiwai@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190327165217.4240-1-tiwai@suse.de> References: <20190327165217.4240-1-tiwai@suse.de> Subject: [alsa-devel] [PATCH 1/4] ALSA: timer: Unify timer callback process code X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" X-Virus-Scanned: ClamAV using ClamSMTP The timer core has two almost identical code for processing callbacks: once in snd_timer_interrupt() for fast callbacks and another in snd_timer_tasklet() for delayed callbacks. Let's unify them. In the new version, the resolution is read from ti->resolution at each call, and this must be fine; ti->resolution is set in the preparation step in snd_timer_interrupt(). Signed-off-by: Takashi Iwai --- sound/core/timer.c | 62 +++++++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index 61a0cec6e1f6..fdcddfb756b4 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -720,29 +720,19 @@ static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_l timer->sticks = ticks; } -/* - * timer tasklet - * - */ -static void snd_timer_tasklet(unsigned long arg) +/* call callbacks in timer ack list */ +static void snd_timer_process_callbacks(struct snd_timer *timer, + struct list_head *head) { - struct snd_timer *timer = (struct snd_timer *) arg; struct snd_timer_instance *ti; - struct list_head *p; unsigned long resolution, ticks; - unsigned long flags; - if (timer->card && timer->card->shutdown) - return; - - spin_lock_irqsave(&timer->lock, flags); - /* now process all callbacks */ - while (!list_empty(&timer->sack_list_head)) { - p = timer->sack_list_head.next; /* get first item */ - ti = list_entry(p, struct snd_timer_instance, ack_list); + while (!list_empty(head)) { + ti = list_first_entry(head, struct snd_timer_instance, + ack_list); /* remove from ack_list and make empty */ - list_del_init(p); + list_del_init(&ti->ack_list); ticks = ti->pticks; ti->pticks = 0; @@ -755,6 +745,22 @@ static void snd_timer_tasklet(unsigned long arg) spin_lock(&timer->lock); ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK; } +} + +/* + * timer tasklet + * + */ +static void snd_timer_tasklet(unsigned long arg) +{ + struct snd_timer *timer = (struct snd_timer *) arg; + unsigned long flags; + + if (timer->card && timer->card->shutdown) + return; + + spin_lock_irqsave(&timer->lock, flags); + snd_timer_process_callbacks(timer, &timer->sack_list_head); spin_unlock_irqrestore(&timer->lock, flags); } @@ -767,8 +773,8 @@ static void snd_timer_tasklet(unsigned long arg) void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) { struct snd_timer_instance *ti, *ts, *tmp; - unsigned long resolution, ticks; - struct list_head *p, *ack_list_head; + unsigned long resolution; + struct list_head *ack_list_head; unsigned long flags; int use_tasklet = 0; @@ -839,23 +845,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) } /* now process all fast callbacks */ - while (!list_empty(&timer->ack_list_head)) { - p = timer->ack_list_head.next; /* get first item */ - ti = list_entry(p, struct snd_timer_instance, ack_list); - - /* remove from ack_list and make empty */ - list_del_init(p); - - ticks = ti->pticks; - ti->pticks = 0; - - ti->flags |= SNDRV_TIMER_IFLG_CALLBACK; - spin_unlock(&timer->lock); - if (ti->callback) - ti->callback(ti, resolution, ticks); - spin_lock(&timer->lock); - ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK; - } + snd_timer_process_callbacks(timer, &timer->ack_list_head); /* do we have any slow callbacks? */ use_tasklet = !list_empty(&timer->sack_list_head); From patchwork Wed Mar 27 16:52:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 10873787 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 330A81575 for ; Wed, 27 Mar 2019 16:56:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1A5D928A41 for ; Wed, 27 Mar 2019 16:56:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0D99628BBD; Wed, 27 Mar 2019 16:56:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3CC2028A41 for ; Wed, 27 Mar 2019 16:56:22 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 6C69C15E3; Wed, 27 Mar 2019 17:55:30 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 6C69C15E3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1553705780; bh=XWOcpoQyfnFmUJ3WNJG2sLcW2mNR93QSFLpBnUofJNY=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=e2uoFBY9SMiusZjPBrgfozrW6pJcemrMNrWhSOLWKtSyQi0WN+Z1B3Up3YT/G1XZT f5MhjpEU34LyqLktnQe2My9xJvMIT1qAzwSBzi3Y2LdqunNcfJKA07KizP0DeRz/h/ rsEHvVvurskmHB25LISt0kG93S20r/uJl2s12RvE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 01F61F89720; Wed, 27 Mar 2019 17:52:34 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 89347F89717; Wed, 27 Mar 2019 17:52:27 +0100 (CET) Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 86DB4F89618 for ; Wed, 27 Mar 2019 17:52:19 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 86DB4F89618 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id ECF7BAF8A for ; Wed, 27 Mar 2019 16:52:18 +0000 (UTC) From: Takashi Iwai To: alsa-devel@alsa-project.org Date: Wed, 27 Mar 2019 17:52:15 +0100 Message-Id: <20190327165217.4240-3-tiwai@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190327165217.4240-1-tiwai@suse.de> References: <20190327165217.4240-1-tiwai@suse.de> Subject: [alsa-devel] [PATCH 2/4] ALSA: timer: Make sure to clear pending ack list X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" X-Virus-Scanned: ClamAV using ClamSMTP When a card is under disconnection, we bail out immediately at each timer interrupt or tasklet. This might leave some items left in ack list. For a better integration of the upcoming change to check ack_list emptiness, clear out the whole list upon the emergency exit route. Signed-off-by: Takashi Iwai --- sound/core/timer.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index fdcddfb756b4..107d8ebeeb2e 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -747,6 +747,18 @@ static void snd_timer_process_callbacks(struct snd_timer *timer, } } +/* clear pending instances from ack list */ +static void snd_timer_clear_callbacks(struct snd_timer *timer, + struct list_head *head) +{ + unsigned long flags; + + spin_lock_irqsave(&timer->lock, flags); + while (!list_empty(head)) + list_del_init(head->next); + spin_unlock_irqrestore(&timer->lock, flags); +} + /* * timer tasklet * @@ -756,8 +768,10 @@ static void snd_timer_tasklet(unsigned long arg) struct snd_timer *timer = (struct snd_timer *) arg; unsigned long flags; - if (timer->card && timer->card->shutdown) + if (timer->card && timer->card->shutdown) { + snd_timer_clear_callbacks(timer, &timer->sack_list_head); return; + } spin_lock_irqsave(&timer->lock, flags); snd_timer_process_callbacks(timer, &timer->sack_list_head); @@ -781,8 +795,10 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) if (timer == NULL) return; - if (timer->card && timer->card->shutdown) + if (timer->card && timer->card->shutdown) { + snd_timer_clear_callbacks(timer, &timer->ack_list_head); return; + } spin_lock_irqsave(&timer->lock, flags); From patchwork Wed Mar 27 16:52:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 10873779 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 888E11575 for ; Wed, 27 Mar 2019 16:54:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6EDD128816 for ; Wed, 27 Mar 2019 16:54:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 62F8A2883F; Wed, 27 Mar 2019 16:54:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AAF4428816 for ; Wed, 27 Mar 2019 16:54:15 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id C9E9A15DB; Wed, 27 Mar 2019 17:53:23 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz C9E9A15DB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1553705653; bh=Gjom1TlP1kM1n0qQCV9BP99JiOOxUArrpsXildnl/Xs=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Pk2AHCwC1dQo1srWzFNcd7n4T5DHdNcIqw5OmCTGqRlaKDEA/Jf9BGfVjNF6AvpOV T+snP/NvadJC3gZNfxQsZTTsx3UnphuxmluGxErdgp7nQeAEWFszIO49u5j4mAC8OW 6YoNpGa8ptcPJBrHtE4ViZ2GNWifuE6AXw/sUCyk= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id B2C7FF89715; Wed, 27 Mar 2019 17:52:26 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 1F056F8963E; Wed, 27 Mar 2019 17:52:24 +0100 (CET) Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 5566BF801D8 for ; Wed, 27 Mar 2019 17:52:19 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 5566BF801D8 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 1171CAFAC for ; Wed, 27 Mar 2019 16:52:19 +0000 (UTC) From: Takashi Iwai To: alsa-devel@alsa-project.org Date: Wed, 27 Mar 2019 17:52:16 +0100 Message-Id: <20190327165217.4240-4-tiwai@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190327165217.4240-1-tiwai@suse.de> References: <20190327165217.4240-1-tiwai@suse.de> Subject: [alsa-devel] [PATCH 3/4] ALSA: timer: Check ack_list emptiness instead of bit flag X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" X-Virus-Scanned: ClamAV using ClamSMTP For checking the pending timer instance that is still left on the timer object that is being closed, we set/clear a bit flag SNDRV_TIMER_IFLG_CALLBACK around the call of callbacks. This can be simplified by replace with the list_empty() call for ti->ack_list. This covers the existence more comprehensively and safely. A gratis bonus is that we can get rid of SNDRV_TIMER_IFLG_CALLBACK bit flag definition as well. Signed-off-by: Takashi Iwai --- include/sound/timer.h | 1 - sound/core/timer.c | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/include/sound/timer.h b/include/sound/timer.h index 7ae226ab6990..bcfee20ea226 100644 --- a/include/sound/timer.h +++ b/include/sound/timer.h @@ -43,7 +43,6 @@ #define SNDRV_TIMER_IFLG_START 0x00000004 #define SNDRV_TIMER_IFLG_AUTO 0x00000008 /* auto restart */ #define SNDRV_TIMER_IFLG_FAST 0x00000010 /* fast callback (do not use tasklet) */ -#define SNDRV_TIMER_IFLG_CALLBACK 0x00000020 /* timer callback is active */ #define SNDRV_TIMER_IFLG_EXCLUSIVE 0x00000040 /* exclusive owner - no more instances */ #define SNDRV_TIMER_IFLG_EARLY_EVENT 0x00000080 /* write early event to the poll queue */ diff --git a/sound/core/timer.c b/sound/core/timer.c index 107d8ebeeb2e..e343de0e4f9e 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -366,7 +366,7 @@ static int snd_timer_close_locked(struct snd_timer_instance *timeri) timer->num_instances--; /* wait, until the active callback is finished */ spin_lock_irq(&timer->lock); - while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) { + while (!list_empty(&timeri->ack_list)) { spin_unlock_irq(&timer->lock); udelay(10); spin_lock_irq(&timer->lock); @@ -731,19 +731,17 @@ static void snd_timer_process_callbacks(struct snd_timer *timer, ti = list_first_entry(head, struct snd_timer_instance, ack_list); - /* remove from ack_list and make empty */ - list_del_init(&ti->ack_list); - ticks = ti->pticks; ti->pticks = 0; resolution = ti->resolution; - ti->flags |= SNDRV_TIMER_IFLG_CALLBACK; spin_unlock(&timer->lock); if (ti->callback) ti->callback(ti, resolution, ticks); spin_lock(&timer->lock); - ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK; + + /* remove from ack_list and make empty */ + list_del_init(&ti->ack_list); } } From patchwork Wed Mar 27 16:52:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 10873785 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8E78413B5 for ; Wed, 27 Mar 2019 16:55:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7541328A39 for ; Wed, 27 Mar 2019 16:55:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6980428BBD; Wed, 27 Mar 2019 16:55:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9D6D328A41 for ; Wed, 27 Mar 2019 16:55:48 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id DAC9315DD; Wed, 27 Mar 2019 17:54:56 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz DAC9315DD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1553705746; bh=U9y/yNVm8hX6v2CmzpO0WzbWkBPIUYrtjkINTDOdTLE=; h=From:To:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=iuR2VZJNRRovXHenb1UmHHlBbKpnTIph5OJvqVnm6y719Mo/0xrSFXLqiyaWnCToC w0iw/1GrkXWTRGveL7dn7kAxKSy3FD88imyLIKixGaexksLSnho4aBWJZHmpkbf1uH svOfPFOczeH8tKUjV8I3sXqE0YZF0S0q21uTbKXE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 92B1EF89718; Wed, 27 Mar 2019 17:52:31 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id E684AF89716; Wed, 27 Mar 2019 17:52:27 +0100 (CET) Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 86C0FF80CAB for ; Wed, 27 Mar 2019 17:52:19 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 86C0FF80CAB X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 152A0AFBC for ; Wed, 27 Mar 2019 16:52:19 +0000 (UTC) From: Takashi Iwai To: alsa-devel@alsa-project.org Date: Wed, 27 Mar 2019 17:52:17 +0100 Message-Id: <20190327165217.4240-5-tiwai@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190327165217.4240-1-tiwai@suse.de> References: <20190327165217.4240-1-tiwai@suse.de> Subject: [alsa-devel] [PATCH 4/4] ALSA: timer: Make snd_timer_close() really kill pending actions X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 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" X-Virus-Scanned: ClamAV using ClamSMTP snd_timer_close() is supposed to close the timer instance and sync with the deactivation of pending actions. However, there are still some overlooked cases: - It calls snd_timer_stop() at the beginning, but some other might re-trigger the timer right after that. - snd_timer_stop() calls del_timer_sync() only when all belonging instances are closed. If multiple instances were assigned to a timer object and one is closed, the timer is still running. Then the pending action assigned to this timer might be left. Actually either of the above is the likely cause of the reported syzkaller UAF. This patch plug these holes by introducing SNDRV_TIMER_IFLG_DEAD flag. This is set at the beginning of snd_timer_close(), and the flag is checked at snd_timer_start*() and else, so that no longer new action is left after snd_timer_close(). Reported-by: syzbot+d5136d4d3240cbe45a2a@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai --- sound/core/timer.c | 45 +++++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index e343de0e4f9e..bb7e90ab90f8 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -38,6 +38,7 @@ /* internal flags */ #define SNDRV_TIMER_IFLG_PAUSED 0x00010000 +#define SNDRV_TIMER_IFLG_DEAD 0x00020000 #if IS_ENABLED(CONFIG_SND_HRTIMER) #define DEFAULT_TIMER_LIMIT 4 @@ -353,15 +354,20 @@ EXPORT_SYMBOL(snd_timer_open); */ static int snd_timer_close_locked(struct snd_timer_instance *timeri) { - struct snd_timer *timer = NULL; + struct snd_timer *timer = timeri->timer; struct snd_timer_instance *slave, *tmp; + if (timer) { + spin_lock_irq(&timer->lock); + timeri->flags |= SNDRV_TIMER_IFLG_DEAD; + spin_unlock_irq(&timer->lock); + } + list_del(&timeri->open_list); /* force to stop the timer */ snd_timer_stop(timeri); - timer = timeri->timer; if (timer) { timer->num_instances--; /* wait, until the active callback is finished */ @@ -497,6 +503,10 @@ static int snd_timer_start1(struct snd_timer_instance *timeri, return -EINVAL; spin_lock_irqsave(&timer->lock, flags); + if (timeri->flags & SNDRV_TIMER_IFLG_DEAD) { + result = -EINVAL; + goto unlock; + } if (timer->card && timer->card->shutdown) { result = -ENODEV; goto unlock; @@ -541,11 +551,16 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri, bool start) { unsigned long flags; + int err; spin_lock_irqsave(&slave_active_lock, flags); + if (timeri->flags & SNDRV_TIMER_IFLG_DEAD) { + err = -EINVAL; + goto unlock; + } if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) { - spin_unlock_irqrestore(&slave_active_lock, flags); - return -EBUSY; + err = -EBUSY; + goto unlock; } timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; if (timeri->master && timeri->timer) { @@ -556,8 +571,10 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri, SNDRV_TIMER_EVENT_CONTINUE); spin_unlock(&timeri->timer->lock); } + err = 1; /* delayed start */ + unlock: spin_unlock_irqrestore(&slave_active_lock, flags); - return 1; /* delayed start */ + return err; } /* stop/pause a master timer */ @@ -731,14 +748,16 @@ static void snd_timer_process_callbacks(struct snd_timer *timer, ti = list_first_entry(head, struct snd_timer_instance, ack_list); - ticks = ti->pticks; - ti->pticks = 0; - resolution = ti->resolution; + if (!(ti->flags & SNDRV_TIMER_IFLG_DEAD)) { + ticks = ti->pticks; + ti->pticks = 0; + resolution = ti->resolution; - spin_unlock(&timer->lock); - if (ti->callback) - ti->callback(ti, resolution, ticks); - spin_lock(&timer->lock); + spin_unlock(&timer->lock); + if (ti->callback) + ti->callback(ti, resolution, ticks); + spin_lock(&timer->lock); + } /* remove from ack_list and make empty */ list_del_init(&ti->ack_list); @@ -810,6 +829,8 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) */ list_for_each_entry_safe(ti, tmp, &timer->active_list_head, active_list) { + if (ti->flags & SNDRV_TIMER_IFLG_DEAD) + continue; if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING)) continue; ti->pticks += ticks_left;