diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2018-08-27 11:10:38 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-09-11 09:53:31 -0400 |
commit | 6736f4e948817ca8385bdc6feb5475cdf1eb1ec8 (patch) | |
tree | 073eb0d6ce248e12b7fa74ca9f3e3941b9e5bc6e /include/media | |
parent | e5079cf11373e4cc98be8b1072aece429eb2d4d2 (diff) | |
download | linux-6736f4e948817ca8385bdc6feb5475cdf1eb1ec8.tar.bz2 |
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.h | 56 |
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; |