Understanding container_of macro in the Linux kernel
NickName:jaeyong Ask DateTime:2013-04-05T19:06:33

Understanding container_of macro in the Linux kernel

When I was browsing the Linux kernel, I found a container_of macro which is defined as follows:

#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})

I understand what does container_of do, but what I do not understand is the last sentence, which is

(type *)( (char *)__mptr - offsetof(type,member) );})

If we use the macro as follows:

container_of(dev, struct wifi_device, dev);

The corresponding part of the last sentence would be:

(struct wifi_device *)( (char *)__mptr - offset(struct wifi_device, dev);

which looks like doing nothing. Could anybody please fill the void here?

Copyright Notice:Content Author:「jaeyong」,Reproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/15832301/understanding-container-of-macro-in-the-linux-kernel

Answers
mikyra 2013-04-05T11:21:15

Your usage example container_of(dev, struct wifi_device, dev); might be a bit misleading as you are mixing two namespaces there.\n\nWhile the first dev in your example refers to the name of pointer the second dev refers to the name of a structure member.\n\nMost probably this mix up is provoking all that headache. In fact the member parameter in your quote refers to the name given to that member in the container structure.\n\nTaking this container for example:\n\nstruct container {\n int some_other_data;\n int this_data;\n}\n\n\nAnd a pointer int *my_ptr to the this_data member you'd use the macro to get a pointer to struct container *my_container by using:\n\nstruct container *my_container;\nmy_container = container_of(my_ptr, struct container, this_data);\n\n\nTaking the offset of this_data to the beginning of the struct into account is essential to getting the correct pointer location.\n\nEffectively you just have to subtract the offset of the member this_data from your pointer my_ptr to get the correct location.\n\nThat's exactly what the last line of the macro does.",


Federico 2013-04-05T11:18:50

The last sentence cast:\n\n(type *)(...)\n\n\na pointer to a given type. The pointer is calculated as offset from a given pointer dev:\n\n( (char *)__mptr - offsetof(type,member) )\n\n\nWhen you use the cointainer_of macro, you want to retrieve the structure that contains the pointer of a given field. For example:\n\nstruct numbers {\n int one;\n int two;\n int three;\n} n;\n\nint *ptr = &n.two;\nstruct numbers *n_ptr;\nn_ptr = container_of(ptr, struct numbers, two);\n\n\nYou have a pointer that points in the middle of a structure (and you know that is a pointer to the filed two [the field name in the structure]), but you want to retrieve the entire structure (numbers). So, you calculate the offset of the filed two in the structure:\n\noffsetof(type,member)\n\n\nand subtract this offset from the given pointer. The result is the pointer to the start of the structure. Finally, you cast this pointer to the structure type to have a valid variable.",


Spyder 2019-01-21T11:06:22

conatainer_of() macro in Linux Kernel -\n\nWhen it comes to managing several data structures in code, you'll almost always need to embed one structure into another and retrieve them at any moment without being asked questions about memory offsets or boundaries. Let's say you have a struct person, as defined here:\n\n struct person { \n int age; \n int salary;\n char *name; \n } p;\n\n\nBy only having a pointer on age or salary, you can retrieve the whole structure wrapping (containing) that pointer. As the name says, the container_of macro is used to find the container of the given field of a structure. The macro is defined in include/linux/kernel.h and looks like the following:\n\n#define container_of(ptr, type, member) ({ \\ \n const typeof(((type *)0)->member) * __mptr = (ptr); \\ \n (type *)((char *)__mptr - offsetof(type, member)); })\n\n\nDon't be afraid of the pointers; just see them as follows:\n\ncontainer_of(pointer, container_type, container_field); \n\n\nHere are the elements of the preceding code fragment:\n\n\npointer: This is the pointer to the field in the structure\ncontainer_type: This is the type of structure wrapping (containing) the pointer\ncontainer_field: This is the name of the field to which\npointer points inside the structure\n\n\nLet's consider the following container:\n\nstruct person { \n int age; \n int salary; \n char *name; \n}; \n\n\nNow, let's consider one of its instances, along with a pointer to the age member:\n\nstruct person somebody; \n[...] \nint *age_ptr = &somebody.age; \n\n\nAlong with a pointer to the name member (age_ptr),you can use the container_of macro in order to get a pointer to the whole structure (container) that wraps this member by using the following:\n\nstruct person *the_person; \nthe_person = container_of(age_ptr, struct person, age); \n\n\ncontainer_of takes the offset of age at the beginning of the struct into account to get the correct pointer location. If you subtract the offset of the field age from the pointer age_ptr, you will get the correct location. This is what the macro's last line does:\n\n(type *)( (char *)__mptr - offsetof(type,member) ); \n\n\nApplying this to a real example, gives the following:\n\nstruct family { \n struct person *father; \n struct person *mother; \n int number_of_sons; \n int family_id; \n} f; \n\n/* \n * Fill and initialise f somewhere */ [...]\n\n /* \n * pointer to a field of the structure \n * (could be any (non-pointer) member in the structure) \n */ \n int *fam_id_ptr = &f.family_id; \n struct family *fam_ptr; \n\n /* now let us retrieve back its family */ \n fam_ptr = container_of(fam_id_ptr, struct family, family_id); \n\n\nThe container_of macro is mainly used in generic containers in the kernel.\n\nThat's all about container_of macro in kernel.",


shodanex 2013-04-05T11:31:08

It is an utilisation of a gcc extension, the statements expressions. If you see the macro as something returning a value, then the last line would be :\n\nreturn (struct wifi_device *)( (char *)__mptr - offset(struct wifi_device, dev);\n\n\nSee the linked page for an explanation of compound statements. Here is an example :\n\nint main(int argc, char**argv)\n{\n int b;\n b = 5;\n b = ({int a; \n a = b*b; \n a;});\n printf(\"b %d\\n\", b); \n}\n\n\nThe output is\n\n\n b 25\n",


Anand 2019-05-14T13:18:00

Very useful link for understanding container_of macro in linux kernel.\nhttps://linux-concepts.blogspot.com/2018/01/understanding-containerof-macro-in.html",


qeatzy 2017-08-28T16:32:40

A little real context says clearer, below use red-black tree as example, which is the\nway that I understand container_of.\n\nas Documentation/rbtree.txt states, in linux kernel code, it's not rb_node contain data\nentry, rather \n\n\n Data nodes in an rbtree tree are structures containing a struct\n rb_node member.\n\n\nstruct vm_area_struct (in file include/linux/mm_types.h:284) is such a structure,\n\nin the same\nfile, there is a macro rb_entry which is defined as\n\n#define rb_entry(ptr, type, member) container_of(ptr, type, member)\n\n\nclearly, rb_entry is same as container_of.\n\nat mm/mmap.c:299 inside function definition browse_rb, there is a usage of rb_entry:\n\nstatic int browse_rb(struct mm_struct *mm)\n{\n /* two line code not matter */\n struct rb_node *nd, *pn = NULL; /*nd, first arg, i.e. ptr. */\n unsigned long prev = 0, pend = 0;\n\n for (nd = rb_first(root); nd; nd = rb_next(nd)) {\n struct vm_area_struct *vma;\n vma = rb_entry(nd, struct vm_area_struct, vm_rb); \n /* -- usage of rb_entry (equivalent to container_of) */\n /* more code not matter here */\n\n\nnow it is clear, in container_of(ptr, type, member),\n\n\ntype is the container struct, here struct vm_area_struct\nmember is name of a member of type instance, here vm_rb, which is of type rb_node,\nptr is a pointer pointing member of an type instance, here rb_node *nd.\n\n\nwhat container_of do is, as in this example, \n\n\ngiven address of obj.member (here obj.vm_rb), return the\naddress of obj. \nsince a struct is a block of contiguous memory, address of obj.vm_rb minus\noffset between the struct and member will be the container's address.\n\n\ninclude/linux/kernel.h:858 -- definition of container_of\n\ninclude/linux/rbtree.h:51 -- definition of rb_entry\n\nmm/mmap.c:299 -- usage of rb_entry\n\ninclude/linux/mm_types.h:284 -- struct vm_area_struct\n\nDocumentation/rbtree.txt: -- Documentation of red-black tree\n\ninclude/linux/rbtree.h:36 -- definition of struct rb_node\n\nP.S.\n\nAbove files are in current develop version, i.e, 4.13.0-rc7.\n\nfile:k mean kth line in file.",


More about “Understanding container_of macro in the Linux kernel” related questions

Understanding container_of macro in the Linux kernel

When I was browsing the Linux kernel, I found a container_of macro which is defined as follows: #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)-...

Show Detail

Understanding container_of macro in the Linux kernel

When I was browsing the Linux kernel, I found a container_of macro which is defined as follows: #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)-...

Show Detail

Understanding container_of macro in the Linux kernel

When I was browsing the Linux kernel, I found a container_of macro which is defined as follows: #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)-...

Show Detail

Replacing the container_of macro used in linux kernel

On trying to understand the functionality of container_of() from the source code linux kernel Definition of container_of, I found out that the below line in the definition of the macro looks like d...

Show Detail

use of macro container_of with struct member

I am trying to understand some proprietary code in which container_of is called with single parameter which is a member struct of the return struct. struct want{ . . struct member_used; }; member_...

Show Detail

The Linux Kernel container_of macro and generic containers in C90

Is it possible to implement the container_of macro in pure C90? I'm not sure how to do it as the Kernel implementation depends on GCC Hacks such as the typeof operator. I'm asking because I would...

Show Detail

Unexpected result when using container_of macro (Linux kernel)

I have a problem with using of container_of macro in the Linux kernel. I have the following code #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member) *__mptr ...

Show Detail

Rationale behind the container_of macro in linux/list.h

In the implementation of linux kernel lists in /include/linux/list.h, what is the rationale behind the first line (pasted below) of the container_of macro? const typeof( ((type *)0)->member ) *...

Show Detail

Rationale behind the container_of macro in linux/list.h

In the implementation of linux kernel lists in /include/linux/list.h, what is the rationale behind the first line (pasted below) of the container_of macro? const typeof( ((type *)0)->member ) *...

Show Detail

linux kernel socket source macro container_of

i was trying to understand how created is socket but i have ran into the problem which i really dont understand. This problem is the code below: static inline struct socket *SOCKET_I(struct inode *

Show Detail