This is a great example of a kind of Polymorphism in C. To borrow terminology from C++, the list_entry() macro allows you to downcast from a list_head type to any type that contains it.
Have a look at kthread.c for a simple fundamental example:
kernel/kthread.c:
struct kthread_create_info
{
/* Information passed to kthread() from kthreadd. */
int (*threadfn)(void *data);
void *data;
int node;
/* Result passed back to kthread_create() from kthreadd. */
struct task_struct *result;
struct completion *done;
struct list_head list;
};
...
int kthreadd(void *unused)
{
...
while (!list_empty(&kthread_create_list)) {
struct kthread_create_info *create;
create = list_entry(kthread_create_list.next,
struct kthread_create_info, list);
...
create_kthread(create);
By including a list_head object in the kthread_create_info struct, you can say that kthread_create_info "derives" from list_head. This allows kthread_create_info objects to be used as nodes in a list, meaning you can pass them to any of the functions declared in list.h by simply dereferencing the list member of the struct. The list_entry macro then gives you the mapping from a base class pointer to its derived start address.
In other words, given a list_head object that you know is contained within an outer kthread_create_info struct, you can recover a pointer to the kthread_create_info container.
This is an extremely common pattern in C programming, where object oriented constructs are desired, but a C++ compiler isn't available.