kernel crash for spinlock concurrency in linux-kernel - c

I want to clear a list which type is defined by Kernel. I have two main structs, num_wrapper and num. num_wapper has a list of num, and kernel crashs when I do the del_all_node() function.
I try to mark the list_del, and the kernel will not be crash. I don't understand why there will be crash problem since I have use spin_lock to protect this num_list.
Any tips will be appreciate.
The following is the simplified code.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/slab.h>
struct num_wrapper {
struct list_head num_list;
spinlock_t list_lock;
u8 check_num;
};
struct num {
struct list_head node;
int number;
struct num_wrapper* num_w_ptr;
};
s32 del_all_node(struct num_wrapper *number_wrap)
{
struct num *tmp;
struct num *num_head;
spin_lock(&number_wrap->list_lock);
list_for_each_entry_safe(num_head, tmp, &number_wrap->num_list, node) {
printk("num_head is %d\n", num_head->number);
list_del(&num_head->node);//this line seems to have problem
}
spin_unlock(&number_wrap->list_lock);
return 0;
}
static int __init hello_init(void)
{
/*Setup Scenario*/
struct num_wrapper *number_wrap = kzalloc(sizeof(struct num_wrapper)
, GFP_KERNEL);
struct num *number = kzalloc(sizeof(struct num), GFP_KERNEL);
number->number = 10;
number_wrap->check_num = 20;
INIT_LIST_HEAD(&number->node);
INIT_LIST_HEAD(&number_wrap->num_list);
list_add_tail(&number->node, &number_wrap->num_list);
del_all_node(number_wrap);
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Good, haha\n");
}
module_init(hello_init);
module_exit(hello_exit);
update
After doing some debug, I seems to find root cause...
my scenario is as follows :
I have a private data struct which is included in the net_device struct.
And the following is the simplified scenario:
struct xx_if *xx_if; //this is private data in net_device
struct xx_if *tmp;
list_for_each_entry_safe(xx_if, tmp, xx_if_wrap->if_list, list) {
free_netdev(xx_if->ndev);
list_del(&xx_if->list);
}
Since free_netdev will also free the private data xx_if, the code broken...
My fix is change the sequence to these two statements, and it fix the crash problem.
Still strange thing is I have check whether xx_if is NULL, but still lead to crash if I don't interchange these two statements.

I don't clearly understand following code:
INIT_LIST_HEAD(&number->node);
INIT_LIST_HEAD(&number_wrap->num_list);
list_add_tail(&number->node, &number_wrap->num_list);
You init two different structures, then you add one type of list to another type of list.
Is that the way you can do?
I think, that you need something like this:
struct num{
u8 check_num;
struct list_head list;
};
struct num_wrapper{
struct num* num_ptr;
spinlock_t list_lock;
};
int init_num_wrapper(struct num_wrapper** prt){
if(!ptr && *ptr){
return -EINVAL;
}
*ptr = kzalloc(sizeof(struct num_wrapper), GFP_KERNEL);
if(!*ptr){
return -ENOMEM;
}
INIT_LIST_HEAD(& (*ptr)->num_ptr->list);
... init spinlock
return 0;
}
int add_num(num_wrapper* prt_wrap, u8 check_num){
... checking pointers
struct num num* = NULL;
num = kmalloc(sizeof(struct num), GFP_KERNEL);
if(! num){
return -ENOMEM;
}
INIT_LIST_HEAD(&num->list);
num->check_num = check_num;
spin_lock(&prt_wrap->list_lock);
list_add_tail(&num->list, &prt_wrap->num_ptr.list);
spin_unlock(&prt_wrap->list_lock);
return 0;
}
int remove_all_nodes(num_wrapper* prt_wrap){
... checking pointer
struct num *tmp = NULL;
struct num *num_head = NULL;
spin_lock(&number_wrap->list_lock);
list_for_each_entry_safe(num_head, tmp, &prt_wrap->list, list)
{
printk("num_head is %d\n", num_head->number);
list_del(&num_head->node);//this line seems to have problem
}
spin_unlock(&num_wrapper->list_lock);
return 0;
}
Update
Then, you can use above functions for manipulating of num_wrapper.
For example:
//...
struct num_wrapper* nums = NULL;
init_num_wrapper(&nums); // after this call, you will have inited nums var, which can be used with others functions for manipulating with num_wrapper list.
u8 num = 2;
add_num(nums, num); // after this call new node with num will be added to num_wrapper
//...

