개요

container_of(입력 주소, 구조체 A, 해당 구조체 멤버)
어떤 구조체(A)의 멤버가 입력 주소일 경우 해당하는 구조체의 주소를 가져온다. 

예를 들어서 linux/bpf/hashtab.c

static void *__htab_map_lookup_elem(struct bpf_map *map, void *key)
{
        struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
        struct hlist_nulls_head *head;
        struct htab_elem *l;
        u32 hash, key_size;

에서 container_of의 구조를 분석해 보면,
map이란 struct bpf_map의 주소값이다. 근데 bpf_htab이란 구조체는 내부 인자중 하나로 struct bpf_map map을 가진다. 이 경우, 우리는 bpf_map의 주소값만을 알지만, bpf_map의 주소값의 bpf_htab의 상대적인 위치를 알기 때문에 결국 bpf_htab의 위치를 알 수 있다.

container_of는 다음과 같은 구현을 가진다.

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

이에 따라서 offsetof로 인해서 구조체 에서의 상대적인 위치를 가져오고 그 결과를 __mptr즉 ptr의 위치에서 빼면서 원하는 구조체의 위치를 가져오게 되는 것이다.