From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA9A040682D for ; Mon, 13 Jul 2026 12:10:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783944610; cv=none; b=nZz78toBh6xrmUPmgdukc77n+IUWYbRX284maB+6AvE9bFFB/pr8d8J7N4GQCa7JBS6FujhbN9qIUCC3iqyh39Bm5CDpfiqT9525X++GLuPqC3rUxvjcQ+0ov/1FbCVPBRj+SS8wzg1SEzpSw4MAiIv4NmJUfh0SdFwLCzsUNI0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783944610; c=relaxed/simple; bh=jmgoQL+MH+cHI2abCHhSjB4sQPbvNKTxgke0bczlm7Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=foESogK7WatHY7v6t8ESkpwPkczAVJbhM4tuHytRXLoiLMVGExXaXLzORiLR29pyKZ6Mk5pP3V5wQny06nh6jcHJS9rKem29/1Nb+y3IZ1iIaOOW6aDw0bdt66/wxmDXxXAPatJQ7DvDP6Ed8ClS7ETJ17Dnd3OLnhb7ZNBeDIs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Nq2R3WEk; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Nq2R3WEk" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-2ceae1ed204so15014655ad.0 for ; Mon, 13 Jul 2026 05:10:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783944608; x=1784549408; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=cz2FSgCZR0hsmFPhKS7OSCHd3SyOY5Jhxrt1826LFDI=; b=Nq2R3WEkPiz8hNUV5yOa5w+XAeChi13GOGHCW94/1P9IuCfm940PzbejHMn9pQzC+T Z6LY5UKdtKMvzVkmV54x4wSMFg6A3X7uH6r+0eZ9jcsakp58gKSjYdUu50CGRNq0WioN peGp7X2cfdHl/qXDKFJO3KwqvxjQUrx/MTShuEzBTC5qKYDMSITVn4lLw0AeMnZ6JkB0 1BMq/HFFQjDPjbWQXBt2uLV7r6fj3Pbwd4YqmoIa1Z/vbaJiY9AQuTqp0mkL5Ocv1ZiZ QWrwrtVMeejJMEviBxPf8iE8F57E2yKPnvXD3hLT9g7b5bg7moUBFBMpKW+MC5cWfOms nKcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783944608; x=1784549408; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=cz2FSgCZR0hsmFPhKS7OSCHd3SyOY5Jhxrt1826LFDI=; b=rpLvOU9Z16JQx0qG3A/mh/KU5sp4BjP8tuJzrMvJQfEd4QVdxFfWKUeQMD79lvZc4a 8xLQXDTri469byinBHq/4AjAvVJt4vYLP1rYl8IQ0P0zjonl6gH7j97bj/+rur8Y5ZWg LnDMTOoNGgWPwVtVMZ7FX9ZNtEeI1vS3dMfJK6Naoe9612iftf2ePHSyCOE/4wVwh3dv GDZAJfBqQiDGNTssH7PQr1sdGp2NnAoNbwPMq3pVVT5+xjvn1jNEVEgEKTZfkl+gTvyK qpy3pzO6CN8Ys0AIFjtRyJixq3xYeRZkhqSEAyhr2VpvRu3XU5sMOeSkBu082j4UK6yI ny/Q== X-Forwarded-Encrypted: i=1; AHgh+RqL9HsKlTc5wR4HCa0WN3P1obtjvLlFWzK9dCyDjgPuUvRnsxYqtjZTmKTo3mjVUUyZdZQ9fyL1R/2hvUw=@vger.kernel.org X-Gm-Message-State: AOJu0YytQc2VS+aLRAV1bKTN66GEI4CQb4ch+AqVfXoRL7dDlaaoKhHE 6+nk9WnqHbYmn32sBy2RPEe+wOJJvPDrfoVBqDFg63RVgV5+3pM8xitt X-Gm-Gg: AfdE7cmwJEYKcFxbz0r4zQQCBQ3DkXSKM8btiLgNMeNGz6gLcpMsT67tw9bEHGHTIcS qMKvTQQokXGor0/iCDQK7yAtWPgQVfdoe0AZoSz2it5NIVQSQfcoNejRYJm52eMvfn44ptIejNo EhmRsT1lisZLX6MYeVVVdWUWH4ik8fHSzjhI1+CxGpxKeEmCIZd9j2RbdgUd6GDgBbC6mvNTdD7 Aog8Eq8CCSpRyIZ1vKbi+WLgtUsckKH3okKHB0Ow7uL1n8l4rIsADPJPVvRFg7+8y96BdDRNzHv mb1JiKB2Tp4Mkvln+47PvM1nmKyz+sm673qXS0p2/PRSTBCwIkEW2qSooAZqRKstYzVF75PRu3l u2/LYOq5MTouiyRyBKCwRAkr1ofLAR0Zj6WJ/WVMswkx6TaDO9vaNG72IGoZuv59CbdRhuvpFGF zINOAtw8pePw== X-Received: by 2002:a05:6a21:140a:b0:3c0:9c19:b27d with SMTP id adf61e73a8af0-3c110cfefa5mr9580843637.75.1783944607855; Mon, 13 Jul 2026 05:10:07 -0700 (PDT) Received: from rockpi-5b ([45.112.0.180]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-311747f7293sm67756935eec.3.2026.07.13.05.10.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Jul 2026 05:10:07 -0700 (PDT) From: Anand Moon To: Neil Armstrong , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Kevin Hilman , Jerome Brunet , Martin Blumenstingl , Mauro Carvalho Chehab , Greg Kroah-Hartman , dri-devel@lists.freedesktop.org (open list:DRM DRIVERS FOR AMLOGIC SOCS), linux-amlogic@lists.infradead.org (open list:DRM DRIVERS FOR AMLOGIC SOCS), linux-arm-kernel@lists.infradead.org (moderated list:ARM/Amlogic Meson SoC support), linux-kernel@vger.kernel.org (open list), linux-media@vger.kernel.org (open list:MESON VIDEO DECODER DRIVER FOR AMLOGIC SOCS), linux-staging@lists.linux.dev (open list:STAGING SUBSYSTEM) Cc: Anand Moon , Doruk Tan Ozturk , Nicolas Dufresne Subject: [PATCH v7 07/19] media: meson: vdec: Refactor esparser work queue and fix teardown race Date: Mon, 13 Jul 2026 17:37:02 +0530 Message-ID: <20260713120840.17427-8-linux.amoon@gmail.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260713120840.17427-1-linux.amoon@gmail.com> References: <20260713120840.17427-1-linux.amoon@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Rework the esparser work queue logic to prevent concurrent queue mutations and fix a race condition during streaming teardown. The previous implementation relied on v4l2_m2m_for_each_src_buf_safe(), which held the session mutex across the entire queue traversal. This blocked concurrent operations, caused inaccurate buffer mapping, and triggered 100+ second watchdog freezes due to an unyielding polling loop. Additionally, the low-level parser handled buffer ownership adjustments and completion callbacks directly, leading to inconsistent error paths and races between streamon and streamoff. Fix this by utilizing the modern scoped_guard(mutex) mechanism inside the main worker loop. This allows the session lock to be automatically dropped on any conditional breakout path, preventing voluntary scheduling bugs while invoking cond_resched(). De-couple buffer lifecycles from the hardware parser routine by leveraging safe, linear fetches via v4l2_m2m_next_src_buf() and v4l2_m2m_src_buf_remove(), ensuring orderly frame transactions. Refactor esparser_queue() to return explicit error codes (such as -EBADMSG, -EIO, and -EAGAIN) to safely handle buffer states. Clean up teardown paths: Execute cancel_work_sync() inside vdec_stop_streaming() and vdec_close() immediately after synchronize_irq(). This ensures any pending scheduled queue work is fully flushed and canceled before the driver destroys hardware instances. Cc: Nicolas Dufresne Signed-off-by: Anand Moon --- drivers/staging/media/meson/vdec/esparser.c | 69 +++++++++++++++------ 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c index 37749ede308c6..e5d3d817b9b2b 100644 --- a/drivers/staging/media/meson/vdec/esparser.c +++ b/drivers/staging/media/meson/vdec/esparser.c @@ -328,15 +328,11 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf) return -EAGAIN; } - v4l2_m2m_src_buf_remove_by_buf(sess->m2m_ctx, vbuf); - offset = esparser_get_offset(sess); ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags); - if (ret) { - v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); + if (ret) return ret; - } dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n", vb->timestamp, payload_size, offset, vbuf->flags); @@ -348,12 +344,10 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf) if (sess->fmt_out->pixfmt == V4L2_PIX_FMT_VP9) { payload_size = vp9_update_header(core, vb); - /* If unable to alter buffer to add headers */ if (payload_size == 0) { + dev_err(core->dev, "esparser: VP9 header update failed\n"); amvdec_remove_ts(sess, vb->timestamp); - v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); - - return 0; + return -EBADMSG; } } @@ -363,33 +357,68 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf) if (ret <= 0) { dev_warn(core->dev, "esparser: input parsing error\n"); amvdec_remove_ts(sess, vb->timestamp); - v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); amvdec_write_parser(core, PARSER_FETCH_CMD, 0); - - return 0; + return -EIO; } atomic_inc(&sess->esparser_queued_bufs); - v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); return 0; } void esparser_queue_all_src(struct work_struct *work) { - struct v4l2_m2m_buffer *buf, *n; struct amvdec_session *sess = container_of(work, struct amvdec_session, esparser_queue_work); + struct device *dev = sess->core->dev_dec; + int ret; - mutex_lock(&sess->lock); - v4l2_m2m_for_each_src_buf_safe(sess->m2m_ctx, buf, n) { - if (sess->should_stop) - break; + while (1) { + struct vb2_v4l2_buffer *vbuf = NULL; + bool processed_frame = false; + + scoped_guard(mutex, &sess->lock) { + /* Safe atomic tracking check: exit loop if session is shutting down */ + if (sess->should_stop) + return; + + /* Queue completely empty: exit work loop cleanly */ + vbuf = v4l2_m2m_next_src_buf(sess->m2m_ctx); + if (!vbuf) + break; + + /* Stop processing if we hit the end-of-stream drain buffer */ + if (vbuf->flags & V4L2_BUF_FLAG_LAST) + break; + + /* Check hardware FIFO limits safely inside the locks */ + ret = esparser_queue(sess, vbuf); + if (ret == -EAGAIN) + break; + + /* Pop the buffer from the source queue since it is now processed */ + vbuf = v4l2_m2m_src_buf_remove(sess->m2m_ctx); + if (!vbuf) { + dev_dbg(dev, "Buffer missing during queue removal\n"); + break; + } + + /* Complete the buffer transaction based on parser results */ + if (ret < 0) + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); + else + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); - if (esparser_queue(sess, &buf->vb) < 0) + /* Set tracking flag indicating transaction completion */ + processed_frame = true; + } + + if (processed_frame) break; + + /* Give other threads and IRQ routines a window to execute while unlocked */ + cond_resched(); } - mutex_unlock(&sess->lock); } int esparser_power_up(struct amvdec_session *sess) -- 2.50.1