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/

Reply via email to