static ktime_t sputrace_start;
static unsigned long sputrace_head, sputrace_tail;
static struct sputrace *sputrace_log;
+static int sputrace_logging;
static int sputrace_used(void)
{
char tbuf[128];
int width;
+ /* If we have data ready to return, don't block waiting
+ * for more */
+ if (cnt > 0 && sputrace_used() == 0)
+ break;
+
error = wait_event_interruptible(sputrace_wait,
sputrace_used() > 0);
if (error)
static int sputrace_open(struct inode *inode, struct file *file)
{
+ int rc;
+
spin_lock(&sputrace_lock);
+ if (sputrace_logging) {
+ rc = -EBUSY;
+ goto out;
+ }
+
+ sputrace_logging = 1;
sputrace_head = sputrace_tail = 0;
sputrace_start = ktime_get();
+ rc = 0;
+
+out:
spin_unlock(&sputrace_lock);
+ return rc;
+}
+static int sputrace_release(struct inode *inode, struct file *file)
+{
+ spin_lock(&sputrace_lock);
+ sputrace_logging = 0;
+ spin_unlock(&sputrace_lock);
return 0;
}
static const struct file_operations sputrace_fops = {
- .owner = THIS_MODULE,
- .open = sputrace_open,
- .read = sputrace_read,
+ .owner = THIS_MODULE,
+ .open = sputrace_open,
+ .read = sputrace_read,
+ .release = sputrace_release,
};
static void sputrace_log_item(const char *name, struct spu_context *ctx,
struct spu *spu)
{
spin_lock(&sputrace_lock);
+
+ if (!sputrace_logging) {
+ spin_unlock(&sputrace_lock);
+ return;
+ }
+
if (sputrace_avail() > 1) {
struct sputrace *t = sputrace_log + sputrace_head;
}
struct spu_probe spu_probes[] = {
- { "spu_bind_context__enter", "%p %p", spu_context_event },
- { "spu_unbind_context__enter", "%p %p", spu_context_event },
- { "spu_get_idle__enter", "%p", spu_context_nospu_event },
- { "spu_get_idle__found", "%p %p", spu_context_event },
- { "spu_get_idle__not_found", "%p", spu_context_nospu_event },
- { "spu_find_victim__enter", "%p", spu_context_nospu_event },
- { "spusched_tick__preempt", "%p %p", spu_context_event },
- { "spusched_tick__newslice", "%p", spu_context_nospu_event },
- { "spu_yield__enter", "%p", spu_context_nospu_event },
- { "spu_deactivate__enter", "%p", spu_context_nospu_event },
- { "__spu_deactivate__unload", "%p %p", spu_context_event },
- { "spufs_ps_nopfn__enter", "%p", spu_context_nospu_event },
- { "spufs_ps_nopfn__sleep", "%p", spu_context_nospu_event },
- { "spufs_ps_nopfn__wake", "%p %p", spu_context_event },
- { "spufs_ps_nopfn__insert", "%p %p", spu_context_event },
- { "spu_acquire_saved__enter", "%p", spu_context_nospu_event },
- { "destroy_spu_context__enter", "%p", spu_context_nospu_event },
- { "spufs_stop_callback__enter", "%p %p", spu_context_event },
+ { "spu_bind_context__enter", "ctx %p spu %p", spu_context_event },
+ { "spu_unbind_context__enter", "ctx %p spu %p", spu_context_event },
+ { "spu_get_idle__enter", "ctx %p", spu_context_nospu_event },
+ { "spu_get_idle__found", "ctx %p spu %p", spu_context_event },
+ { "spu_get_idle__not_found", "ctx %p", spu_context_nospu_event },
+ { "spu_find_victim__enter", "ctx %p", spu_context_nospu_event },
+ { "spusched_tick__preempt", "ctx %p spu %p", spu_context_event },
+ { "spusched_tick__newslice", "ctx %p", spu_context_nospu_event },
+ { "spu_yield__enter", "ctx %p", spu_context_nospu_event },
+ { "spu_deactivate__enter", "ctx %p", spu_context_nospu_event },
+ { "__spu_deactivate__unload", "ctx %p spu %p", spu_context_event },
+ { "spufs_ps_fault__enter", "ctx %p", spu_context_nospu_event },
+ { "spufs_ps_fault__sleep", "ctx %p", spu_context_nospu_event },
+ { "spufs_ps_fault__wake", "ctx %p spu %p", spu_context_event },
+ { "spufs_ps_fault__insert", "ctx %p spu %p", spu_context_event },
+ { "spu_acquire_saved__enter", "ctx %p", spu_context_nospu_event },
+ { "destroy_spu_context__enter", "ctx %p", spu_context_nospu_event },
+ { "spufs_stop_callback__enter", "ctx %p spu %p", spu_context_event },
};
static int __init sputrace_init(void)
struct proc_dir_entry *entry;
int i, error = -ENOMEM;
- sputrace_log = kcalloc(sizeof(struct sputrace),
- bufsize, GFP_KERNEL);
+ sputrace_log = kcalloc(bufsize, sizeof(struct sputrace), GFP_KERNEL);
if (!sputrace_log)
goto out;
- entry = create_proc_entry("sputrace", S_IRUSR, NULL);
+ entry = proc_create("sputrace", S_IRUSR, NULL, &sputrace_fops);
if (!entry)
goto out_free_log;
- entry->proc_fops = &sputrace_fops;
for (i = 0; i < ARRAY_SIZE(spu_probes); i++) {
struct spu_probe *p = &spu_probes[i];
remove_proc_entry("sputrace", NULL);
kfree(sputrace_log);
+ marker_synchronize_unregister();
}
module_init(sputrace_init);