[libcamera-devel] [PATCH v1 3/4] ipa: ipu3: Prevent over queuing of requests

Umang Jain umang.jain at ideasonboard.com
Fri Jun 3 15:22:58 CEST 2022


The IPAIPU3 processes each IPAFrameContext present in the FCQueue
ring buffer. If the application queues the requests at a pace where
IPAFrameContext(s) can get potentially over-written without getting
processed by the IPA, it would lead to un-desirable effects.

Hence, inspect the FCQueue if it is full and reject any further
queuing of requests. This requires changes to the IPAIPU3 mojom
interface. The IPAIPU3::queueRequest() cannot be [async] anymore
since we need to return a success/failure value.

The rejection by the IPA doesn't mean it cannot be queued
later. The request is still preserved in
IPU3CameraData::pendingRequests_. It shall be queued sequentially
on subsequent calls to  IPU3CameraData::queuePendingRequests().

Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
---
I am not super-happy with changing the interface and dropping [async]
but this is what I've for now. Would appreciate any other ideas...
---
 include/libcamera/ipa/ipu3.mojom     |  2 +-
 src/ipa/ipu3/ipu3.cpp                | 11 +++++++++--
 src/libcamera/pipeline/ipu3/ipu3.cpp | 10 +++++++++-
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom
index d1b1c6b8..3faffd9c 100644
--- a/include/libcamera/ipa/ipu3.mojom
+++ b/include/libcamera/ipa/ipu3.mojom
@@ -30,7 +30,7 @@ interface IPAIPU3Interface {
 	mapBuffers(array<libcamera.IPABuffer> buffers);
 	unmapBuffers(array<uint32> ids);
 
-	[async] queueRequest(uint32 frame, libcamera.ControlList controls);
+	queueRequest(uint32 frame, libcamera.ControlList controls) => (int32 ret);
 	[async] fillParamsBuffer(uint32 frame, uint32 bufferId);
 	[async] processStatsBuffer(uint32 frame, int64 frameTimestamp,
 				   uint32 bufferId, libcamera.ControlList sensorControls);
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 1d6ee515..63aa9b56 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -145,7 +145,7 @@ public:
 	void mapBuffers(const std::vector<IPABuffer> &buffers) override;
 	void unmapBuffers(const std::vector<unsigned int> &ids) override;
 
-	void queueRequest(const uint32_t frame, const ControlList &controls) override;
+	int queueRequest(const uint32_t frame, const ControlList &controls) override;
 	void fillParamsBuffer(const uint32_t frame, const uint32_t bufferId) override;
 	void processStatsBuffer(const uint32_t frame, const int64_t frameTimestamp,
 				const uint32_t bufferId,
@@ -616,11 +616,18 @@ void IPAIPU3::processStatsBuffer(const uint32_t frame,
  *
  * Parse the request to handle any IPA-managed controls that were set from the
  * application such as manual sensor settings.
+ *
+ * \return 0 if successful, -EPERM otherwise.
  */
-void IPAIPU3::queueRequest(const uint32_t frame, const ControlList &controls)
+int IPAIPU3::queueRequest(const uint32_t frame, const ControlList &controls)
 {
+	if (context_.frameContexts.isFull())
+		return -EPERM;
+
 	/* \todo Start processing for 'frame' based on 'controls'. */
 	*context_.frameContexts.get(frame) = { frame, controls };
+
+	return 0;
 }
 
 /**
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index fd989e61..d69e28d4 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -874,7 +874,15 @@ void IPU3CameraData::queuePendingRequests()
 
 		info->rawBuffer = rawBuffer;
 
-		ipa_->queueRequest(info->id, request->controls());
+		/*
+		 * Queueing request to the IPA can fail in cases like over-flowing
+		 * its queue. Hence, keep the request preserved in pendingRequests_
+		 * if a failure occurs.
+		 */
+		if (ipa_->queueRequest(info->id, request->controls()) != 0) {
+			frameInfos_.remove(info);
+			break;
+		}
 
 		pendingRequests_.pop();
 		processingRequests_.push(request);
-- 
2.31.1



More information about the libcamera-devel mailing list