Re: Polling in kernel threads

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Lukas Razik <linux@xxxxxxxxxx> writes:

> Hello Mulyadi!
>
>> first of all, what do you poll there? some register status? could the
>> device just yield an interrupt?
>
> I poll a message queue. The Dolphin SCI network card's kernel modules
> have a message queue implementation and I call their receive function:
> SCILReceiveVMsg(queue,&scimsg,size,&bytes_left,SCIL_FLAG_FULL_ERROR_CHECK|SCIL_FLAG_MESSAGE_MODE);
> And if there's a new message in the queue, then we have it in our scimsg...
>
>
>> And why don't you utilize NAPI here?
>
> Yesterday I thought the first time about this possibility because I
> never used NAPI before and it would only be another way of polling
> (maybe the right way for us) but we wanted to poll the whole time and
> I wanted to try it with a kernel thread. I haven't thought that I'll
> have any problems...
> And I thought that NAPI only polls if there are many packets coming in
> but I must read more about this technique...
>
>
>>>But now there are two problems:
>>>
>>>1. problem is that the kernel thread doesn't get any signals which are sent
>>>to it. A possibility is to use a variable instead of
>>>"!signal_pending(current)" to advise the thread to exit. But I would like to
>>>know why the thread gets no signals until I insert a sleep function, like
>>>"msleep(1)", into the while loop.
>>
>>
>> Interesting....what preemption model do you use? CMIIW, but I guess
>> signal is not delivered because the other code path (i.e tasklet code
>> or anything that send the signal) didn't have chance to run.
>>
>> may we know how do you deliver the signal?
>
>
> I do it like in the following example (kernel v2.6.25, Preemption
> Model: PREEMPT_NONE):
> Wee need PREEMPT_NONE because we want to use the driver with a
> Kerrighed patched kernel which doesn't allow kernel preemption yet.
>
> - BEGIN -
> #include <linux/module.h>
> #include <linux/init.h>
> #include <linux/in.h>
> #include <linux/kthread.h>
> #include <linux/timer.h>
>
> static unsigned int sleep = 1;
> module_param(sleep, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
>
> static DECLARE_COMPLETION( threadcomplete );
> static int com_thread_pid;
>
> static int com_thread( void *data )
> {
>   long count = 0;
>
>   daemonize( "comthread" );
>   allow_signal( SIGTERM );
>   printk(KERN_INFO "threadtest: Thread will loop...\n");
>   while( !signal_pending(current) ) {
>      count++;
>      if(sleep) msleep(1);
>   }
>   printk(KERN_INFO "threadtest: Thread has finished and will be
> closed... (count=%ld)\n", count);
>   complete_and_exit(&threadcomplete, 0);
> }
>
> static int __init server_init( void )
> {
>   com_thread_pid=kernel_thread(com_thread,NULL, CLONE_KERNEL );
>   if( com_thread_pid < 0 ) {
>     return -EIO;
>   }
>   return 0;
> }
>
> static void __exit server_exit( void )
> {
>   if( com_thread_pid ) {
>     kill_proc( com_thread_pid, SIGTERM, 0 );
>     wait_for_completion( &threadcomplete );
>   }
> }
>
> module_init( server_init );
> module_exit( server_exit );
> MODULE_LICENSE("GPL");
> - END -
>
>
> If you load this module and set:
>
> echo 0 > /sys/module/threadtest/parameters/sleep
>
> then you won't be able to unload the module by rmmod and myabe the
> system won't work stable anymore (maybe opening a file will block or
> something different won't work) even if you have several CPUs...
>
>
> After setting
>
> echo 1 > /sys/module/threadtest/parameters/sleep
>
> back, you will be able to unload the module and the system will become
> stable again.
> It was the same with other systems (2 and 8 CPUs) and older kernels
> (like 2.6.18)...

You don't give the scheduler a chance to run.  If you sleep, the
scheduler will run and be able to deliver the signal and this is why it
works then.

Spinning like this is bad.  That should actually freeze a UP machine if
I do not miss something.

I would do the following (might be wrong):

	while (!signal_pending(current))
		schedule();

Hope that helps,

	Hannes

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux