From nobody Sun Oct 20 11:21:30 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4XWbcC29k7z5YvNr; Sun, 20 Oct 2024 11:21:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4XWbcB5hqgz4WsH; Sun, 20 Oct 2024 11:21:30 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1729423290; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=IRfJ0VHBpxopBuxBt13XuQSzYV25AvUowtenzBo2iE8=; b=ActX/9LyTmWWGcgDl58Y3kmr/dZWe1ABc+x+1X+eszRheFd6OGkVmWnjtSDBvmmsmkGlsV pxw4+loRbpc08FEvUAdRtPQLWU2L8QwbCMruHnMoXWl9WxdaVzbhYmuki4c8nxv3qVkzL2 7VPZXl7XvQtWXq2DYTQWki1y+dfWQOmmBWFiviXKRwyIrEm3LkrzpA9xpQoLT6NRQa8IqO dl92jB/Vfu18GC0pTfV+Xv4dO9aK/BZCLH+WOmK/kmCrwetdfwE8cJjQQf1M/zTg+t4arN czZJT3ewRuu6jYDlZlf9reMEy06XcCcKLy1Fq8/dY+j4BBQhvxwATm+zPhK57w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1729423290; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=IRfJ0VHBpxopBuxBt13XuQSzYV25AvUowtenzBo2iE8=; b=ZQXSzkNl9mpCBj3ry4b6tUtpI+CLQDcmy3LIr+HQAq74TroEFGJG0j25WC1oygVIBIzyfU oOBOd1DWwmBa9kW2TBWycMwUMEeGv/g2CF5/jEE5/cn5BB99JYn0r8SrPJCX/MAZco+R9T heBmYXvRxDpIhUJgTO40/iJxqawl1CKBJGaH8eYfw1wbqBOKKyA6KrEppY2NqHYfLKo/1g Bd5OvZw0KDpyU3io8xjSc1dxWfqwrfKVPo7pTRGDJPck7pt5BFrbvAr3cSIbrkxpNyVHb2 yPnzNbcTQjM/axRscVDxaPG4GsVO3kM6H5avrNuHI69rhB7X4hQqg4cR9oQt6g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1729423290; a=rsa-sha256; cv=none; b=EdO6PwZGTgiAcLN168p5tOxx+9Pu+j2xRCkfGouurtTSsrtcdmcsjY8aP8+E9IXZIa8grh YwfbTRMlItHVLa6AYqsjIwIJcEnERGRXG9doL7NajwgFm1aDfB5XfeByD6O/NsrFoZG6Yu oYd/WByoLQUI/4QLZBXP0i/i9MjYsC0hCoHDemokfNCUe3/mGVAaJqqMpEf9pTtzSNBU9J B6SO1jMZVM3kL0YcdS3HjtMlHKRwBiRvu9FYT1NVjHIE8AS8ZxSHWiZ4SHC4xRl8JxuQ9a uw943fRQNHFRGtDRQ81lkJ3IXobpSg9R1t6oCIcnf90CsrUkje7wtVoy37TrHA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4XWbcB5Cq0z10Jf; Sun, 20 Oct 2024 11:21:30 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 49KBLUD0061450; Sun, 20 Oct 2024 11:21:30 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 49KBLUJD061447; Sun, 20 Oct 2024 11:21:30 GMT (envelope-from git) Date: Sun, 20 Oct 2024 11:21:30 GMT Message-Id: <202410201121.49KBLUJD061447@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Christos Margiolis Subject: git: 4cf4144d8f7f - stable/14 - sound: Simplify pcm_chnalloc() and fix infinite loop bug List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: christos X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 4cf4144d8f7fdd51562b45fa8f1f4aa16d444b3a Auto-Submitted: auto-generated The branch stable/14 has been updated by christos: URL: https://cgit.FreeBSD.org/src/commit/?id=4cf4144d8f7fdd51562b45fa8f1f4aa16d444b3a commit 4cf4144d8f7fdd51562b45fa8f1f4aa16d444b3a Author: Christos Margiolis AuthorDate: 2024-10-18 08:38:50 +0000 Commit: Christos Margiolis CommitDate: 2024-10-20 11:21:04 +0000 sound: Simplify pcm_chnalloc() and fix infinite loop bug Simplify logic to execute the following algorithm: 1. Search for a free (i.e not busy) channel and return successfully. 2. If no channel was found, either return an ENOTSUP if no VCHAN can be created (disabled or we reached the limit), or create one more VCHAN and scan for it again. 3. If the second scan failed again, return EBUSY. This patch also solves a bug where we'd end up in an infinite loop, calling vchan_setnew() with the same `newcnt` value indefinitely, after the following scenario: 1. Plug device. 2. Spawn X channels. 3. Kill all channels except _last_ opened. 4. Clean up all unused VCHANs. 5. Spawn X+1 channels. 6. Infinite loop in pcm_chnalloc(). I am not exactly sure which part of pcm_chnalloc() caused this bug, but the patch fixes it at least... Sponsored by: The FreeBSD Foundation MFC after: 2 days Reviewed by: dev_submerge.ch Differential Revision: https://reviews.freebsd.org/D46548 (cherry picked from commit b973a14d354f332a3428cbab8e9d4b72cb3e2d6e) --- sys/dev/sound/pcm/sound.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index b18b83468150..1aaf614078a4 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -109,13 +109,12 @@ snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand return bus_setup_intr(dev, res, flags, NULL, hand, param, cookiep); } -/* return error status and a locked channel */ int pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction, pid_t pid, char *comm) { struct pcm_channel *c; - int err, vchancount, vchan_num; + int err, vchancount; bool retry; KASSERT(d != NULL && ch != NULL && @@ -125,46 +124,38 @@ pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction, PCM_BUSYASSERT(d); *ch = NULL; - vchan_num = 0; vchancount = (direction == PCMDIR_PLAY) ? d->pvchancount : d->rvchancount; - retry = false; + retry_chnalloc: - err = ENOTSUP; - /* scan for a free channel */ + /* Scan for a free channel. */ CHN_FOREACH(c, d, channels.pcm) { CHN_LOCK(c); - if (c->direction == direction && (c->flags & CHN_F_VIRTUAL)) { - if (vchancount < snd_maxautovchans && - vchan_num < c->unit) { - CHN_UNLOCK(c); - goto vchan_alloc; - } - vchan_num++; + if (c->direction != direction) { + CHN_UNLOCK(c); + continue; } - if (c->direction == direction && !(c->flags & CHN_F_BUSY)) { + if (!(c->flags & CHN_F_BUSY)) { c->flags |= CHN_F_BUSY; c->pid = pid; strlcpy(c->comm, (comm != NULL) ? comm : CHN_COMM_UNKNOWN, sizeof(c->comm)); *ch = c; + return (0); - } else if (c->direction == direction && (c->flags & CHN_F_BUSY)) - err = EBUSY; + } CHN_UNLOCK(c); } - - /* - * We came from retry_chnalloc and still didn't find a free channel. - */ + /* Maybe next time... */ if (retry) - return (err); + return (EBUSY); -vchan_alloc: - /* no channel available */ + /* No channel available. We also cannot create more VCHANs. */ if (!(vchancount > 0 && vchancount < snd_maxautovchans)) - return (err); + return (ENOTSUP); + + /* Increase the VCHAN count and try to get the new channel. */ err = vchan_setnew(d, direction, vchancount + 1); if (err == 0) { retry = true;