container_of 例子
#include<stdio.h> #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of(ptr, type, member) ({ \ const typeof(((type *)0)->member)*__mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type, member)); }) struct Test{ char i; int j; char k; }; void main() { struct Test test; test.i=7; test.j=10; test.k=12; char *p=&(test.k);//假设只知道test.k的地址 struct Test *q=container_of(p,struct Test,k); printf("q->j=%d\n",q->j); }运算结果
q->j=10
这下记忆就深刻了。
Documentation/kref.txt 有很好说明,当没有引用的时候就free.
obj-m := test.o KERNEL := /lib/modules/`uname -r`/build all: make -C $(KERNEL) M=`pwd` modules install: make -C $(KERNEL) M=`pwd` modules_install depmod -A clean: make -C $(KERNEL) M=`pwd` clean rm -f Module.*
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/kthread.h> struct my_data{ struct kref refcount; }; void data_release(struct kref *ref) { struct my_data *data = container_of(ref, struct my_data, refcount); printk(KERN_INFO "free my data\n"); kfree(data); } int more_data_handling(void *cb_data) { struct my_data *data = cb_data; printk(KERN_INFO "more_data_handling.\n"); kref_put(&data->refcount, data_release); return 0; } int my_data_handler(void) { int rv = 0; struct my_data *data; struct task_struct *task; data = kmalloc(sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; kref_init(&data->refcount); kref_get(&data->refcount); task = kthread_run(more_data_handling, data, "more_data_handling"); if (task == ERR_PTR(-ENOMEM)) { rv = -ENOMEM; goto out; } out: kref_put(&data->refcount, data_release); return rv; } int __init tst_start(void) { int ret; printk(KERN_INFO "START\n"); ret = my_data_handler(); return 0; } static void __exit tst_end(void) { printk(KERN_INFO "From tst module: Goodbye, Tony.\n"); } module_init(tst_start); module_exit(tst_end); MODULE_LICENSE("GPL"); MODULE_AUTHOR("xiayu");