|
List Info
Thread: problems with kthread
|
|
| problems with kthread |

|
2007-06-22 07:01:08 |
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 worldn");
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.evilkit
tens.org/~syl/
|
|
| Re: problems with kthread |
  United States |
2007-06-23 11:47:14 |
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_deferred....and then....heeeelp?
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
>
> void theHook(void *data)
> {
> uprintf("Goodbye threaded worldn");
> 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.evilkit
tens.org/~syl/
>
>
>
--
View this message in context: http://www.nabble.com/problems-with-kthread-
tf3964264.html#a11268150
Sent from the openbsd user - misc mailing list archive at
Nabble.com.
|
|
| Re: problems with kthread |
  Sweden |
2007-06-25 04:10:45 |
syl <ccna.syl gmail.com> writes:
> 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 worldn");
> 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.
Erm. How do you know it didn't work?
You're definitely using uprintf incorrectly since the
kthread will not
have any tty, therefore it won't know where to print stuff.
So if you're
depending on uprintf to know what happened, it won't do what
you think
it will.
uprintf should be used very carefully.
> I therefor replaced kthread_create by
kthread_create_deferred and it
> looked like this :
kthread_create_deferred is not for you.
//art
|
|
[1-3]
|
|