summaryrefslogtreecommitdiff
path: root/lwis_fence.h
blob: a79fc06cec2d4030fb3ed08ffdd2729a8d52bdd9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
 * 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 <linux/hashtable.h>
#include <linux/list.h>

#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_ */