Linux Kernel Linked List
參考:https://hackmd.io/@sysprog/linux2025-lab0/%2F%40sysprog%2Flinux2025-lab0-a
Linux kernel 的 list_head(定義於 include/linux/list.h)是一個 intrusive、doubly、circular 的鏈結串列。
struct list_head {
struct list_head *next, *prev;
};
特色
- Intrusive(侵入式):
list_head內嵌在使用者自己的 struct 裡,而非串列存資料指標。同一結構可同時掛在多個串列。 - Circular(環狀):head 的
prev指向尾節點、尾節點next指回 head,插入刪除不需特判 NULL。 - 空串列:
head->next == head->prev == head。
container_of
由成員指標回推整個外層 struct 的起始位址,是 intrusive list 取回資料的關鍵:
#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))
#define list_entry(ptr, type, member) container_of(ptr, type, member)
常用巨集
LIST_HEAD(name):宣告並初始化一個串列 head。list_add(new, head)/list_add_tail(new, head):頭部 / 尾部插入。list_del(entry):刪除節點(O(1))。list_for_each(pos, head):走訪每個list_head節點。list_for_each_entry(pos, head, member):直接走訪外層 struct,內部用list_entry取回。
走訪中若要刪除節點,需用
list_for_each_safe/list_for_each_entry_safe,先暫存 next 避免存取已釋放記憶體。