Related

Linux Kernel List, Freeing memory

I am currently learning some Linux Driver writing, and i try to implement list with the Linux Kernel list API.
My code just allocate a list and add 2 elements to it.
All go Ok until i try to free the memory i allocate, here i got a segmentation fault, and from what i test, it come from list_del call.
But i cannot see where i did wrong.
Here is my code :
struct drv_cdev{
int devno;
};
struct drv_dev_itf {
struct drv_cdev cdev; //DATA
struct list_head cdev_list;
};
struct drv_dev {
int number;
struct list_head list_master;
struct drv_dev_itf drv_dev_itf;
};
void add_node(struct drv_dev *dev, int num)
{
struct drv_dev_itf *new_cdev;
new_cdev = kmalloc(sizeof(struct drv_dev_itf*), GFP_KERNEL);
new_cdev->cdev.devno = num;
INIT_LIST_HEAD(&new_cdev->cdev_list);
list_add(&new_cdev->cdev_list, &dev->list_master);
}
void destroy_list(struct drv_dev *dev)
{
struct list_head *position;
struct drv_dev_itf *data_structure;
list_for_each (position, &dev->list_master) {
data_structure = list_entry(position, struct drv_dev_itf, cdev_list);
printk("Devno testing : %d\n", data_structure->cdev.devno);
//dev_node_release(driver_class, &data_structure->cdev);
list_del(position);
printk("List head deleted\n");
/*kfree(data_structure);
printk("List data_structure deleted\n");*/
}
}
static int __init test_init(void)
{
struct drv_dev *dev;
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
INIT_LIST_HEAD(&dev->list_master);
add_node(dev, 1);
add_node(dev, 2);
destroy_list(dev);
kfree(dev);
return 0;
}
Thanks in advance for your answers, have a nice day.

Linux kernel linked lists - and sorting

