title: kernel crash for spinlock concurrency in linux-kernel
body: <p>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.</p>
  
  <p>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.</p>
  
  <p>Any tips will be appreciate.</p>
  
  <p>The following is the simplified code.</p>
  
  <pre><code>#include &lt;linux/init.h&gt;
  #include &lt;linux/module.h&gt;
  #include &lt;linux/list.h&gt;
  #include &lt;linux/slab.h&gt;
  
  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(&amp;number_wrap-&gt;list_lock); 
      list_for_each_entry_safe(num_head, tmp, &amp;number_wrap-&gt;num_list, node) {
          printk("num_head is %d\n", num_head-&gt;number); 
          list_del(&amp;num_head-&gt;node);//this line seems to have problem 
      }
      spin_unlock(&amp;number_wrap-&gt;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-&gt;number = 10; 
      number_wrap-&gt;check_num = 20;
      INIT_LIST_HEAD(&amp;number-&gt;node);   
      INIT_LIST_HEAD(&amp;number_wrap-&gt;num_list); 
      list_add_tail(&amp;number-&gt;node, &amp;number_wrap-&gt;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);
  </code></pre>
  
  <p><strong>update</strong></p>
  
  <p>After doing some debug, I seems to find root cause...
  my scenario is as follows :</p>
  
  <p>I have a private data struct which is included in the net_device struct.
  And the following is the simplified scenario:</p>
  
  <pre><code>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-&gt;if_list, list) {
      free_netdev(xx_if-&gt;ndev);
      list_del(&amp;xx_if-&gt;list);
  } 
  </code></pre>
  
  <p>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. </p>
  
  <p>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.</p>