/* Just a sanity check. No other code path is allowed to change this. */
WARN_ON(req->state != MEDIA_REQUEST_STATE_CLEANING);
WARN_ON(req->updating_count);
WARN_ON(req->access_count);
/* * Ensure the request that is validated will be the one that gets queued * next by serialising the queueing process. This mutex is also used * to serialize with canceling a vb2 queue and with setting values such * as controls in a request.
*/
mutex_lock(&mdev->req_queue_mutex);
media_request_get(req);
spin_lock_irqsave(&req->lock, flags); if (req->state == MEDIA_REQUEST_STATE_IDLE)
req->state = MEDIA_REQUEST_STATE_VALIDATING;
state = req->state;
spin_unlock_irqrestore(&req->lock, flags); if (state != MEDIA_REQUEST_STATE_VALIDATING) {
dev_dbg(mdev->dev, "request: unable to queue %s, request in state %s\n",
req->debug_str, media_request_state_str(state));
media_request_put(req);
mutex_unlock(&mdev->req_queue_mutex); return -EBUSY;
}
ret = mdev->ops->req_validate(req);
/* * If the req_validate was successful, then we mark the state as QUEUED * and call req_queue. The reason we set the state first is that this * allows req_queue to unbind or complete the queued objects in case * they are immediately 'consumed'. State changes from QUEUED to another * state can only happen if either the driver changes the state or if * the user cancels the vb2 queue. The driver can only change the state * after each object is queued through the req_queue op (and note that * that op cannot fail), so setting the state to QUEUED up front is * safe. * * The other reason for changing the state is if the vb2 queue is * canceled, and that uses the req_queue_mutex which is still locked * while req_queue is called, so that's safe as well.
*/
spin_lock_irqsave(&req->lock, flags);
req->state = ret ? MEDIA_REQUEST_STATE_IDLE
: MEDIA_REQUEST_STATE_QUEUED;
spin_unlock_irqrestore(&req->lock, flags);
if (!mdev || !mdev->ops ||
!mdev->ops->req_validate || !mdev->ops->req_queue) return ERR_PTR(-EBADR);
CLASS(fd, f)(request_fd); if (fd_empty(f)) goto err;
if (fd_file(f)->f_op != &request_fops) goto err;
req = fd_file(f)->private_data; if (req->mdev != mdev) goto err;
/* * Note: as long as someone has an open filehandle of the request, * the request can never be released. The fdget() above ensures that * even if userspace closes the request filehandle, the release() * fop won't be called, so the media_request_get() always succeeds * and there is no race condition where the request was released * before media_request_get() is called.
*/
media_request_get(req); return req;
spin_lock_irqsave(&req->lock, flags); if (obj->completed) goto unlock;
obj->completed = true; if (WARN_ON(!req->num_incomplete_objects) ||
WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED)) goto unlock;
if (!--req->num_incomplete_objects) {
req->state = MEDIA_REQUEST_STATE_COMPLETE;
wake_up_interruptible_all(&req->poll_wait);
completed = true;
}
unlock:
spin_unlock_irqrestore(&req->lock, flags); if (completed)
media_request_put(req);
}
EXPORT_SYMBOL_GPL(media_request_object_complete);
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.11Bemerkung:
(vorverarbeitet am 2026-06-07)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.