How to safely exit from a kthread, that executes a function periodically, on removing a module?
<p>I am starting a kthread, which will execute a function periodically, from a loadable kernel module.</p>

<pre><code>int start_fwd_filter(struct bloom_filter *bflt)
{
    fwd_bflt_thread = 
    kthread_run((void *)timed_fwd_filter, (void *)bflt, "fwd_bflt");

    if(fwd_bflt_thread == NULL)
            return -1;

    return 0;
}

int timed_fwd_filter(void* data)
{
    struct bloom_filter *bflt = (struct bloom_filter *)data;

    allow_signal(SIGKILL|SIGSTOP);

    while(1)
    {
            __set_current_state(TASK_INTERRUPTIBLE);
            schedule_timeout(delay*HZ);

            if(kthread_should_stop())
            {
                   pr_info(" *** mtp | 1.timed_fwd_filter thread"
                           " stopped | timed_fwd_filter *** \n");

                   timed_fwd_filter_stopped = 1;
                   return 0;
            }

            if(signal_pending(current))
                    goto exit_timed_fwd_filter;


            if(tcp_client_fwd_filter(bflt) &lt; 0)
            {
                    pr_info(" *** mtp | tcp_client_fwd_filter 2 attmepts "
                            "failed | timed_fwd_filter *** \n");
            }

            if(kthread_should_stop())
            {
                   pr_info(" *** mtp | 2.timed_fwd_filter thread"
                           " stopped | timed_fwd_filter *** \n");

                   timed_fwd_filter_stopped = 1;
                   return 0;
            }

            if(signal_pending(current))
            {
                   goto exit_timed_fwd_filter;
            }

    }

exit_timed_fwd_filter:

    timed_fwd_filter_stopped = 1;

    do_exit(0);
}
</code></pre>

<p>And when the module is unloaded, I am issuing a call to kthread_stop() to stop this thread:</p>

<pre><code>static void __exit network_server_exit(void)
{
    int ret;
    int id;

    if(fwd_bflt_thread != NULL)
    {
            if(!timed_fwd_filter_stopped)
            {
                    ret = kthread_stop(fwd_bflt_thread);

                    if(!ret)
                            pr_info(" *** mtp | timed forward filter thread"
                                    " stopped | network_server_exit *** \n");
            }
    }
    ...
}
</code></pre>

<p>But I am unable to remove module as rmmod is getting hung:</p>

<pre><code>[  599.823825] INFO: task rmmod:2359 blocked for more than 120 seconds.
[  599.823845]       Tainted: G           OE 3.16.0-45-generic #60~14.04.1-Ubuntu
[  599.823863] "echo 0 &gt; /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  599.823882] rmmod           D ffff88022f3530c0     0  2359   2358 0x00000004
[  599.823884]  ffff880216eb3da0 0000000000000082 ffff8802209d3d20 ffff880216eb3fd8
[  599.823885]  00000000000130c0 00000000000130c0 ffff8802239a3d20 ffff8800bb91ff10
[  599.823887]  ffff8800bb91ff18 7fffffffffffffff ffff8802209d3d20 00007fe3a7de9200
[  599.823888] Call Trace:
[  599.823893]  [&lt;ffffffff8176a2d9&gt;] schedule+0x29/0x70
[  599.823894]  [&lt;ffffffff817696b9&gt;] schedule_timeout+0x229/0x2a0
[  599.823897]  [&lt;ffffffff810c9198&gt;] ? console_unlock+0x1f8/0x440
[  599.823899]  [&lt;ffffffff8176add6&gt;] wait_for_completion+0xa6/0x160
[  599.823901]  [&lt;ffffffff810a1b30&gt;] ? wake_up_state+0x20/0x20
[  599.823904]  [&lt;ffffffff810917da&gt;] kthread_stop+0x4a/0xe0
[  599.823907]  [&lt;ffffffffc052b6b0&gt;] network_server_exit+0x83/0x9d3 [local_tcp]
[  599.823910]  [&lt;ffffffff810ebb92&gt;] SyS_delete_module+0x162/0x200
[  599.823912]  [&lt;ffffffff81013057&gt;] ? do_notify_resume+0x97/0xb0
[  599.823915]  [&lt;ffffffff8176e34d&gt;] system_call_fastpath+0x1a/0x1f
</code></pre>

<p>Suspecting that my explicit call to <code>schedule_timeout()</code>, to periodically call <code>tcp_client_fwd_filter(bflt)</code>, might be causing a problem as <code>kthread_stop()</code> also eventually calls <code>schedule_timeout(</code>) with <code>MAX_SCHEDULE_TIMEOUT</code> to let <code>kthread-&gt;exited-&gt;done</code> to be true, I removed <code>schedule_timeout()</code> call and put in:</p>

<pre><code>int timed_fwd_filter(void* data)
{
    struct bloom_filter *bflt = (struct bloom_filter *)data;

    DECLARE_WAIT_QUEUE_HEAD(fwdwait);

    allow_signal(SIGKILL|SIGSTOP);

    while(1)
    {
            wait_event_timeout( fwdwait, (kthread_should_stop() == true), delay*HZ)
            if(kthread_should_stop())
            {
                   pr_info(" *** mtp | 1.timed_fwd_filter thread"
                           " stopped | timed_fwd_filter *** \n");

                   timed_fwd_filter_stopped = 1;
                   return 0;
            }
            ...
</code></pre>

<p>Still I was facing the same problem and also I realized that <code>wait_event_timeout()</code> also calls <code>schedule_timeout(</code>). I think I am doing something wrong here, but unable to figure out what exactly. Can someone help me out with us?</p>

<blockquote>
  <p>EDIT:
  I cleaned up the code and made <code>!kthread_should_stop()</code>check the <code>while</code> loop condition, as it was found in many examples, still no luck.</p>
</blockquote>

<pre><code>int timed_fwd_filter(void* data)
{
    unsigned long jleft = 0;

    struct bloom_filter *bflt = (struct bloom_filter *)data;

    allow_signal(SIGKILL|SIGSTOP);

    set_current_state(TASK_INTERRUPTIBLE);

    while(!kthread_should_stop())
    {
            jleft = schedule_timeout(delay*HZ);

            __set_current_state(TASK_RUNNING);

            if(signal_pending(current))
            {
                   goto exit_timed_fwd_filter;
            }

            if(tcp_client_fwd_filter(bflt) &lt; 0)
            {
                    pr_info(" *** mtp | tcp_client_fwd_filter 2 attmepts "
                            "failed | timed_fwd_filter *** \n");
            }

            set_current_state(TASK_INTERRUPTIBLE);


    }

    __set_current_state(TASK_RUNNING);


exit_timed_fwd_filter:

   timed_fwd_filter_stopped = 1;
   do_exit(0);
}
</code></pre>