summaryrefslogtreecommitdiff
path: root/lwis_fence.c
diff options
context:
space:
mode:
authorEdmond Chung <edmondchung@google.com>2023-02-15 12:42:20 -0800
committerEdmond Chung <edmondchung@google.com>2023-02-24 04:17:34 +0000
commitf2b68cdd6ab891d34ab2d1ee36551d5556275923 (patch)
tree888a11e3d47c37dd1119bb4f0daf210b53dd710b /lwis_fence.c
parent2bcaf2071dd8d8ae2f5456aa7b80ea697051423a (diff)
downloadlwis-f2b68cdd6ab891d34ab2d1ee36551d5556275923.tar.gz
Add precondition fence to event trigger logic
Commit-Topic: lwis-precond-fence Bug: 268208840 Test: CTS, GCA Change-Id: I525a07beb97a3704aee29cfc3d29aa24e9bea4b9 Signed-off-by: Edmond Chung <edmondchung@google.com>
Diffstat (limited to 'lwis_fence.c')
-rw-r--r--lwis_fence.c80
1 files changed, 63 insertions, 17 deletions
diff --git a/lwis_fence.c b/lwis_fence.c
index ee241f5..997c7bf 100644
--- a/lwis_fence.c
+++ b/lwis_fence.c
@@ -39,6 +39,16 @@ static const struct file_operations fence_file_ops = {
.poll = lwis_fence_poll,
};
+static int get_fence_status(struct lwis_fence *lwis_fence)
+{
+ int status;
+ unsigned long flags;
+ spin_lock_irqsave(&lwis_fence->lock, flags);
+ status = lwis_fence->status;
+ spin_unlock_irqrestore(&lwis_fence->lock, flags);
+ return status;
+}
+
/*
* lwis_fence_release: Closing an instance of a LWIS fence
*/
@@ -91,7 +101,6 @@ static int lwis_fence_release(struct inode *node, struct file *fp)
static ssize_t lwis_fence_get_status(struct file *fp, char __user *user_buffer, size_t len,
loff_t *offset)
{
- unsigned long flags;
int status = 0;
struct lwis_fence *lwis_fence = fp->private_data;
int max_len, read_len;
@@ -106,10 +115,7 @@ static ssize_t lwis_fence_get_status(struct file *fp, char __user *user_buffer,
len = max_len;
}
- spin_lock_irqsave(&lwis_fence->lock, flags);
- status = lwis_fence->status;
- spin_unlock_irqrestore(&lwis_fence->lock, flags);
-
+ status = get_fence_status(lwis_fence);
read_len = len - copy_to_user((void __user *)user_buffer, (void *)&status + *offset, len);
return read_len;
@@ -369,20 +375,60 @@ bool lwis_event_triggered_condition_ready(struct lwis_transaction *transaction,
size_t all_signaled;
struct lwis_transaction_info *info = &transaction->info;
int i;
+ struct lwis_fence *lwis_fence;
+ bool is_node_signaled = false;
operator_type = info->trigger_condition.operator_type;
all_signaled = info->trigger_condition.num_nodes;
+ /*
+ * Three scenarios to consider a node signaled:
+ * 1) Event ID and event counter match,
+ * 2) Event ID match, event counter not specified but precondition fence signaled, or,
+ * 3) Event ID match, event counter and precondition fence not specified.
+ */
for (i = 0; i < info->trigger_condition.num_nodes; i++) {
+ is_node_signaled = false;
if (info->trigger_condition.trigger_nodes[i].type == LWIS_TRIGGER_EVENT &&
- info->trigger_condition.trigger_nodes[i].event.id == event_id &&
- (info->trigger_condition.trigger_nodes[i].event.counter == event_counter ||
- info->trigger_condition.trigger_nodes[i].event.counter ==
- LWIS_EVENT_COUNTER_ON_NEXT_OCCURRENCE)) {
- transaction->signaled_count++;
- list_del(&weak_transaction->event_list_node);
- kfree(weak_transaction);
- break;
+ info->trigger_condition.trigger_nodes[i].event.id == event_id) {
+ if (info->trigger_condition.trigger_nodes[i].event.counter ==
+ event_counter ||
+ (info->trigger_condition.trigger_nodes[i].event.counter ==
+ LWIS_EVENT_COUNTER_ON_NEXT_OCCURRENCE &&
+ weak_transaction->precondition_fence_fp == NULL)) {
+ is_node_signaled = true;
+ } else if (info->trigger_condition.trigger_nodes[i].event.counter ==
+ LWIS_EVENT_COUNTER_ON_NEXT_OCCURRENCE) {
+ lwis_fence = weak_transaction->precondition_fence_fp->private_data;
+ if (lwis_fence != NULL && get_fence_status(lwis_fence) == 0) {
+ is_node_signaled = true;
+ if (lwis_fence_debug) {
+ pr_info("TransactionId %lld: event 0x%llx (%lld), precondition fence %d signaled",
+ info->id, event_id, event_counter,
+ info->trigger_condition.trigger_nodes[i]
+ .event.precondition_fence_fd);
+ }
+ } else {
+ if (lwis_fence_debug) {
+ pr_info("TransactionId %lld: event 0x%llx (%lld), precondition fence %d NOT signaled yet",
+ info->id, event_id, event_counter,
+ info->trigger_condition.trigger_nodes[i]
+ .event.precondition_fence_fd);
+ }
+ }
+ }
+
+ if (is_node_signaled) {
+ transaction->signaled_count++;
+ list_del(&weak_transaction->event_list_node);
+ if (weak_transaction->precondition_fence_fp) {
+ fput(weak_transaction->precondition_fence_fp);
+ }
+ kfree(weak_transaction);
+ /* The break here assumes that this event ID only appears once in
+ the trigger expression. Might need to revisit this. */
+ break;
+ }
}
}
@@ -403,8 +449,7 @@ bool lwis_event_triggered_condition_ready(struct lwis_transaction *transaction,
return false;
}
-bool lwis_fence_triggered_condition_ready(struct lwis_transaction *transaction,
- int fence_status)
+bool lwis_fence_triggered_condition_ready(struct lwis_transaction *transaction, int fence_status)
{
int32_t operator_type;
size_t all_signaled;
@@ -457,8 +502,9 @@ int lwis_parse_trigger_condition(struct lwis_client *client, struct lwis_transac
for (i = 0; i < info->trigger_condition.num_nodes; i++) {
if (info->trigger_condition.trigger_nodes[i].type == LWIS_TRIGGER_EVENT) {
ret = lwis_trigger_event_add_weak_transaction(
- client, info->id,
- info->trigger_condition.trigger_nodes[i].event.id);
+ client, info->id, info->trigger_condition.trigger_nodes[i].event.id,
+ info->trigger_condition.trigger_nodes[i]
+ .event.precondition_fence_fd);
} else {
ret = lwis_trigger_fence_add_transaction(
info->trigger_condition.trigger_nodes[i].fence_fd, client,