#include <linux/percpu.h>
#include <linux/ctype.h>
#include <linux/init.h>
+#include <linux/poll.h>
#include <linux/gfp.h>
#include <linux/fs.h>
static int max_tracer_type_len;
static DEFINE_MUTEX(trace_types_lock);
+static DECLARE_WAIT_QUEUE_HEAD (trace_wait);
#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct trace_entry))
TRACE_ITER_RAW = 0x10,
TRACE_ITER_HEX = 0x20,
TRACE_ITER_BIN = 0x40,
+ TRACE_ITER_BLOCK = 0x80,
};
#define TRACE_ITER_SYM_MASK \
"raw",
"hex",
"bin",
+ "block",
NULL
};
entry->fn.ip = ip;
entry->fn.parent_ip = parent_ip;
spin_unlock_irqrestore(&data->lock, irq_flags);
+
+ if (!(trace_flags & TRACE_ITER_BLOCK))
+ wake_up (&trace_wait);
}
notrace void
entry->special.arg2 = arg2;
entry->special.arg3 = arg3;
spin_unlock_irqrestore(&data->lock, irq_flags);
+
+ if (!(trace_flags & TRACE_ITER_BLOCK))
+ wake_up (&trace_wait);
}
notrace void
entry->ctx.next_pid = next->pid;
entry->ctx.next_prio = next->prio;
spin_unlock_irqrestore(&data->lock, irq_flags);
+
+ if (!(trace_flags & TRACE_ITER_BLOCK))
+ wake_up (&trace_wait);
}
#ifdef CONFIG_FTRACE
.read = tracing_readme_read,
};
-
static ssize_t
tracing_ctrl_read(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
return 0;
}
+static unsigned int
+tracing_poll_pipe(struct file *filp, poll_table *poll_table)
+{
+ struct trace_iterator *iter = filp->private_data;
+
+ if (trace_flags & TRACE_ITER_BLOCK) {
+ /*
+ * Always select as readable when in blocking mode
+ */
+ return POLLIN | POLLRDNORM;
+ }
+ else {
+ if (!trace_empty(iter))
+ return POLLIN | POLLRDNORM;
+ poll_wait(filp, &trace_wait, poll_table);
+ if (!trace_empty(iter))
+ return POLLIN | POLLRDNORM;
+
+ return 0;
+ }
+}
+
/*
* Consumer reader.
*/
start = 0;
while (trace_empty(iter)) {
+ if (!(trace_flags & TRACE_ITER_BLOCK))
+ return -EWOULDBLOCK;
/*
* This is a make-shift waitqueue. The reason we don't use
* an actual wait queue is because:
static struct file_operations tracing_pipe_fops = {
.open = tracing_open_pipe,
+ .poll = tracing_poll_pipe,
.read = tracing_read_pipe,
.release = tracing_release_pipe,
};