title: Kernel panic inside mod_timer()
body: <p>I am writing a program which uses multiple timers. For every 5 seconds, they will use one same netlink to communicate with userspace.</p>
  
  <p>To be more specifically, every 5 seconds each timer will call a <code>func()</code>, the <code>func()</code> will do lock, sending something, unlock, and:</p>
  
  <pre><code>delay_us(200);        
  if(!timer_pending(&amp;timer1)){
      mod_timer(&amp;timer1, jiffies+RTL_SECONDS_TO_JIFFIES(5));
  }
  </code></pre>
  
  <p>The strange thing is in very few occasion, the system will crash inside <code>mod_timer()</code>, I disassembly and find it crash at <code>tne  zero,v0,0xc</code></p>
  
  <p>The piece of code (MIPS instructions) is below:</p>
  
  <pre><code>    /*
       * This is a common optimization triggered by the
       * networking code - if the timer is re-modified
       * to be the same thing then just return:
       */
      if (timer_pending(timer) &amp;&amp; timer-&gt;expires == expires)
  800216bc:   8e020000    lw  v0,0(s0)
  800216c0:   50400005    beqzl   v0,800216d8 &lt;mod_timer+0x98&gt;
  800216c4:   8e020010    lw  v0,16(s0)
  800216c8:   8e020008    lw  v0,8(s0)
  800216cc:   10510042    beq v0,s1,800217d8 &lt;mod_timer+0x198&gt;
  800216d0:   24130001    li  s3,1
  800216d4:   8e020010    lw  v0,16(s0)
  800216d8:   2c420001    sltiu   v0,v0,1
  800216dc:   00020336    tne zero,v0,0xc
  </code></pre>
  
  <p>I am in great pain to debug. I doubt timer race but technically if so, crash should not inside <code>mod_timer()</code> right? It looks very likely some kind of racing happen but it's beyond my knowledge. Any debug suggestions are appreciated.</p>
  
  <p>EDIT :I just add some important dump message below：</p>
  
  <pre><code>Call Trace:
  [&lt;800243a4&gt;] mod_timer+0x9c/0x1b8
  [&lt;8002399c&gt;] call_timer_fn+0x20/0x88
  [&lt;80023bd0&gt;] run_timer_softirq+0x1cc/0x244
  [&lt;8001de80&gt;] __do_softirq+0x118/0x218
  [&lt;8001e05c&gt;] do_softirq+0x58/0x78
  [&lt;8001e0e0&gt;] irq_exit+0x64/0x80
  [&lt;8000044c&gt;] ret_from_irq+0x0/0x4
  [&lt;800036cc&gt;] __copy_user_common+0x44/0x2b8
  [&lt;8006701c&gt;] file_read_actor+0x9c/0x114
  [&lt;8006a47c&gt;] generic_file_aio_read+0x4f4/0x7f4
  [&lt;80092f00&gt;] do_sync_read+0x90/0xd4
  [&lt;80093fc8&gt;] vfs_read+0xb0/0x158
  [&lt;80094170&gt;] SyS_read+0x60/0x9c
  [&lt;800017b0&gt;] stack_done+0x20/0x40
  
  
  Code: 24130001  8e020010  2c420001 &lt;00020336&gt; 02002021  0c008f12  27a50010  8e030000  10600015
  </code></pre>
  
  <p>EDIT:The callback function is like:</p>
  
  <pre><code>void send_info(unsigned long task_priv)
  {
      unsigned long flags;
  
      struct target_priv *priv = (struct target_priv *)task_priv;
  
      SMP_LOCK(flags);
  
      construct_netlink_send(priv);
  
      SMP_UNLOCK(flags);
  
      delay_us(200);
  
      if ((!strcmp(priv-&gt;name, "timer0")) &amp;&amp; (!timer_pending(&amp;priv-&gt;timer0))){
                  mod_timer(&amp;priv-&gt;timer0, jiffies+SECONDS_TO_JIFFIES(5));
                      return;
              }
      ...//do same for the rest 9 timers
  }
  </code></pre>