/* * Google LWIS Fence * * Copyright (c) 2022 Google, LLC * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifndef LWIS_FENCE_H_ #define LWIS_FENCE_H_ #include #include #include "lwis_device.h" #define LWIS_CLIENTS_HASH_BITS 8 extern bool lwis_fence_debug; struct lwis_fence { int fd; int status; spinlock_t lock; /* Top device for printing logs */ struct lwis_device *lwis_top_dev; /* Status wait queue for waking up userspace */ wait_queue_head_t status_wait_queue; /* Hash table of transactions that's triggered by this fence */ DECLARE_HASHTABLE(transaction_list, LWIS_CLIENTS_HASH_BITS); }; struct lwis_fence_trigger_transaction_list { struct lwis_client *owner; struct list_head list; struct hlist_node node; }; struct lwis_fence_pending_signal { struct file *fp; struct lwis_fence *fence; int pending_status; struct list_head node; }; /* * lwis_fence_create: Create a new lwis_fence. */ int lwis_fence_create(struct lwis_device *lwis_dev); int ioctl_lwis_fence_create(struct lwis_device *lwis_dev, int32_t __user *msg); /* * lwis_fence_get: Get the lwis_fence associated with the fd. */ struct lwis_device *lwis_fence_get(int fd); /* Creates all fences that do not currently exist */ int lwis_initialize_transaction_fences(struct lwis_client *client, struct lwis_transaction *transaction); bool lwis_triggered_by_condition(struct lwis_transaction *transaction); bool lwis_event_triggered_condition_ready(struct lwis_transaction *transaction, struct lwis_transaction *weak_transaction, int64_t event_id, int64_t event_counter); bool lwis_fence_triggered_condition_ready(struct lwis_transaction *transaction, int fence_status); /* * lwis_parse_trigger_condition: Add the transaction to the associated trigger * fence and event lists. */ int lwis_parse_trigger_condition(struct lwis_client *client, struct lwis_transaction *transaction); /* * lwis_fence_signal: Signals the lwis_fence with the provided error code. */ int lwis_fence_signal(struct lwis_fence *lwis_fence, int status); /* * lwis_add_completion_fence: Adds the fence with the given fd as a completion fence to this transaction. */ int lwis_add_completion_fence(struct lwis_client *client, struct lwis_transaction *transaction); /* lwis_fence_pending_signal_create: Creates and returns a lwis_fence_pending_signal list entry */ struct lwis_fence_pending_signal *lwis_fence_pending_signal_create(struct lwis_fence *fence, struct file *fp); /* * lwis_fences_pending_signal_emit: Signal all lwis_fence_pending_signals in the pending_fences list */ void lwis_fences_pending_signal_emit(struct lwis_device *lwis_device, struct list_head *pending_fences); /* * lwis_pending_fences_move_all: Move all lwis_fence_pending_signal from the transaction to pending_fences. */ void lwis_pending_fences_move_all(struct lwis_device *lwis_device, struct lwis_transaction *transaction, struct list_head *pending_fences, int error_code); #endif /* LWIS_IOCTL_H_ */