Understanding container_of macro of Linux Kernel
container_of macro is the macro you see almost in most of driver code. Search of "container_of" macro in drivers folder of Linux Source code gave more than 10 k results.
What is the use of container_of macro?
Given a structure having many members. The container_of macro will give the address of the structure when you pass the address of one of the member variable of that structure.
Definition:
container_of macro is defined in linux/kernel.h.
({ void *__mptr = (void *)(ptr);
((type *)(__mptr - offsetof(type, member))); })
To understand these two lines of the macro, we need to get familiar with the following concepts.
What is the use of container_of macro?
Given a structure having many members. The container_of macro will give the address of the structure when you pass the address of one of the member variable of that structure.
Definition:
container_of macro is defined in linux/kernel.h.
({ void *__mptr = (void *)(ptr);
((type *)(__mptr - offsetof(type, member))); })
To understand these two lines of the macro, we need to get familiar with the following concepts.
- typeof()
- offsetof()
- Compound Statements
1. typeof(): It is a very useful operator helpful to find out the type of the argument at run time. Using typeof we can write a simple macro which can work for multiple types. For example the swap function defined in kernel.h
2. offsetof(type, member): The offsetof() returns the offset of the field member from the start of structure type
This is useful as the size of the members of the structure can differ across different architectures (x86, x86_64) and sometimes compiler also adds some padding for performance.
3. Compound Statements:
Compound statements is a sequence of statements surrounded by braces. Parentheses also go around these braces.
The last line in the compound statement should be an expression followed by a semicolon. The value of the expression serves as the value of the compound statement.
container_of is also a compound statement, the value of ((type *)(__mptr - offsetof(type, member))); will be the return value of macro.
Sample C code to understand container_of macro:
We declare a pointer of the member and then subtract the offset of the member variable to get the structure address.
You can see container_of returns the address of "t1" in the above example.
Comments
Post a Comment