I am trying to use relayFS from an interrupt context. I read the documentation and downloaded and ran successfully the examples from http://relayfs.sourceforge.net. I am running on Fedora 6 machine with 2.6.18-1.2798.fc6 kernel (no patches). I have two years of experience in linux kernel programming. I am mounting successfully debugfs on /debug. According to relay.txt from the Linux documentation, relay_write() should be used if you might be logging from interrupt context. My module needs to write from interrupt context (in fact, it is a soft interrupt) so I tried using relay_write. My user space application try to read the relayFS files using read, not mmap, following the read-mod kernel module from the examples (which I tried successfully). What happens that when I try reading the relayFS files (by cat, which eventually uses read) which I generated from interrupt context in my module, I get nothing; while when trying files which are generated from a kernel thread with relay_write, I do succeed with reading these files using cat. I am attaching the code for the test module I wrote and I hope you can take a look at it; I simplified it and removed away everything which is not connected directly to my question. What happens is, in fact: when calling start_test_thread_new() we DO succeed to read the file with cat /debug/testTree/cpu0, whereas when using the second alternative, meaning calling directly test_thread_new() from the main_hook() (which runs in software interrupt context) we do not read anything (cat /debug/testTree/cpu0 shows nothing; there is,however, no segfault when running "cat /debug/testTree/cpu0" in that case). here below is test.c, a short module which I wrote demonstarting this problem. Any ideas? Regards, Rami Rosen // test.c #include <linux/version.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/kmod.h> #include <linux/slab.h> #include <asm/uaccess.h> #include <asm/system.h> #include <linux/compiler.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv4.h> #include <linux/byteorder/generic.h> #include <linux/inet.h> #include <linux/netdevice.h> #include <linux/netfilter_ipv4/ip_nat.h> #include <linux/spinlock.h> #include <net/ip.h> #include <linux/vmalloc.h> #include <linux/debugfs.h> #include <linux/relay.h> #include <linux/kthread.h> #define MAX_EVENT_SIZE 256 struct dentry *dir; struct rchan *channel; static struct completion done; static int hooksRegistered = 0; static struct task_struct *kthread_thread; static int test_thread_new(void *unused) { int i,count; char buf[MAX_EVENT_SIZE + 1]; for (i = 0; i < 10; i++) { count = snprintf(buf, MAX_EVENT_SIZE, "[%08i]test event\n", i); relay_write(channel, buf, count); } return 0; } static void start_test_thread_new(void) { int cpu = 0; struct task_struct *p; printk("in start_test_thread_new\n"); init_completion(&done); p = kthread_create(test_thread_new, NULL, "%s/%d", "test", cpu); if (IS_ERR(p)) return; if (p) { kthread_bind(p, cpu); wake_up_process(p); kthread_thread = p; } } static int test_subbuf_start_callback(struct rchan_buf *buf, void *subbuf, void *prev_subbuf, size_t prev_padding) { if (relay_buf_full(buf)) { printk("buffer full\n"); return 0; } return 1; } static int test_remove_buf_file_callback(struct dentry *dentry) { debugfs_remove(dentry); return 0; } static struct dentry *test_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 struct nf_hook_ops netfilter_ops_in; static int inithook(void); ////////////////////////////////////////////////////////////////////////////// unsigned int main_hook(unsigned int hooknum, struct sk_buff** skb, const struct net_device* in, const struct net_device* out, int (*okfn)(struct sk_buff*)) { static int counter=0; void *unused=NULL; counter++; printk("in main_hook counter=%d\n",counter); test_thread_new(unused); return NF_ACCEPT; } ////////////////////////////////////////////////////////////////////////////// static int inithook() { int i; printk("starting inithook\n"); netfilter_ops_in.hook = main_hook; netfilter_ops_in.pf = PF_INET; netfilter_ops_in.hooknum = NF_IP_PRE_ROUTING; netfilter_ops_in.priority = NF_IP_PRI_FIRST; nf_register_hook(&netfilter_ops_in); hooksRegistered = 1; printk(KERN_INFO "ioctl_init finished OK \n"); return 0; } ////////////////////////////////////////////////////////////////////////////// static int __init test_init(void) { int ret; int j; int res; printk("starting test_init \n"); { static struct rchan_callbacks blk_relay_callbacks = { .subbuf_start = test_subbuf_start_callback, .create_buf_file = test_create_buf_file_callback, .remove_buf_file = test_remove_buf_file_callback, }; dir = debugfs_create_dir("testTree",0); if (!dir) { printk("debugfs_create_dir failed!\n"); } else printk("debugfs_create_dir succeeded!\n"); channel=relay_open("cpu", dir, 262144, 4, &blk_relay_callbacks); if (!(channel)) { printk("relay_open() failed!\n"); return -1; } } res = inithook(); // start_test_thread_new(); if (res==-1) return -1; return 0; } ////////////////////////////////////////////////////////////////////////////// static void __exit test_exit(void) { if (hooksRegistered) nf_unregister_hook(&netfilter_ops_in); if (channel) relay_close(channel); if (dir) debugfs_remove(dir); printk("test_exit finished \n"); } ////////////////////////////////////////////////////////////////////////////// module_init(test_init) module_exit(test_exit) MODULE_AUTHOR("test"); MODULE_DESCRIPTION("test"); MODULE_LICENSE("GPL"); - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html