{"id":12257,"url":"https://patchwork.libcamera.org/api/1.1/patches/12257/?format=json","web_url":"https://patchwork.libcamera.org/patch/12257/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20210513022946.2194341-1-hiroh@chromium.org>","date":"2021-05-13T02:29:45","name":"[libcamera-devel,v5,1/2] pipeline: ipu3: Store requests in the case a buffer shortage","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"5c4c896d0a397d8bf8bbef1cd80a0d51552943fa","submitter":{"id":63,"url":"https://patchwork.libcamera.org/api/1.1/people/63/?format=json","name":"Hirokazu Honda","email":"hiroh@chromium.org"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/12257/mbox/","series":[{"id":2021,"url":"https://patchwork.libcamera.org/api/1.1/series/2021/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=2021","date":"2021-05-13T02:29:45","name":"[libcamera-devel,v5,1/2] pipeline: ipu3: Store requests in the case a buffer shortage","version":5,"mbox":"https://patchwork.libcamera.org/series/2021/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/12257/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/12257/checks/","tags":{},"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 BEA40C1D12\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 13 May 2021 02:29:57 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4BEBE6891A;\n\tThu, 13 May 2021 04:29:56 +0200 (CEST)","from mail-pg1-x52c.google.com (mail-pg1-x52c.google.com\n\t[IPv6:2607:f8b0:4864:20::52c])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8A19961538\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 13 May 2021 04:29:54 +0200 (CEST)","by mail-pg1-x52c.google.com with SMTP id s22so19893075pgk.6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 12 May 2021 19:29:54 -0700 (PDT)","from hiroh2.tok.corp.google.com\n\t([2401:fa00:8f:2:90f6:be0f:1d8a:d075])\n\tby smtp.gmail.com with ESMTPSA id\n\td23sm864358pfo.80.2021.05.12.19.29.50\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 12 May 2021 19:29:51 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"a785MDA2\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org;\n\ts=google; h=from:to:cc:subject:date:message-id:mime-version\n\t:content-transfer-encoding;\n\tbh=xOJ+v1Pkn4CaBBnLJFL78g5tgqEuNDo694T4tDXiVIE=;\n\tb=a785MDA21gPG+5pKDFIxjdHhs2eO8LQd6FZMaSZzN33MWWQThQwItJF20sg1ljz74z\n\t2CaNQr0bc9Hjh8bI+UCxegcSNetV02H5kJ+9sNcOBDMRxmHW65ONquuvzwG8VUn4YOGa\n\tRch7wzYcW+dRzq75Q12/eAkzXUjrdZnxOGZE0=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version\n\t:content-transfer-encoding;\n\tbh=xOJ+v1Pkn4CaBBnLJFL78g5tgqEuNDo694T4tDXiVIE=;\n\tb=sL9TgxPQ3K0vJfHaGDx2rWMJHThKfCLVf7VKtLLZbBwJposQRUktOQ7PhqIf4mfu9b\n\tksxGQPnD5rN3yAda7Ij48CloBzYinTNC8SVqplMN3x3USHiGJozs1MuacI8AjkU7VfHd\n\t8rKH8HfVVV8kM2fGTKRwVqoQorFwUEKxgGyoZF4ic7KxSxhSwObGWolPrfyOYkS0rW3e\n\tt6s6AONN2/ak/uRmpeorQdPKSktZJJwBDCMfjlh+luc0uKcSXVGp2s2Dnx12ND+m5Ls4\n\tiHyXHkg8bfV5KRxNj2caj6MSOYzxeb2pVnR2ABQppjJN4fl9FU4E4cbhTwDdkxVf+i23\n\tMWDA==","X-Gm-Message-State":"AOAM530mESDq+6rLrotIq2aNLldje5SoAi7PZXxAM1vKmFPhdhUrdcJW\n\tbybWJIjNgP0LBNudtKpWdf9sWVvEIKYTeA==","X-Google-Smtp-Source":"ABdhPJwD6VmRpogQcO9+KZX66cCv6LoX5kIZpJl9tMwR7DTDpDE/mTxVlt7FU0mzLsHbJ7HDAvEujw==","X-Received":"by 2002:a17:90a:1382:: with SMTP id\n\ti2mr42990705pja.176.1620872992349; \n\tWed, 12 May 2021 19:29:52 -0700 (PDT)","From":"Hirokazu Honda <hiroh@chromium.org>","To":"libcamera-devel@lists.libcamera.org","Date":"Thu, 13 May 2021 11:29:45 +0900","Message-Id":"<20210513022946.2194341-1-hiroh@chromium.org>","X-Mailer":"git-send-email 2.31.1.607.g51e8a6a459-goog","MIME-Version":"1.0","Subject":"[libcamera-devel] [PATCH v5 1/2] pipeline: ipu3: Store requests in\n\tthe case a buffer shortage","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>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"PipelineHandlerIPU3 returns -ENOBUFS and -ENOMEM on queueing a\nrequest when there are not sufficient buffers for the request.\nSince the request will be successful if it is queued later when\nenough buffers are available. The requests failed due to a buffer\nshortage should be stored and retried later in the FIFO order.\nThis introduces the queue in IPU3CameraData to do that.\n\nSigned-off-by: Hirokazu Honda <hiroh@chromium.org>\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n---\n src/libcamera/pipeline/ipu3/cio2.cpp   |  2 +-\n src/libcamera/pipeline/ipu3/frames.cpp |  4 +-\n src/libcamera/pipeline/ipu3/ipu3.cpp   | 80 +++++++++++++++++++-------\n 3 files changed, 63 insertions(+), 23 deletions(-)","diff":"diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp\nindex 3cd777d1..8bbef174 100644\n--- a/src/libcamera/pipeline/ipu3/cio2.cpp\n+++ b/src/libcamera/pipeline/ipu3/cio2.cpp\n@@ -272,7 +272,7 @@ FrameBuffer *CIO2Device::queueBuffer(Request *request, FrameBuffer *rawBuffer)\n \t/* If no buffer is provided in the request, use an internal one. */\n \tif (!buffer) {\n \t\tif (availableBuffers_.empty()) {\n-\t\t\tLOG(IPU3, Error) << \"CIO2 buffer underrun\";\n+\t\t\tLOG(IPU3, Debug) << \"CIO2 buffer underrun\";\n \t\t\treturn nullptr;\n \t\t}\n \ndiff --git a/src/libcamera/pipeline/ipu3/frames.cpp b/src/libcamera/pipeline/ipu3/frames.cpp\nindex d0f55ab9..29d9aafc 100644\n--- a/src/libcamera/pipeline/ipu3/frames.cpp\n+++ b/src/libcamera/pipeline/ipu3/frames.cpp\n@@ -44,12 +44,12 @@ IPU3Frames::Info *IPU3Frames::create(Request *request)\n \tunsigned int id = request->sequence();\n \n \tif (availableParamBuffers_.empty()) {\n-\t\tLOG(IPU3, Error) << \"Parameters buffer underrun\";\n+\t\tLOG(IPU3, Debug) << \"Parameters buffer underrun\";\n \t\treturn nullptr;\n \t}\n \n \tif (availableStatBuffers_.empty()) {\n-\t\tLOG(IPU3, Error) << \"Statistics buffer underrun\";\n+\t\tLOG(IPU3, Debug) << \"Statistics buffer underrun\";\n \t\treturn nullptr;\n \t}\n \ndiff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex ade8ffbd..6961d498 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -66,6 +66,8 @@ public:\n \tvoid cio2BufferReady(FrameBuffer *buffer);\n \tvoid paramBufferReady(FrameBuffer *buffer);\n \tvoid statBufferReady(FrameBuffer *buffer);\n+\tvoid queuePendingRequests();\n+\tvoid cancelPendingRequests();\n \n \tCIO2Device cio2_;\n \tImgUDevice *imgu_;\n@@ -84,6 +86,8 @@ public:\n \n \tstd::unique_ptr<ipa::ipu3::IPAProxyIPU3> ipa_;\n \n+\tstd::queue<Request *> pendingRequests_;\n+\n private:\n \tvoid queueFrameAction(unsigned int id,\n \t\t\t      const ipa::ipu3::IPU3Action &action);\n@@ -764,6 +768,8 @@ void PipelineHandlerIPU3::stop(Camera *camera)\n \tIPU3CameraData *data = cameraData(camera);\n \tint ret = 0;\n \n+\tdata->cancelPendingRequests();\n+\n \tdata->ipa_->stop();\n \n \tret |= data->imgu_->stop();\n@@ -774,32 +780,66 @@ void PipelineHandlerIPU3::stop(Camera *camera)\n \tfreeBuffers(camera);\n }\n \n-int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)\n+void IPU3CameraData::cancelPendingRequests()\n {\n-\tIPU3CameraData *data = cameraData(camera);\n+\twhile (!pendingRequests_.empty()) {\n+\t\tRequest *request = pendingRequests_.front();\n \n-\tIPU3Frames::Info *info = data->frameInfos_.create(request);\n-\tif (!info)\n-\t\treturn -ENOBUFS;\n+\t\tfor (auto it : request->buffers()) {\n+\t\t\tFrameBuffer *buffer = it.second;\n+\t\t\tbuffer->cancel();\n+\t\t\tpipe_->completeBuffer(request, buffer);\n+\t\t}\n \n-\t/*\n-\t * Queue a buffer on the CIO2, using the raw stream buffer provided in\n-\t * the request, if any, or a CIO2 internal buffer otherwise.\n-\t */\n-\tFrameBuffer *reqRawBuffer = request->findBuffer(&data->rawStream_);\n-\tFrameBuffer *rawBuffer = data->cio2_.queueBuffer(request, reqRawBuffer);\n-\tif (!rawBuffer) {\n-\t\tdata->frameInfos_.remove(info);\n-\t\treturn -ENOMEM;\n+\t\tpipe_->completeRequest(request);\n+\t\tpendingRequests_.pop();\n \t}\n+}\n \n-\tinfo->rawBuffer = rawBuffer;\n+void IPU3CameraData::queuePendingRequests()\n+{\n+\twhile (!pendingRequests_.empty()) {\n+\t\tRequest *request = pendingRequests_.front();\n \n-\tipa::ipu3::IPU3Event ev;\n-\tev.op = ipa::ipu3::EventProcessControls;\n-\tev.frame = info->id;\n-\tev.controls = request->controls();\n-\tdata->ipa_->processEvent(ev);\n+\t\tIPU3Frames::Info *info = frameInfos_.create(request);\n+\t\tif (!info)\n+\t\t\tbreak;\n+\n+\t\t/*\n+\t\t * Queue a buffer on the CIO2, using the raw stream buffer\n+\t\t * provided in the request, if any, or a CIO2 internal buffer\n+\t\t * otherwise.\n+\t\t */\n+\t\tFrameBuffer *reqRawBuffer = request->findBuffer(&rawStream_);\n+\t\tFrameBuffer *rawBuffer = cio2_.queueBuffer(request, reqRawBuffer);\n+\t\t/*\n+\t\t * \\todo If queueBuffer fails in queuing a buffer to the device,\n+\t\t * report the request as error by cancelling the request and\n+\t\t * calling PipelineHandler::completeRequest().\n+\t\t */\n+\t\tif (!rawBuffer) {\n+\t\t\tframeInfos_.remove(info);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tinfo->rawBuffer = rawBuffer;\n+\n+\t\tipa::ipu3::IPU3Event ev;\n+\t\tev.op = ipa::ipu3::EventProcessControls;\n+\t\tev.frame = info->id;\n+\t\tev.controls = request->controls();\n+\t\tipa_->processEvent(ev);\n+\n+\t\tpendingRequests_.pop();\n+\t}\n+}\n+\n+int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)\n+{\n+\tIPU3CameraData *data = cameraData(camera);\n+\n+\tdata->pendingRequests_.push(request);\n+\tdata->queuePendingRequests();\n \n \treturn 0;\n }\n","prefixes":["libcamera-devel","v5","1/2"]}