I'm implementing some system calls which are mainly supposed to maintain a list of processes, and a list of open files with each process. However I'm having a hard time debugging the code, which requires recompiling over and over again.
Here are probably my main problems:
When and how can I initialize the list keeping the processes? Currently I'm checking if the list is empty before initializing but it doesn't work. I also tried head == head->prev->next but failed.
What's the correct way to call the list_sort considering the related 'compare' function? I'm getting the error
[ 1827.710802] BUG: unable to handle kernel paging request at fffff550
[ 1827.710808] IP: [] compare+0x8/0x20
[ 1827.710814] *pde = 00a32067 *pte = 00000000
This is the code. I'd really appreciate you reviewing it, especially the init system call whose correct behavior the others rely on.
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/list.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/fdtable.h>
#include <linux/list_sort.h>
#include <linux/slab.h>
struct fileDescriptor {
int fd;
struct list_head list;
};
struct processInfo {
struct task_struct task;
int len_files;
struct fileDescriptor listHead;
struct list_head list;
};
struct processInfo listHead;
int compare(void* priv, struct list_head *a, struct list_head *b)
{
struct processInfo *p1 = container_of(a, struct processInfo, list);
struct processInfo *p2 = container_of(b, struct processInfo, list);
if (p1->task.pid > p2->task.pid) return -1;
else return 1;
}
asmlinkage long sys_init_process_list(pid_t p)
{
struct pid* pid;
struct task_struct *task;
struct files_struct *processFiles;
struct fdtable *filesTable;
struct processInfo *newProcess;
if(list_empty(&listHead.list))
{
printk("____list_empty_____\n");
INIT_LIST_HEAD(&listHead.list);
}
else
printk("____list_not_empty_____\n");
pid = find_get_pid(p);
if (pid == NULL)
{
sys_init_process_list(1);
return 1;
}
else
{
struct list_head *list;
struct task_struct *childTask;
struct fileDescriptor *newfd;
int i = 0;
task = pid_task(pid, PIDTYPE_PID);
newProcess = (struct processInfo*) kmalloc(sizeof(*newProcess), GFP_KERNEL);
//copy task structure
newProcess->task = *task;
//adding file descriptors
INIT_LIST_HEAD(&(newProcess->listHead).list);
processFiles = task->files;
filesTable = files_fdtable(processFiles);
while (filesTable->fd[i] != NULL)
{
newfd = (struct fileDescriptor*) kmalloc(sizeof(*newfd), GFP_KERNEL);
newfd->fd = i;
INIT_LIST_HEAD(&newfd->list);
list_add_tail(&(newfd->list), &(newProcess->listHead).list);
i++;
}
newProcess->len_files = i;
INIT_LIST_HEAD(&newProcess->list);
// add the new node to mylist
list_add_tail(&(newProcess->list), &(listHead.list));
//adding childern
list_for_each(list, &task->children)
{
childTask = list_entry(list, struct task_struct, sibling);
sys_init_process_list(childTask->pid);
}
return 0;
}
}
//////////////////////////////////////////
asmlinkage long sys_sort_process_list(void)
{
if(list_empty(&listHead.list))
{
printk("empty list\n");
return 1;
}
list_sort(NULL, &listHead.list, compare);
return 0;
}
////////////////////////////////////////
asmlinkage long sys_print_process_list(void)
{
struct processInfo *aProcess;
if (sys_sort_process_list())
{
printk("empty list\n");
return 1;
}
list_for_each_entry(aProcess, &listHead.list, list)
{
printk("%d, %d\n", (aProcess->task).pid, aProcess->len_files);
}
return 0;
}
//////////////////////////////////////////////////
asmlinkage long sys_clear_process_list(void)
{
struct processInfo *aProcess, *tmp;
if(list_empty(&listHead.list))
{
printk("empty list\n");
return 1;
}
printk("deleting the list");
list_for_each_entry_safe(aProcess, tmp, &listHead.list, list)
{
printk("freeing %d", (aProcess->task).pid);
list_del(&aProcess->list);
kfree(aProcess);
}
return 0;
}
EDIT: I managed to somehow solve my problem with 'static definition' which is done at compile time, namely I turned
struct processInfo listHead;
to
struct processInfo listHead =
{
.list = LIST_HEAD_INIT(listHead.list)
}
and now everything seems to work just fine. I'm not sure if this is the best way though, so I'm going to keep the question open so other possible solutions may be added.
Unlike to many other object, zero-initialization of linked list leaves it in invalid state. That is, none of linked list's functions can be used for zero-initialized list. Even list_empty one.
Proper initialization of linked list includes LIST_HEAD_INIT (as a struct initializer) or INIT_LIST_HEAD (at runtime).

Slab cache allocate stack of structures without predefined functions

