Oh geeze, list_heads. I remember wrangling with these when I was taking an OS class. In particular, my partner and I lost points on a project because we (and basically everybody else in the class) failed to recognize a subtle bug in how we were traversing lists.<p>Say you have a task_struct, and you want to iterate through the list of that task's children. You look through the code and you see<p>>struct list_head children; /* list of my children * /<p>>struct list_head sibling; /* linkage in my parent's children * /<p>And because it's late and you've been working for hours, you say "Ah ha! We'll just iterate through the children list_head, which is the list of the task's children, and that will give us what we want!"<p>But it turns out that's not how it works, because list_heads aren't linked lists like how you're used to thinking of them from your class on Data Structures! Here's what happens when you run your naive code iterating through children!<p>You start at task_struct foo, and you follow the pointer to a child of foo. Now, you follow children again, because you're still thinking that children is the list_head of foo's children. But you're wrong, because now you're in task_struct bar, and list_head children is now a list of bar's children; what you should be doing is iterating through list_head siblings!<p>We were pretty salty about losing the points, as I recall. On the other hand, after that experience we were very careful about keeping track of which struct we were in during any particular operation on a list_head, and I can remember how how they work (and how angry they made me) long after the class is over.