Hi everyone,
I'm not sure if I'm at the right place to ask this question, but I
might aswell try; I'm writing you this mail because there is one thing
I can't understand in the openbsd kthread.
Actually, it is those two functions from the kthread's man :
kthread_create and kthread_create_deferred.. from man 9
kthread_create creates a kernel thread and kthread_create_deferred
adds a pointer to a function in a queue that will be then went through
and each of it's elements will be launched in a seperate kthread.
I wrote a simple syscall using the lkm and kthread_create;
Here is the syscall :
#include <sys/param.h>
#include <sys/kthread.h>
#include <sys/types.h>
#include <sys/malloc.h>
#define NB_THREAD 1
void theHook(void *data)
{
uprintf("Goodbye threaded world\n");
kthread_exit(0);
}
int mycall(struct proc *p, void *uap, int retval[])
{
int error;
struct proc *mypr;
uprintf( "I create a new thread for fun :)\n" );
kthread_create(theHook, NULL, &mypr, "bite!");
return (0);
}
But it would not work : The thread was not launched.
I therefor replaced kthread_create by kthread_create_deferred and it
looked like this :
kthread_create_deferred(theHook, NULL)
And then the thread was launched ...
This was disturbing me, so I went and looked at the kernel sources for
the threads :
/usr/src/sys/kern/kern_kthread.c
/usr/src/sys/sys/kthread.h
In kthread_create, everything seems normal, it creates a process.
But in kthread_create_deferred i found this code :
kthread_create_deferred(void (*func)(void *), void *arg)
{
struct kthread_q *kq;
if (kthread_create_now) {
(*func)(arg);
return;
}
kq = malloc(sizeof *kq, M_TEMP, M_NOWAIT);
if (kq == NULL)
panic("unable to allocate kthread_q");
bzero(kq, sizeof *kq);
kq->kq_func = func;
kq->kq_arg = arg;
SIMPLEQ_INSERT_TAIL(&kthread_q, kq, kq_q);
}
What this code roughly does is :
Check if the variable kthread_create_now is true,
if it is, it launchs the function sent in parameter
else it adds it in the queue with it's attached parameters
So I ask myself :"When is initialised this kthread_create_now variable ?"
And I found out that it is global, and never initialized. It is also
used in the next function : kthread_run_deferred_queue :
kthread_run_deferred_queue(void)
{
struct kthread_q *kq;
/* No longer need to defer kthread creation. */
kthread_create_now = 1;
while ((kq = SIMPLEQ_FIRST(&kthread_q)) != NULL) {
SIMPLEQ_REMOVE_HEAD(&kthread_q, kq_q);
(*kq->kq_func)(kq->kq_arg);
free(kq, M_TEMP);
}
}
it sets ouyr mysterious variable to 1 and then launch every function
in the queu one by one. I can't find in any of those functions a hint
of a thread.
i try searching where kthread_run_deffered_queue is called, maybe
there is where the threads are launched ?
After a grep over all the sources, I can find only one call in the
file kern/init_main.c line 426 and still no clue where those threads
are launched.
I just can't figure out how it works ?!
With a simple kthread_create, it won't work ... Am I using it the rigth way ?
is it normal and safe that the global variable kthread_create_now is
not initialised ?
Is it normal that kthread_create_deferred doesn't launch any threads
or am I just not understanding the sources ?
Thanks a lot,
--
Gallon sylvestre
Astek michant / Assistant CISCO
Rathaxes Core Developper
http://blog.evilkittens.org/~syl/