Hi guys,
Say we have a module for kernel 2.4(.25 exactly) with the
module_init() as followed:
module_init()
{
.....
mod_timer(&my_timer, jiffies+INTERVAL);
.....
}
and we have my_timer.function as followed:
void my_timer_fun(unsigned long dummy)
{
if(condition) {
schedule_task(&my_task);
}
if(!stop_my_timer) {
mod_timer(&my_timer, jiffies+INTERVAL);
}
}
When rmmod, we must do some housekeeping for my_timer and my_task, and
here comes the questions:
1. As to my_timer, is the following code enough? Does any race condition exist?
stop_my_timer = 1;
del_timer_sync(&my_timer);
According to my understanding, the code is enough, and furthermore,
the flag var "stop_my_timer" is unnecessary. Since after return,
del_timer_sync() can ensure a) my_timer is not running on any CPU; b)
my_timer is not in the timer list so it will not execute in the
future.
But according to "Linux device driver, 2e", Chapter 6 Flow of Time,
Kernel Timers, it says:
" If the timer function can restart the timer itself (a common
pattern), you should also have a "stop timer'' flag that you set
before calling del_timer_sync. The timer function should then check
that flag and not reschedule itself with add_timer if the flag has
been set."
Do I misunderstand something here? Is there any trap for del_timer_sync()?
The previous quoted text can be found online here:
http://www.xml.com/ldd/chapter/book/ch06.html#t5
2. As to my_task, after my_timer has been deleted, it maybe in 3
status: a) running; b) in the task queue waiting for running; c) not
running and not in the task queue. So, how can I distinguish these
situations? Since my_task.list will not be reinitialized after
run_task_queue(), we can't use it to check whether my_task is in queue
or not. And we can't use my_task.sync either, since it has obvious
race condition. I guess it's really a newbie's question but I just can
not resolve it by myself in the last few days.
To say the least, suppose we know my_task is in the queue or is
running by some way, we must wait for its completion, maybe we can
apply interruptiable_sleep_on() in module_exit(), and
wake_up_interruptible() at the end of my_task.routine() like this:
void my_task_routine(void *dummy)
{
.....
.....
wake_up_interruptible(...);
}
Well, as we know, a function contains prolog and epilog. After
wake_up_interruptible(), the rmmod thread executes and frees the
memory of this module. At this time, memory containing epilog of the
my_task_routine() was freed, it may oops when those "epilog" execute
later on. Is this a trap? or do I make some mistakes?
At last, many thanks for you to read my post, and any help will be appreciated.
--
Invent and fit; have fits and reinvent!
We toast the Lisp programmer who pens his thoughts within nests of parentheses.
N�����r��y����b�X��ǧu�ޙ���+a�{.n�+���z�ޖw�n'����j�b�ye�{������z��v�^�m���z�ޖw�n'���?