/* Copyright (C) 2007 Arnaldo Carvalho de Melo This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include "ctracer_relay.h" static struct rchan *ctracer__rchan; static int ctracer__subbuf_start_callback(struct rchan_buf *buf, void *subbuf, void *prev_subbuf, size_t prev_padding) { static int warned; if (!relay_buf_full(buf)) return 1; if (!warned) { warned = 1; printk("relay_buf_full!\n"); } return 0; } static struct dentry *ctracer__create_buf_file_callback(const char *filename, struct dentry *parent, int mode, struct rchan_buf *buf, int *is_global) { return debugfs_create_file(filename, mode, parent, buf, &relay_file_operations); } static int ctracer__remove_buf_file_callback(struct dentry *dentry) { debugfs_remove(dentry); return 0; } static struct rchan_callbacks ctracer__relay_callbacks = { .subbuf_start = ctracer__subbuf_start_callback, .create_buf_file = ctracer__create_buf_file_callback, .remove_buf_file = ctracer__remove_buf_file_callback, }; extern void ctracer__class_state(const void *from, void *to); void ctracer__method_hook(const unsigned long long now, const int probe_type, const unsigned long long function_id, const void *object, const int state_len) { if (object != NULL) { void *t = relay_reserve(ctracer__rchan, sizeof(struct trace_entry) + state_len); if (t != NULL) { struct trace_entry *entry = t; entry->nsec = now; entry->probe_type = probe_type; entry->object = object; entry->function_id = function_id; ctracer__class_state(object, t + sizeof(*entry)); } } } EXPORT_SYMBOL_GPL(ctracer__method_hook); static int __init ctracer__relay_init(void) { ctracer__rchan = relay_open("ctracer", NULL, 512 * 1024, 64, &ctracer__relay_callbacks, NULL); if (ctracer__rchan == NULL) { pr_info("ctracer: couldn't create the relay\n"); return -1; } return 0; } module_init(ctracer__relay_init); static void __exit ctracer__relay_exit(void) { relay_close(ctracer__rchan); } module_exit(ctracer__relay_exit); MODULE_LICENSE("GPL");