blob: 6692b805ec454bd6751d5515c19bc74d927bfefc [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* The interface for waiting on multiple inter-IP fences to complete the signaler submission.
*
* Copyright (C) 2023 Google LLC
*/
#ifndef __IIF_IIF_SIGNALER_SUBMISSION_WAITER_H__
#define __IIF_IIF_SIGNALER_SUBMISSION_WAITER_H__
#include <gcip/iif/iif-fence.h>
#define IIF_NO_REGISTER_EVENTFD (~0u)
/*
* These structures are not supposed to be used by the IP drivers.
* They must use the `iif_wait_signaler_submission` function below directly.
*/
/* Waiter which waits on multiple fences to finish the signaler submission. */
struct iif_signaler_submission_waiter {
/* Registered callbacks. */
struct list_head cb_list;
/* Refcount. */
struct kref kref;
/* Eventfd context. */
struct eventfd_ctx *ctx;
/* The number of remaining fences to register the callback. */
int pending_fences;
/* True if waiter is cancelled and all callbacks in @cb_list should be flushed. */
bool cancel;
/* Protects @cb_list, @pending_fences and @cancel. */
spinlock_t lock;
};
/* Contains information required when each fence calls the signaler_submitted callback. */
struct iif_signaler_submission_waiter_cb {
/* The callback object which will be registered to @fence. */
struct iif_fence_all_signaler_submitted_cb fence_cb;
/* The fence which is going to finish the signaler submission. */
struct iif_fence *fence;
/* The waiter instance which waits on this callback. */
struct iif_signaler_submission_waiter *waiter;
/* The node to be added to @waiter->cb_list. */
struct list_head node;
};
/*
* Waits on @fences to complete the signaler submission. If at least one of @fences have remaining
* signalers to be submitted, it will register @eventfd and will trigger it once all fences have
* finishes the submission. Also, the number of remaining signalers of each fence will be returned
* to @remaining_signalers in the same order with @fences.
*
* If @eventfd is IIF_NO_REGISTER_EVENTFD, this function won't wait on @fences to finish signaler
* submission and will simply return the number of remaining signalers of each fence.
*
* Returns 0 on success. Otherwise, returns a negative errno.
*/
int iif_wait_signaler_submission(struct iif_fence **fences, int num_fences, unsigned int eventfd,
int *remaining_signalers);
/* Increments the refcount of @waiter. */
struct iif_signaler_submission_waiter *
iif_all_signaler_submission_waiter_get(struct iif_signaler_submission_waiter *waiter);
/* Decrements the refcount of @waiter and releases it if the count becomes 0. */
void iif_all_signaler_submission_waiter_put(struct iif_signaler_submission_waiter *waiter);
#endif /* __IIF_IIF_SIGNALER_SUBMISSION_WAITER_H__ */