summaryrefslogtreecommitdiffstats
path: root/include/media
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2018-08-27 11:10:38 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-09-11 09:53:31 -0400
commit6736f4e948817ca8385bdc6feb5475cdf1eb1ec8 (patch)
tree073eb0d6ce248e12b7fa74ca9f3e3941b9e5bc6e /include/media
parente5079cf11373e4cc98be8b1072aece429eb2d4d2 (diff)
downloadlinux-6736f4e948817ca8385bdc6feb5475cdf1eb1ec8.tar.gz
linux-6736f4e948817ca8385bdc6feb5475cdf1eb1ec8.tar.bz2
linux-6736f4e948817ca8385bdc6feb5475cdf1eb1ec8.zip
media: media-request: add media_request_(un)lock_for_access
Add helper functions to prevent a completed request from being re-inited while it is being accessed. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Reviewed-by: Tomasz Figa <tfiga@chromium.org> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'include/media')
-rw-r--r--include/media/media-request.h56
1 files changed, 56 insertions, 0 deletions
diff --git a/include/media/media-request.h b/include/media/media-request.h
index 453a6b95c61a..f0920aa84509 100644
--- a/include/media/media-request.h
+++ b/include/media/media-request.h
@@ -53,6 +53,7 @@ struct media_request_object;
* @debug_str: Prefix for debug messages (process name:fd)
* @state: The state of the request
* @updating_count: count the number of request updates that are in progress
+ * @access_count: count the number of request accesses that are in progress
* @objects: List of @struct media_request_object request objects
* @num_incomplete_objects: The number of incomplete objects in the request
* @poll_wait: Wait queue for poll
@@ -64,6 +65,7 @@ struct media_request {
char debug_str[TASK_COMM_LEN + 11];
enum media_request_state state;
unsigned int updating_count;
+ unsigned int access_count;
struct list_head objects;
unsigned int num_incomplete_objects;
struct wait_queue_head poll_wait;
@@ -73,6 +75,50 @@ struct media_request {
#ifdef CONFIG_MEDIA_CONTROLLER
/**
+ * media_request_lock_for_access - Lock the request to access its objects
+ *
+ * @req: The media request
+ *
+ * Use before accessing a completed request. A reference to the request must
+ * be held during the access. This usually takes place automatically through
+ * a file handle. Use @media_request_unlock_for_access when done.
+ */
+static inline int __must_check
+media_request_lock_for_access(struct media_request *req)
+{
+ unsigned long flags;
+ int ret = -EBUSY;
+
+ spin_lock_irqsave(&req->lock, flags);
+ if (req->state == MEDIA_REQUEST_STATE_COMPLETE) {
+ req->access_count++;
+ ret = 0;
+ }
+ spin_unlock_irqrestore(&req->lock, flags);
+
+ return ret;
+}
+
+/**
+ * media_request_unlock_for_access - Unlock a request previously locked for
+ * access
+ *
+ * @req: The media request
+ *
+ * Unlock a request that has previously been locked using
+ * @media_request_lock_for_access.
+ */
+static inline void media_request_unlock_for_access(struct media_request *req)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&req->lock, flags);
+ if (!WARN_ON(!req->access_count))
+ req->access_count--;
+ spin_unlock_irqrestore(&req->lock, flags);
+}
+
+/**
* media_request_lock_for_update - Lock the request for updating its objects
*
* @req: The media request
@@ -334,6 +380,16 @@ void media_request_object_complete(struct media_request_object *obj);
#else
static inline int __must_check
+media_request_lock_for_access(struct media_request *req)
+{
+ return -EINVAL;
+}
+
+static inline void media_request_unlock_for_access(struct media_request *req)
+{
+}
+
+static inline int __must_check
media_request_lock_for_update(struct media_request *req)
{
return -EINVAL;