[{"id":31673,"web_url":"https://patchwork.libcamera.org/comment/31673/","msgid":"<172851085429.532453.8068218543076263779@ping.linuxembedded.co.uk>","date":"2024-10-09T21:54:14","subject":"Re: [PATCH v3 2/2] libcamera: software_isp: Clean up pending\n\trequests on stop","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Milan Zamazal (2024-10-09 18:21:08)\n> PipelineHandler::stop() calls stopDevice() method to perform pipeline\n> specific cleanup and then completes waiting requests.  If any queued\n> requests remain, an assertion error is raised.\n> \n> Software ISP stores request buffers in\n> SimpleCameraData::conversionQueue_ and queues them as V4L2 signals\n> bufferReady.  stopDevice() cleanup forgets to clean up the buffers and\n> their requests from conversionQueue_, possibly resulting in the\n> assertion error.  This patch fixes the omission.\n> \n> The problem wasn't very visible when\n> SimplePipelineHandler::kNumInternalBuffers (the number of buffers\n> allocated in V4L2) was equal to the number of buffers exported from\n> software ISP.  But when the number of the exported buffers was increased\n> by one in commit abe2ec64f9e4e97bbdfe3a50372611bd7b5315c2, the assertion\n> error started pop up in some environments.  Increasing the number of the\n> buffers much more, e.g. to 9, makes the problem very reproducible.\n> \n> Each pipeline uses its own mechanism to track the requests to clean up\n> and it can't be excluded that similar omissions are present in other\n> places.  But there is no obvious way to make a common cleanup for all\n> the pipelines (except for doing it instead of raising the assertion\n> error, which is probably undesirable, in order not to hide incomplete\n> pipeline specific cleanups).\n> \n> Bug: https://bugs.libcamera.org/show_bug.cgi?id=234\n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> ---\n>  src/libcamera/pipeline/simple/simple.cpp | 15 +++++++++++++++\n>  1 file changed, 15 insertions(+)\n> \n> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\n> index 3ddce71d3..ff3859f18 100644\n> --- a/src/libcamera/pipeline/simple/simple.cpp\n> +++ b/src/libcamera/pipeline/simple/simple.cpp\n> @@ -284,6 +284,7 @@ public:\n>         std::vector<std::unique_ptr<FrameBuffer>> conversionBuffers_;\n>         std::queue<std::map<const Stream *, FrameBuffer *>> conversionQueue_;\n>         bool useConversion_;\n> +       void clearIncompleteRequests();\n>  \n>         std::unique_ptr<Converter> converter_;\n>         std::unique_ptr<SoftwareIsp> swIsp_;\n> @@ -897,6 +898,19 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)\n>                 pipe->completeRequest(request);\n>  }\n>  \n> +void SimpleCameraData::clearIncompleteRequests()\n> +{\n> +       while (!conversionQueue_.empty()) {\n> +               for (auto &item : conversionQueue_.front()) {\n> +                       FrameBuffer *outputBuffer = item.second;\n> +                       Request *request = outputBuffer->request();\n> +                       if (request->status() == Request::RequestPending)\n> +                               pipe()->cancelRequest(request);\n\nHrm. ... Is it possible to have a request on the conversionQueue_ which\nis not RequestPending ?\n\nI am worried that if we are selecting only Request::RequestPending\nrequests to cancel - then at the end of this while loop we need an\n\nASSERT(conversionQueue_.empty());\n\nAlthough in fact, we're in a while loop that we can't leave until it's\nempty. Is this a potential for an infinite loop if there is a request in\nhere which is request->status() != Request::RequestPending?\n\nWhich would then take me back to really thinking we shouldn't have that\ncheck - we should cancel *all* requests in conversionQueue_ - or\nidentify that there is a request that shouldn't be here ?\n\n> +               }\n> +               conversionQueue_.pop();\n> +       }\n> +}\n> +\n>  void SimpleCameraData::ispStatsReady(uint32_t frame, uint32_t bufferId)\n>  {\n>         swIsp_->processStats(frame, bufferId,\n> @@ -1406,6 +1420,7 @@ void SimplePipelineHandler::stopDevice(Camera *camera)\n>  \n>         video->bufferReady.disconnect(data, &SimpleCameraData::bufferReady);\n>  \n> +       data->clearIncompleteRequests();\n>         data->conversionBuffers_.clear();\n>  \n>         releasePipeline(data);\n> -- \n> 2.44.1\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id C8767C32DE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  9 Oct 2024 21:54:19 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DE23D63538;\n\tWed,  9 Oct 2024 23:54:18 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id ABC5F618C5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  9 Oct 2024 23:54:17 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id EAE39594;\n\tWed,  9 Oct 2024 23:52:39 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"OaBo+Mkb\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1728510760;\n\tbh=Bs++NENF37W3J4AcAKvtWRhaHqHzURnMI7zLviRTRLc=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=OaBo+MkbPgrkugHKOgjrYBQYXLiKFMuTnGLI0WNeEPXdeRSHSe9+P/4n0cg3GYYyQ\n\tkpN9pmKKWPu4CAEwLrNHhfeQM5ya89VYmPbYdIUIZzu+sFtvvlQQ8l3bvLsQXJuZaR\n\tHXKoyyl8ggOySoVPN+IGEUpewWp8ThMoNEWIAbbg=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20241009172108.2058320-3-mzamazal@redhat.com>","References":"<20241009172108.2058320-1-mzamazal@redhat.com>\n\t<20241009172108.2058320-3-mzamazal@redhat.com>","Subject":"Re: [PATCH v3 2/2] libcamera: software_isp: Clean up pending\n\trequests on stop","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Milan Zamazal <mzamazal@redhat.com>, robert.mader@posteo.de,\n\tlaurent.pinchart@ideasonboard.com","To":"Milan Zamazal <mzamazal@redhat.com>, libcamera-devel@lists.libcamera.org","Date":"Wed, 09 Oct 2024 22:54:14 +0100","Message-ID":"<172851085429.532453.8068218543076263779@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":31686,"web_url":"https://patchwork.libcamera.org/comment/31686/","msgid":"<87v7y0qul7.fsf@redhat.com>","date":"2024-10-10T07:35:00","subject":"Re: [PATCH v3 2/2] libcamera: software_isp: Clean up pending\n\trequests on stop","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Kieran Bingham <kieran.bingham@ideasonboard.com> writes:\n\n> Quoting Milan Zamazal (2024-10-09 18:21:08)\n>> PipelineHandler::stop() calls stopDevice() method to perform pipeline\n>> specific cleanup and then completes waiting requests.  If any queued\n>\n>> requests remain, an assertion error is raised.\n>> \n>> Software ISP stores request buffers in\n>> SimpleCameraData::conversionQueue_ and queues them as V4L2 signals\n>> bufferReady.  stopDevice() cleanup forgets to clean up the buffers and\n>> their requests from conversionQueue_, possibly resulting in the\n>> assertion error.  This patch fixes the omission.\n>> \n>> The problem wasn't very visible when\n>> SimplePipelineHandler::kNumInternalBuffers (the number of buffers\n>> allocated in V4L2) was equal to the number of buffers exported from\n>> software ISP.  But when the number of the exported buffers was increased\n>> by one in commit abe2ec64f9e4e97bbdfe3a50372611bd7b5315c2, the assertion\n>> error started pop up in some environments.  Increasing the number of the\n>> buffers much more, e.g. to 9, makes the problem very reproducible.\n>> \n>> Each pipeline uses its own mechanism to track the requests to clean up\n>> and it can't be excluded that similar omissions are present in other\n>> places.  But there is no obvious way to make a common cleanup for all\n>> the pipelines (except for doing it instead of raising the assertion\n>> error, which is probably undesirable, in order not to hide incomplete\n>> pipeline specific cleanups).\n>> \n>> Bug: https://bugs.libcamera.org/show_bug.cgi?id=234\n>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>> ---\n>>  src/libcamera/pipeline/simple/simple.cpp | 15 +++++++++++++++\n>>  1 file changed, 15 insertions(+)\n>> \n>> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\n>> index 3ddce71d3..ff3859f18 100644\n>> --- a/src/libcamera/pipeline/simple/simple.cpp\n>> +++ b/src/libcamera/pipeline/simple/simple.cpp\n>> @@ -284,6 +284,7 @@ public:\n>>         std::vector<std::unique_ptr<FrameBuffer>> conversionBuffers_;\n>>         std::queue<std::map<const Stream *, FrameBuffer *>> conversionQueue_;\n>>         bool useConversion_;\n>> +       void clearIncompleteRequests();\n>>  \n>>         std::unique_ptr<Converter> converter_;\n>>         std::unique_ptr<SoftwareIsp> swIsp_;\n>> @@ -897,6 +898,19 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)\n>>                 pipe->completeRequest(request);\n>>  }\n>>  \n>> +void SimpleCameraData::clearIncompleteRequests()\n>> +{\n>> +       while (!conversionQueue_.empty()) {\n>> +               for (auto &item : conversionQueue_.front()) {\n>> +                       FrameBuffer *outputBuffer = item.second;\n>> +                       Request *request = outputBuffer->request();\n>> +                       if (request->status() == Request::RequestPending)\n>> +                               pipe()->cancelRequest(request);\n>\n> Hrm. ... Is it possible to have a request on the conversionQueue_ which\n> is not RequestPending ?\n\nThe inner loop iterates over a map of streams and buffers.  If there are\nmultiple buffers in a request, the request gets processed repeatedly\nhere.  On the first run, it's status is pending, after being canceled,\nit's status is different and the next attempts to cancel it are skipped.\n\nI believe all `item's have the same request so it would be sufficient to\nlook at the first `item' but I think it's better to avoid implicit\nassumptions.\n\n> I am worried that if we are selecting only Request::RequestPending\n> requests to cancel - then at the end of this while loop we need an\n>\n> ASSERT(conversionQueue_.empty());\n\nI can add it.\n\n> Although in fact, we're in a while loop that we can't leave until it's\n> empty. Is this a potential for an infinite loop if there is a request in\n> here which is request->status() != Request::RequestPending?\n\nNo, conversionQueue_.pop() below is called unconditionally.\n\n> Which would then take me back to really thinking we shouldn't have that\n> check - we should cancel *all* requests in conversionQueue_ - or\n> identify that there is a request that shouldn't be here ?\n\nThe check is to avoid duplicate cancellation of a request.  If there is\na request with a different status originally and not completed/canceled,\nit will get caught by the assertion in the pipeline handler, I believe.\n\nIt looks like this change introduces confusion.  I'm not sure how to\nimprove it.\n\n>> +               }\n>> +               conversionQueue_.pop();\n>> +       }\n>> +}\n>> +\n>>  void SimpleCameraData::ispStatsReady(uint32_t frame, uint32_t bufferId)\n>>  {\n>>         swIsp_->processStats(frame, bufferId,\n>> @@ -1406,6 +1420,7 @@ void SimplePipelineHandler::stopDevice(Camera *camera)\n>>  \n>>         video->bufferReady.disconnect(data, &SimpleCameraData::bufferReady);\n>>  \n>> +       data->clearIncompleteRequests();\n>>         data->conversionBuffers_.clear();\n>>  \n>>         releasePipeline(data);\n>> -- \n>> 2.44.1\n>>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 655ABC32E0\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 10 Oct 2024 07:35:09 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3DBCE6536B;\n\tThu, 10 Oct 2024 09:35:08 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 388C063538\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 10 Oct 2024 09:35:06 +0200 (CEST)","from mail-wm1-f72.google.com (mail-wm1-f72.google.com\n\t[209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-411-MVuZLAgzOFmH0_ja0hz-Ng-1; Thu, 10 Oct 2024 03:35:03 -0400","by mail-wm1-f72.google.com with SMTP id\n\t5b1f17b1804b1-43056c979c9so3659995e9.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 10 Oct 2024 00:35:03 -0700 (PDT)","from nuthatch (nat-pool-brq-t.redhat.com. [213.175.37.10])\n\tby smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-430d748d450sm40195575e9.39.2024.10.10.00.35.01\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 10 Oct 2024 00:35:01 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"fCK2uI26\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1728545705;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=Uh3wORNUGZl2fR15lXc6MUyH+fua7NEUfJoW/dzjU+c=;\n\tb=fCK2uI261ojZty12SD/Lcm524C2WQxPkHbyL9PYffHBO/7HnOFva01mT4ZVYnovuvhA5Sb\n\tAVK0S//n8wYk1Q8s6BwrF+454OqP6nPfx+rCj92+w6y3WRW7Ggdk7axf3b1fIUrlxWR4lL\n\tXDRCRxwa1wKG+PppbK5GIEU4gP0TRrE=","X-MC-Unique":"MVuZLAgzOFmH0_ja0hz-Ng-1","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1728545702; x=1729150502;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=Uh3wORNUGZl2fR15lXc6MUyH+fua7NEUfJoW/dzjU+c=;\n\tb=urZN0aVzWlYCfCo5Lj7V9f+a2x91i0ldrxT0lo/8oXj1JYkmsBib0dDWXabIi5woAU\n\tUJiFgKylp1K+icbLjMwd+f5uag/6otDrBHRh/rZDyYw8MEPxGuLcDEr191OMMZyKcsUQ\n\tYkFKWZtmBQ2S++kr6xWTTBTnufDzkPJ8gw4qektfIKlspKYcgJK9O8zdxQ4L2pmcXGpD\n\tlS48/jJxgv4qwBDB1nzErPO+yzbrx4sgllYDuasfDllHL1SSuYqHU0qVcKN3q4XbuBa1\n\t8B7MlUGh44xnXFHE1LEcHGz9fI5htBMO8oCNEUziZNEWdUSYK4q70CWoO8wftt7OuMbK\n\tJD8w==","X-Gm-Message-State":"AOJu0YzfqsC7EdZ/bdcJfk2cyc5iL9S/7E4FM9GDOjf2rWIcYuMaFhy4\n\tF8+TmhTxCjN2oUD7VYjt5LCQVTON7rMbb+vmim1+ZCB66CPN7zAXG4St+BJlOpA2nPct2x76bxC\n\txOaPCr2ZErZ0aQ/eY71i+KmL++ehUfS1I2T2W7wBuh9d2ZawI52s+VsUGlEtwnAykm8/NhIg=","X-Received":["by 2002:a05:600c:4fd4:b0:42c:bad0:6c1c with SMTP id\n\t5b1f17b1804b1-430ccf31ba0mr37560685e9.18.1728545702540; \n\tThu, 10 Oct 2024 00:35:02 -0700 (PDT)","by 2002:a05:600c:4fd4:b0:42c:bad0:6c1c with SMTP id\n\t5b1f17b1804b1-430ccf31ba0mr37560495e9.18.1728545702102; \n\tThu, 10 Oct 2024 00:35:02 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IFjtKJKcZxiV55UXUn4SL+sllVJ80sH4s+Sylz7r6gCDcJtx7GKqE0pwstlUW6T3jRdmy8LFg==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,  robert.mader@posteo.de,\n\tlaurent.pinchart@ideasonboard.com","Subject":"Re: [PATCH v3 2/2] libcamera: software_isp: Clean up pending\n\trequests on stop","In-Reply-To":"<172851085429.532453.8068218543076263779@ping.linuxembedded.co.uk>\n\t(Kieran Bingham's message of \"Wed, 09 Oct 2024 22:54:14 +0100\")","References":"<20241009172108.2058320-1-mzamazal@redhat.com>\n\t<20241009172108.2058320-3-mzamazal@redhat.com>\n\t<172851085429.532453.8068218543076263779@ping.linuxembedded.co.uk>","Date":"Thu, 10 Oct 2024 09:35:00 +0200","Message-ID":"<87v7y0qul7.fsf@redhat.com>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":31700,"web_url":"https://patchwork.libcamera.org/comment/31700/","msgid":"<172856903992.532453.5124403973269017497@ping.linuxembedded.co.uk>","date":"2024-10-10T14:03:59","subject":"Re: [PATCH v3 2/2] libcamera: software_isp: Clean up pending\n\trequests on stop","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Milan Zamazal (2024-10-10 08:35:00)\n> Kieran Bingham <kieran.bingham@ideasonboard.com> writes:\n> \n> > Quoting Milan Zamazal (2024-10-09 18:21:08)\n> >> PipelineHandler::stop() calls stopDevice() method to perform pipeline\n> >> specific cleanup and then completes waiting requests.  If any queued\n> >\n> >> requests remain, an assertion error is raised.\n> >> \n> >> Software ISP stores request buffers in\n> >> SimpleCameraData::conversionQueue_ and queues them as V4L2 signals\n> >> bufferReady.  stopDevice() cleanup forgets to clean up the buffers and\n> >> their requests from conversionQueue_, possibly resulting in the\n> >> assertion error.  This patch fixes the omission.\n> >> \n> >> The problem wasn't very visible when\n> >> SimplePipelineHandler::kNumInternalBuffers (the number of buffers\n> >> allocated in V4L2) was equal to the number of buffers exported from\n> >> software ISP.  But when the number of the exported buffers was increased\n> >> by one in commit abe2ec64f9e4e97bbdfe3a50372611bd7b5315c2, the assertion\n> >> error started pop up in some environments.  Increasing the number of the\n> >> buffers much more, e.g. to 9, makes the problem very reproducible.\n> >> \n> >> Each pipeline uses its own mechanism to track the requests to clean up\n> >> and it can't be excluded that similar omissions are present in other\n> >> places.  But there is no obvious way to make a common cleanup for all\n> >> the pipelines (except for doing it instead of raising the assertion\n> >> error, which is probably undesirable, in order not to hide incomplete\n> >> pipeline specific cleanups).\n> >> \n> >> Bug: https://bugs.libcamera.org/show_bug.cgi?id=234\n> >> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> >> ---\n> >>  src/libcamera/pipeline/simple/simple.cpp | 15 +++++++++++++++\n> >>  1 file changed, 15 insertions(+)\n> >> \n> >> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\n> >> index 3ddce71d3..ff3859f18 100644\n> >> --- a/src/libcamera/pipeline/simple/simple.cpp\n> >> +++ b/src/libcamera/pipeline/simple/simple.cpp\n> >> @@ -284,6 +284,7 @@ public:\n> >>         std::vector<std::unique_ptr<FrameBuffer>> conversionBuffers_;\n> >>         std::queue<std::map<const Stream *, FrameBuffer *>> conversionQueue_;\n> >>         bool useConversion_;\n> >> +       void clearIncompleteRequests();\n> >>  \n> >>         std::unique_ptr<Converter> converter_;\n> >>         std::unique_ptr<SoftwareIsp> swIsp_;\n> >> @@ -897,6 +898,19 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)\n> >>                 pipe->completeRequest(request);\n> >>  }\n> >>  \n> >> +void SimpleCameraData::clearIncompleteRequests()\n> >> +{\n> >> +       while (!conversionQueue_.empty()) {\n> >> +               for (auto &item : conversionQueue_.front()) {\n> >> +                       FrameBuffer *outputBuffer = item.second;\n> >> +                       Request *request = outputBuffer->request();\n> >> +                       if (request->status() == Request::RequestPending)\n> >> +                               pipe()->cancelRequest(request);\n> >\n> > Hrm. ... Is it possible to have a request on the conversionQueue_ which\n> > is not RequestPending ?\n> \n> The inner loop iterates over a map of streams and buffers.  If there are\n> multiple buffers in a request, the request gets processed repeatedly\n> here.  On the first run, it's status is pending, after being canceled,\n> it's status is different and the next attempts to cancel it are skipped.\n> \n> I believe all `item's have the same request so it would be sufficient to\n> look at the first `item' but I think it's better to avoid implicit\n> assumptions.\n> \n> > I am worried that if we are selecting only Request::RequestPending\n> > requests to cancel - then at the end of this while loop we need an\n> >\n> > ASSERT(conversionQueue_.empty());\n> \n> I can add it.\n\nI wouldn't now I understand the while loop better. There's no break, and\nno way to get out of while (!conversionQueue_.empty()) { } without the\nqueue being emptied...\n\n\n> > Although in fact, we're in a while loop that we can't leave until it's\n> > empty. Is this a potential for an infinite loop if there is a request in\n> > here which is request->status() != Request::RequestPending?\n> \n> No, conversionQueue_.pop() below is called unconditionally.\n\nOoops, I missed that I think.\n\n> \n> > Which would then take me back to really thinking we shouldn't have that\n> > check - we should cancel *all* requests in conversionQueue_ - or\n> > identify that there is a request that shouldn't be here ?\n> \n> The check is to avoid duplicate cancellation of a request.  If there is\n> a request with a different status originally and not completed/canceled,\n> it will get caught by the assertion in the pipeline handler, I believe.\n> \n> It looks like this change introduces confusion.  I'm not sure how to\n> improve it.\n\nIt's probably just me not understanding things ;-)\n\nOk - so perhaps the part I missed is that the queue will always be\nemptied, because ...\n\n> \n> >> +               }\n\n... I missed reading that } so the next line always happens ;-)\n\n\n> >> +               conversionQueue_.pop();\n\nI thought we were only popping off requests that were directly cancelled\nabove.\n\nSo it seems correct ... \n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> >> +       }\n> >> +}\n> >> +\n> >>  void SimpleCameraData::ispStatsReady(uint32_t frame, uint32_t bufferId)\n> >>  {\n> >>         swIsp_->processStats(frame, bufferId,\n> >> @@ -1406,6 +1420,7 @@ void SimplePipelineHandler::stopDevice(Camera *camera)\n> >>  \n> >>         video->bufferReady.disconnect(data, &SimpleCameraData::bufferReady);\n> >>  \n> >> +       data->clearIncompleteRequests();\n> >>         data->conversionBuffers_.clear();\n> >>  \n> >>         releasePipeline(data);\n> >> -- \n> >> 2.44.1\n> >>\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 284A7C32E0\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 10 Oct 2024 14:04:06 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 26E016353B;\n\tThu, 10 Oct 2024 16:04:05 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 226DF6353A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 10 Oct 2024 16:04:03 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E16BD4D4;\n\tThu, 10 Oct 2024 16:02:24 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"jBKMxXYF\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1728568945;\n\tbh=O1lIkqA41X9xXgsrKvgr0GjaMYg/B+nTaTkGuRJLfwk=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=jBKMxXYFaDNT4vhXwSjNUk2JEOmtjs1UTsVtaShlG3wLJvBkuFSor2XMr1jxJbJ9I\n\tKNmDOWXSCTzZJzgMq8E+NoZ5cWSJRj2mxlod08UhC/z/sWpOXSEL4mELaCEHxh3B+i\n\tHpvV985YQYKlROl7FfRmkpIgJflBfmCCf7OGsoJo=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<87v7y0qul7.fsf@redhat.com>","References":"<20241009172108.2058320-1-mzamazal@redhat.com>\n\t<20241009172108.2058320-3-mzamazal@redhat.com>\n\t<172851085429.532453.8068218543076263779@ping.linuxembedded.co.uk>\n\t<87v7y0qul7.fsf@redhat.com>","Subject":"Re: [PATCH v3 2/2] libcamera: software_isp: Clean up pending\n\trequests on stop","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org, robert.mader@posteo.de,\n\tlaurent.pinchart@ideasonboard.com","To":"Milan Zamazal <mzamazal@redhat.com>","Date":"Thu, 10 Oct 2024 15:03:59 +0100","Message-ID":"<172856903992.532453.5124403973269017497@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]