| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- /*
- *
- * (C) COPYRIGHT ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation, and any use by you of this program is subject to the terms
- * of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained
- * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
- #ifndef _KDS_H_
- #define _KDS_H_
- #include <linux/list.h>
- #include <linux/workqueue.h>
- #define KDS_WAIT_BLOCKING (ULONG_MAX)
- struct kds_resource_set;
- typedef void (*kds_callback_fn) (void *callback_parameter, void *callback_extra_parameter);
- struct kds_callback
- {
- kds_callback_fn user_cb; /* real cb */
- int direct; /* do direct or queued call? */
- struct workqueue_struct *wq;
- };
- struct kds_link
- {
- struct kds_resource_set *parent;
- struct list_head link;
- unsigned long state;
- };
- struct kds_resource
- {
- struct kds_link waiters;
- };
- /* callback API */
- /* Initialize a callback object.
- *
- * Typically created per context or per hw resource.
- *
- * Callbacks can be performed directly if no nested locking can
- * happen in the client.
- *
- * Nested locking can occur when a lock is held during the kds_async_waitall or
- * kds_resource_set_release call. If the callback needs to take the same lock
- * nested locking will happen.
- *
- * If nested locking could happen non-direct callbacks can be requested.
- * Callbacks will then be called asynchronous to the triggering call.
- */
- int kds_callback_init(struct kds_callback *cb, int direct, kds_callback_fn user_cb);
- /* Terminate the use of a callback object.
- *
- * If the callback object was set up as non-direct
- * any pending callbacks will be flushed first.
- * Note that to avoid a deadlock the lock callbacks needs
- * can't be held when a callback object is terminated.
- */
- void kds_callback_term(struct kds_callback *cb);
- /* resource object API */
- /* initialize a resource handle for a shared resource */
- void kds_resource_init(struct kds_resource * const resource);
- /*
- * Will return 0 on success.
- * If the resource is being used or waited -EBUSY is returned.
- * The caller should NOT try to terminate a resource that could still have clients.
- * After the function returns the resource is no longer known by kds.
- */
- int kds_resource_term(struct kds_resource *resource);
- /* Asynchronous wait for a set of resources.
- * Callback will be called when all resources are available.
- * If all the resources was available the callback will be called before kds_async_waitall returns.
- * So one must not hold any locks the callback code-flow can take when calling kds_async_waitall.
- * Caller considered to own/use the resources until \a kds_rset_release is called.
- * exclusive_access_bitmap is a bitmap where a high bit means exclusive access while a low bit means shared access.
- * Use the Linux __set_bit API, where the index of the buffer to control is used as the bit index.
- *
- * Standard Linux error return value.
- */
- int kds_async_waitall(
- struct kds_resource_set ** const pprset,
- struct kds_callback *cb,
- void *callback_parameter,
- void *callback_extra_parameter,
- int number_resources,
- unsigned long *exclusive_access_bitmap,
- struct kds_resource **resource_list);
- /* Synchronous wait for a set of resources.
- * Function will return when one of these have happened:
- * - all resources have been obtained
- * - timeout lapsed while waiting
- * - a signal was received while waiting
- *
- * To wait without a timeout, specify KDS_WAIT_BLOCKING for \a jifies_timeout, otherwise
- * the timeout in jiffies. A zero timeout attempts to obtain all resources and returns
- * immediately with a timeout if all resources could not be obtained.
- *
- * Caller considered to own/use the resources when the function returns.
- * Caller must release the resources using \a kds_rset_release.
- *
- * Calling this function while holding already locked resources or other locking primitives is dangerous.
- * One must if this is needed decide on a lock order of the resources and/or the other locking primitives
- * and always take the resources/locking primitives in the specific order.
- *
- * Use the ERR_PTR framework to decode the return value.
- * NULL = time out
- * If IS_ERR then PTR_ERR gives:
- * ERESTARTSYS = signal received, retry call after signal
- * all other values = internal error, lock failed
- * Other values = successful wait, now the owner, must call kds_resource_set_release
- */
- struct kds_resource_set *kds_waitall(
- int number_resources,
- unsigned long *exclusive_access_bitmap,
- struct kds_resource **resource_list,
- unsigned long jifies_timeout);
- /* Release resources after use.
- * Caller must handle that other async callbacks will trigger,
- * so must avoid holding any locks a callback will take.
- *
- * The function takes a pointer to your poiner to handle a race
- * between a cancelation and a completion.
- *
- * If the caller can't guarantee that a race can't occur then
- * the passed in pointer must be the same in both call paths
- * to allow kds to manage the potential race.
- */
- void kds_resource_set_release(struct kds_resource_set **pprset);
- /* Release resources after use and wait callbacks to complete.
- * Caller must handle that other async callbacks will trigger,
- * so must avoid holding any locks a callback will take.
- *
- * The function takes a pointer to your poiner to handle a race
- * between a cancelation and a completion.
- *
- * If the caller can't guarantee that a race can't occur then
- * the passed in pointer must be the same in both call paths
- * to allow kds to manage the potential race.
- *
- * This should be used to cancel waits which are pending on a kds
- * resource.
- *
- * It is a bug to call this from atomic contexts and from within
- * a kds callback that now owns the kds_rseource.
- */
- void kds_resource_set_release_sync(struct kds_resource_set **pprset);
- #endif /* _KDS_H_ */
|