How to Use container_of in Linux Kernel Development
In this post, I will explain the usage of linux's container_of macro with a sample code.
If you know address of a data structure's field, you can get the address of the instance of that data structure by using the container_of macro. This is the simplest explanation of this macro.
Let's say you have a function called with a pointer parameter and you know that the pointer is pointing an address of a data structure field.
If you want to access the other field "a" in the function, you need to use container_of macro.
Let's see the below sample code and it's output to understand it easily.
If you know address of a data structure's field, you can get the address of the instance of that data structure by using the container_of macro. This is the simplest explanation of this macro.
Let's say you have a function called with a pointer parameter and you know that the pointer is pointing an address of a data structure field.
struct my_object { int a; int b;
} obj; function(&obj->b);
If you want to access the other field "a" in the function, you need to use container_of macro.
Let's see the below sample code and it's output to understand it easily.
/* * my_object structure. */ struct my_object { int a; int b; int c; }; /* * container_test() * Test function for usage of container_of macro. * * This function is passed a pointer which points a field of * an allocated my_object instance and prints the address of the * object and its other fields. */ static void container_test(int *val) { struct my_object *obj; obj = container_of(val, struct my_object, b); printk(KERN_INFO "obj obtained by container_of macro using &obj->b\n"); printk(KERN_INFO "obj: %p obj->a: %d obj->b: %d obj->c: %d\n", obj, obj->a, obj->b, obj->c); } /* * container_init() */ static int container_init(void) { struct my_object *obj; printk(KERN_INFO "container init\n"); /* * Allocate an instance of my_object. */ obj = kmalloc(sizeof(struct my_object), GFP_KERNEL); if (!obj) { printk(KERN_WARNING "unable to allocate memory\n"); return -1; } /* * Initialize the fields of the object. */ obj->a = 5; obj->b = 15; obj->c = 25; printk(KERN_INFO "Allocated and initialized object\n"); printk(KERN_INFO "obj: %p obj->a: %d obj->b: %d obj->c: %d\n", obj, obj->a, obj->b, obj->c); /* * Call the test function with the address of the field b. */ container_test(&obj->b); kfree(obj); return 0; }
OUTPUT:
Allocated and initialized object
obj: b5a07100 obj->a: 5 obj->b: 15 obj->c: 25
obj obtained by container_of macro using &obj->b
obj: b5a07100 obj->a: 5 obj->b: 15 obj->c: 25
Source Code Download:
Comments