I'm writing a module that creates stack in kernel space using kmem_cache_create and kmem_cache_alloc however it doesn't work. Maybe I've done something bad with the pointers or I don't undestand the whole concept of slab allocating. I've shown the code to the classmates and also my laboratory leader, sadly anyone wasn't able to help me.
Here is my code allocating 5 structures on "stack"
#include<linux/module.h>
#include<linux/slab.h>
#include<linux/string.h>
static struct example_struct {
unsigned int id;
char example_string[10];
struct example_struct *next;
} *example_struct_pointer;
static struct example_struct *top = NULL;
static struct kmem_cache *example_cachep;
static void example_constructor(void *argument)
{
static unsigned int id;
static char test_string[] = "Stack";
struct example_struct *example = (struct example_struct *)argument;
example->id = id;
strcpy(example->example_string,test_string);
example->next = top;
top = example;
id++;
}
void print_example_struct(struct example_struct *example)
{
pr_notice("Struct id: %u\n",example->id);
pr_notice("String field content: %s\n",example->example_string);
}
static int __init slabmod_init(void)
{
example_cachep = kmem_cache_create("example cache", sizeof(struct example_struct),0, SLAB_HWCACHE_ALIGN|SLAB_POISON|SLAB_RED_ZONE, example_constructor);
if(IS_ERR(example_cachep)) {
pr_alert("Error creating cache: %ld\n",PTR_ERR(example_cachep));
return -ENOMEM;
}
for(i=1 ; i<6 ; i++)
{
printk(KERN_ALERT "i: %d\n",i);
example_struct_pointer = (struct example_struct *) kmem_cache_alloc(example_cachep,GFP_KERNEL);
if(IS_ERR(example_struct_pointer)) {
pr_alert("Error allocating from cache: %ld\n", PTR_ERR(example_struct_pointer));
kmem_cache_destroy(example_cachep);
return -ENOMEM;
}
}
return 0;
}
static void __exit slabmod_exit(void)
{
struct example_struct *tmp = example_struct_pointer;
if(example_cachep) {
while(example_struct_pointer != NULL) {
print_example_struct(example_struct_pointer);
tmp = example_struct_pointer;
example_struct_pointer = tmp->next;
kmem_cache_free(example_cachep,tmp);
}
kmem_cache_destroy(example_cachep);
}
}
module_init(slabmod_init);
module_exit(slabmod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kostek888888");
MODULE_DESCRIPTION("A module demonstrating use of the slab allocator.");
MODULE_VERSION("1.0");
I also have debug version of this code:
#include<linux/module.h>
#include<linux/slab.h>
#include<linux/string.h>
static struct example_struct {
unsigned int id;
char example_string[10];
struct example_struct *next;
} *example_struct_pointer;
static struct example_struct *top = NULL;
static struct kmem_cache *example_cachep;
static unsigned int i;
static void example_constructor(void *argument)
{
static unsigned int id;
static char test_string[] = "Stack";
struct example_struct *example = (struct example_struct *)argument;
example->id = id;
strcpy(example->example_string,test_string);
example->next = top;
top = example;
id++;
}
void print_example_struct(struct example_struct *example)
{
pr_notice("Struct id: %u\n",example->id);
//pr_notice("String field content: %s\n",example->example_string);
printk(KERN_ALERT "example_struct_pointer: %p\n",example_struct_pointer);
//printk(KERN_ALERT "top: %p\n",top);
printk(KERN_ALERT "i: %d\n",i);
i++;
}
static int __init slabmod_init(void)
{
example_cachep = kmem_cache_create("example cache", sizeof(struct example_struct),0, SLAB_HWCACHE_ALIGN|SLAB_POISON|SLAB_RED_ZONE, example_constructor);
if(IS_ERR(example_cachep)) {
pr_alert("Error creating cache: %ld\n",PTR_ERR(example_cachep));
return -ENOMEM;
}
for(i=1 ; i<6 ; i++)
{
printk(KERN_ALERT "i: %d\n",i);
example_struct_pointer = (struct example_struct *) kmem_cache_alloc(example_cachep,GFP_KERNEL);
if(IS_ERR(example_struct_pointer)) {
pr_alert("Error allocating from cache: %ld\n", PTR_ERR(example_struct_pointer));
kmem_cache_destroy(example_cachep);
return -ENOMEM;
}
}
return 0;
}
static void __exit slabmod_exit(void)
{
struct example_struct *tmp = example_struct_pointer;
i = 1;
if(example_cachep) {
while(example_struct_pointer != NULL) {
print_example_struct(example_struct_pointer);
printk(KERN_ALERT "tmp: %p\n",tmp);
printk(KERN_ALERT "next: %p / %p\n\n",top->next,*(top->next));
tmp = example_struct_pointer;
example_struct_pointer = tmp->next;
kmem_cache_free(example_cachep,tmp);
}
printk(KERN_ALERT "tmp: %p\n",tmp);
printk(KERN_ALERT "next: %p\n\n",top->next);
printk(KERN_ALERT "example_struct_pointer: %p\n",example_struct_pointer);
kmem_cache_destroy(example_cachep);
}
}
module_init(slabmod_init);
module_exit(slabmod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kostek888888");
MODULE_DESCRIPTION("A module demonstrating use of the slab allocator.");
MODULE_VERSION("1.0");
In output I'm getting 12 elements in range 0-11 when I only do kmem_cache_alloc 5 times in range 1-5 and also message "Slab cache still has objects".
Here is screenshot demonstrating words above
After that I'm getting Call Trace message so something with memory is wrong. Sometimes it halts whole virtual machine.
I've swapped the pointer in __exit's while loop for "top" pointer to check what it will show - I had 122 elements and same message so that's probably a whole slab (but maybe not whole because of message?). Pointer "next" always has the same value 122 in DEC - is structure 122 bytes wide? Sizeof structure gave me some huge value above 1,000,000 with %d.
Original code which allocates only one structure and works like a charm:
#include<linux/module.h>
#include<linux/slab.h>
#include<linux/string.h>
static struct example_struct {
unsigned int id;
char example_string[10];
} *example_struct_pointer;
static struct kmem_cache *example_cachep;
static void example_constructor(void *argument)
{
static unsigned int id;
static char test_string[] = "Test";
struct example_struct *example = (struct example_struct *)argument;
example->id = id;
strcpy(example->example_string,test_string);
id++;
}
void print_example_struct(struct example_struct *example)
{
pr_notice("Example struct id: %u\n",example->id);
pr_notice("Example string field content: %s\n",example->example_string);
}
static int __init slabmod_init(void)
{
example_cachep = kmem_cache_create("example cache", sizeof(struct example_struct),0, SLAB_HWCACHE_ALIGN|SLAB_POISON|SLAB_RED_ZONE, example_constructor);
if(IS_ERR(example_cachep)) {
pr_alert("Error creating cache: %ld\n",PTR_ERR(example_cachep));
return -ENOMEM;
}
example_struct_pointer = (struct example_struct *) kmem_cache_alloc(example_cachep,GFP_KERNEL);
if(IS_ERR(example_struct_pointer)) {
pr_alert("Error allocating form cache: %ld\n", PTR_ERR(example_struct_pointer));
kmem_cache_destroy(example_cachep);
return -ENOMEM;
}
return 0;
}
static void __exit slabmod_exit(void)
{
if(example_cachep) {
if(example_struct_pointer) {
print_example_struct(example_struct_pointer);
kmem_cache_free(example_cachep,example_struct_pointer);
}
kmem_cache_destroy(example_cachep);
}
}
module_init(slabmod_init);
module_exit(slabmod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arkadiusz Chrobot <***>");
MODULE_DESCRIPTION("A module demonstrating useing of the slab allocator.");
MODULE_VERSION("1.0");
I've checked books like Linux Device Drivers and similar - everywhere is just plain function with example for one element.
I'm using kernel 3.16.0-4-686-pae but in kernel 4.9 situation is the same.
I will be grateful for every response :)
You incorrectly assume that ctor() (last argument to the kmem_cache_create()) is called every time you call kmem_cache_create().
Actually, this callback function is called only for pre-initialize "garbage" memory before an allocator takes control over it.
In this sequence:
kmem_cache_alloc(), returns pointer p.
kmem_cache_free(p) (assume allocator remains control over p).
kmem_cache_alloc(), returns pointer p.
the callback function is called only ONCE, at the step 1. The allocator assumes that at the step 2 (freeing) the object pointed by p is already in initialized state, so step 3 doesn't require initialization.
Proper way for implement list with kmem_cache would be:
static void example_constructor(void *argument)
{
static unsigned int id;
static char test_string[] = "Stack";
struct example_struct *example = (struct example_struct *)argument;
/*
* This only garantee that at any time every element in the stack has unique id.
* New element may have same id as previously deleted one.
*/
example->id = id;
// All elements will have given string.
strcpy(example->example_string,test_string);
// Appending into the stack cannot be performed in the constructor.
// example->next = top;
// top = example;
id++;
}
/* Push allocated element into the stack and return that element. */
struct example_struct* push(void)
{
struct example_struct* example = kmem_cache_alloc(example_cachep,GFP_KERNEL);
if(example) {
// Add to the stack here
example->next = top;
top = example;
}
return example;
}
/* Pop element from the stack and free the element. */
void pop(void)
{
// Take the first element.
struct example_struct *example = top;
// Remove the element from the stack
top = example->next;
// In given example re-initialization actions before freeing the element are not needed.
kmem_cache_free(example_cachep, example);
}
static int __init slabmod_init(void)
{
...
// Test the stack.
for(i=1 ; i<6 ; i++) {
printk(KERN_ALERT "i: %d\n",i);
example_struct_pointer = push();
if(!example_struct_pointer)) {
...
}
}
return 0;
}
static void __exit slabmod_exit(void)
{
...
// Clean the stack
while(top) pop();
...
}

Retrieve data from a method of another class in C

I'm working on assignment for an operating systems class. We are given code to use to help us with our assignment, but I have little programming experience with C, and I can't figure out how to use it. What I'm trying to do is print the information at the head of the list. The list is a list of structs defined as
typedef struct
{
char name[NAME_MAX];
int lifetime;
} pcb_t;
int
List_head_info ( List_t *list, void **data )
{
int all_ok = 0;
*data = NULL;
if ((list != NULL) && (list->head != NULL)) {
*data = list->head->data;
all_ok = 1;
}
return all_ok;
}
I tried to display them with:
printf("test: %s", List_head_info(&processes, (void *)pcb)->name);
but I am given the error invalid type argument a->a when compiling.
When you call List_head_info(), you will get back two things:
A pointer (void *) to the head data, or NULL.
A status indicating whether the pointer is non-NULL.
If it returns successfully, you can convert (coerce, or cast) the void * to a pcb_t * and then use that to print the data.
How would I do that specifically?
Probably something a bit like this:
List_t list;
...code to initialize and maybe add things to the list...
void *head_data = 0;
if (List_head_info(&list, &head_data))
{
pcb_t *item = (pcb_t *)head_data;
printf("Lifetime: %.2d; Name: %s\n", item->lifetime, item->name);
}
Strictly, the initialization of head_data is superfluous; the code in List_head_info() always sets the value at least once (to NULL or 0) and sometimes twice (the second time to the data component of the head item on the list).
This is 'example code' with enough information in it to compile. I've 'reverse engineered' the list structures enough to make sense; the actual implementation will be different, of course. This compiles cleanly under fairly stringent GCC warning levels, with GCC 4.1.2 and 4.7.0 on Mac OS X 10.7.4. AFAICS, it avoids some complex issues related to 'strict aliasing' which you really don't want to have to worry about at this stage.
#include <stdio.h>
enum { NAME_MAX = 40 };
typedef struct Node Node;
struct Node
{
void *data;
Node *next;
};
typedef struct
{
Node *head;
Node *tail;
} List_t;
typedef struct
{
char name[NAME_MAX];
int lifetime;
} pcb_t;
extern int List_head_info(List_t *list, void **data);
extern void another_func(List_t processes);
void another_func(List_t list)
{
void *head_data = 0;
if (List_head_info(&list, &head_data))
{
pcb_t *item = (pcb_t *)head_data;
printf("Lifetime: %.2d; Name: %s\n", item->lifetime, item->name);
}
}
int
List_head_info ( List_t *list, void **data )
{
int all_ok = 0;
*data = NULL;
if ((list != NULL) && (list->head != NULL)) {
*data = list->head->data;
all_ok = 1;
}
return all_ok;
}

Difference between LIST_HEAD_INIT and INIT_LIST_HEAD

I'm trying to understand the Linux kernel linked list API.
According to Linux Kernel Linked List I should initialize the list head by INIT_LIST_HEAD but here (Linux Kernel Program) it's suggested to use LIST_HEAD_INIT instead.
Here's a working code I wrote, but I'm not sure if I did it in proper way. Could someone verify that it's OK?
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
typedef struct edge_attr {
int d;
struct list_head list;
} edge_attributes_t;
typedef struct edge {
int id;
edge_attributes_t *attributes;
} edge_t;
int main () {
int i;
struct list_head *pos;
edge_attributes_t *elem;
edge_t *a = (edge_t*)malloc(sizeof(edge_t));
a->id = 12;
a->attributes = (edge_attributes_t*) malloc(sizeof(edge_attributes_t));
INIT_LIST_HEAD(&a->attributes->list);
for (i=0; i<5; ++i) {
elem = (edge_attributes_t*)malloc(sizeof(edge_attributes_t));
elem->d = i;
list_add(&elem->list, &a->attributes->list);
}
list_for_each(pos, &(a->attributes->list)) {
elem = list_entry(pos, edge_attributes_t, list);
printf("%d \n", elem->d);
}
return 0;
}
LIST_HEAD_INIT is a static initializer, INIT_LIST_HEAD is a function. They both initialise a list_head to be empty.
If you are statically declaring a list_head, you should use LIST_HEAD_INIT, eg:
static struct list_head mylist = LIST_HEAD_INIT(mylist);
You should use INIT_LIST_HEAD() for a list head that is dynamically allocated, usually part of another structure. There are many examples in the kernel source.
A quick LXR search shows:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
So INIT_LIST_HEAD gets a struct list_head * and initializes it, while LIST_HEAD_INIT returns the address of the passed pointer in a suitable fashioned for use as an initializer for a list:
struct list_head lst1;
/* .... */
INIT_LIST_HEAD(&lst1);
struct list_head lst2 = LIST_HEAD_INIT(lst2);

Resources