I am certainly not the right person to answer this...but anyway...
After getting my securelevel down under ice, and playing a little with the
/usr/share/lkm source,
I tried putting your code into the mycall.c and it worked for me. (I can
send you a tarball if you want to try it.)
In fact, I put NULL where you had mypr, but that makes no big difference
for a simple test.
From the manpage of kthread_create:
Since the system has to be up and running for creating new processes, de-
vice drivers that want to create kernel threads early (e.g., at attach
time) may use kthread_create_deferred() instead. The system will call
back the function func with argument arg when it can create threads, so
it is up to func to call kthread_create() at that point.
This is probably the explanation to why there is no fork1 call creating a
thread
in the kthread_run_deferred_queue function. There is no fork1 in
kthread_create_deferred either,
of course...
I don't write device drivers, so I can't help you further. However, I could
reason a little:
The global variable kthread_create_now is a state which tells the kthread
functions
whether the kernel can create threads.
The funky thing is that it is not obvious how to write your kernel module.
If you use kthread_create
and it returns an error != EAGAIN, you might assume that the kernel can not
create threads at that point.
Hence, it would be right to use kthread_create_deferred, but then the
function which is supposed to
be run by the kthread is not in its own thread, so you will have to try
kthread_create from that function...
and then...if that fails with error != EAGAIN...you could put it on the
queue by using
kthread_create_deferredand thenhlp?
Conclusion is that everything is allright unless you write poorly designed
drivers. :)
Just my two cents...
// V.A.
syl-4 wrote:
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
voidtheHook(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