2 * Copyright (C) ARM Limited 2010-2015. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
10 #include <linux/slab.h>
13 #include <linux/sched.h>
14 #include <linux/uaccess.h>
15 #include <asm/current.h>
16 #include <linux/spinlock.h>
18 static DEFINE_SPINLOCK(annotate_lock);
19 static bool collect_annotations;
21 static int annotate_copy(struct file *file, char const __user *buf, size_t count)
24 int write = per_cpu(gator_buffer_write, cpu)[ANNOTATE_BUF];
27 /* copy from kernel */
28 memcpy(&per_cpu(gator_buffer, cpu)[ANNOTATE_BUF][write], buf, count);
30 /* copy from user space */
31 if (copy_from_user(&per_cpu(gator_buffer, cpu)[ANNOTATE_BUF][write], buf, count) != 0)
34 per_cpu(gator_buffer_write, cpu)[ANNOTATE_BUF] = (write + count) & gator_buffer_mask[ANNOTATE_BUF];
39 static ssize_t annotate_write(struct file *file, char const __user *buf, size_t count_orig, loff_t *offset)
41 int pid, cpu, header_size, available, contiguous, length1, length2, size, count = count_orig & 0x7fffffff;
42 bool interrupt_context;
47 interrupt_context = in_interrupt();
48 /* Annotations are not supported in interrupt context, but may work
49 * if you comment out the the next four lines of code. By doing so,
50 * annotations in interrupt context can result in deadlocks and lost
53 if (interrupt_context) {
54 pr_warning("gator: Annotations are not supported in interrupt context. Edit gator_annotate.c in the gator driver to enable annotations in interrupt context.\n");
59 /* synchronize between cores and with collect_annotations */
60 spin_lock(&annotate_lock);
62 if (!collect_annotations) {
63 /* Not collecting annotations, tell the caller everything was written */
65 goto annotate_write_out;
68 /* Annotation only uses a single per-cpu buffer as the data must be in order to the engine */
76 /* determine total size of the payload */
77 header_size = MAXSIZE_PACK32 * 3 + MAXSIZE_PACK64;
78 available = buffer_bytes_available(cpu, ANNOTATE_BUF) - header_size;
79 size = count < available ? count : available;
82 /* Buffer is full, wait until space is available */
83 spin_unlock(&annotate_lock);
85 /* Drop the annotation as blocking is not allowed in interrupt context */
86 if (interrupt_context)
89 wait_event_interruptible(gator_annotate_wait, buffer_bytes_available(cpu, ANNOTATE_BUF) > header_size || !collect_annotations);
91 /* Check to see if a signal is pending */
92 if (signal_pending(current))
98 /* synchronize shared variables annotateBuf and annotatePos */
99 if (per_cpu(gator_buffer, cpu)[ANNOTATE_BUF]) {
100 u64 time = gator_get_time();
102 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, get_physical_cpu());
103 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid);
104 gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, time);
105 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, size);
107 /* determine the sizes to capture, length1 + length2 will equal size */
108 contiguous = contiguous_space_available(cpu, ANNOTATE_BUF);
109 if (size < contiguous) {
113 length1 = contiguous;
114 length2 = size - contiguous;
117 if (annotate_copy(file, buf, length1) != 0) {
119 goto annotate_write_out;
122 if (length2 > 0 && annotate_copy(file, &buf[length1], length2) != 0) {
124 goto annotate_write_out;
127 /* Check and commit; commit is set to occur once buffer is 3/4 full */
128 buffer_check(cpu, ANNOTATE_BUF, time);
132 spin_unlock(&annotate_lock);
134 /* return the number of bytes written */
138 #include "gator_annotate_kernel.c"
140 static int annotate_release(struct inode *inode, struct file *file)
144 /* synchronize between cores */
145 spin_lock(&annotate_lock);
147 if (per_cpu(gator_buffer, cpu)[ANNOTATE_BUF] && buffer_check_space(cpu, ANNOTATE_BUF, MAXSIZE_PACK64 + 3 * MAXSIZE_PACK32)) {
148 uint32_t pid = current->pid;
150 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, get_physical_cpu());
151 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, pid);
153 gator_buffer_write_packed_int64(cpu, ANNOTATE_BUF, 0);
155 gator_buffer_write_packed_int(cpu, ANNOTATE_BUF, 0);
158 /* Check and commit; commit is set to occur once buffer is 3/4 full */
159 buffer_check(cpu, ANNOTATE_BUF, gator_get_time());
161 spin_unlock(&annotate_lock);
166 static const struct file_operations annotate_fops = {
167 .write = annotate_write,
168 .release = annotate_release
171 static int gator_annotate_create_files(struct super_block *sb, struct dentry *root)
173 return gatorfs_create_file_perm(sb, root, "annotate", &annotate_fops, 0666);
176 static int gator_annotate_start(void)
178 collect_annotations = true;
182 static void gator_annotate_stop(void)
184 /* the spinlock here will ensure that when this function exits, we are not in the middle of an annotation */
185 spin_lock(&annotate_lock);
186 collect_annotations = false;
187 wake_up(&gator_annotate_wait);
188 spin_unlock(&annotate_lock);