Mailing List Archive

[patch 02/11] syslets: add syslet.h include file, user API/ABI definitions
From: Ingo Molnar <mingo@elte.hu>

add include/linux/syslet.h which contains the user-space API/ABI
declarations. Add the new header to include/linux/Kbuild as well.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
include/linux/Kbuild | 1
include/linux/syslet.h | 136 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 137 insertions(+)

Index: linux/include/linux/Kbuild
===================================================================
--- linux.orig/include/linux/Kbuild
+++ linux/include/linux/Kbuild
@@ -140,6 +140,7 @@ header-y += sockios.h
header-y += som.h
header-y += sound.h
header-y += synclink.h
+header-y += syslet.h
header-y += telephony.h
header-y += termios.h
header-y += ticable.h
Index: linux/include/linux/syslet.h
===================================================================
--- /dev/null
+++ linux/include/linux/syslet.h
@@ -0,0 +1,136 @@
+#ifndef _LINUX_SYSLET_H
+#define _LINUX_SYSLET_H
+/*
+ * The syslet subsystem - asynchronous syscall execution support.
+ *
+ * Started by Ingo Molnar:
+ *
+ * Copyright (C) 2007 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * User-space API/ABI definitions:
+ */
+
+/*
+ * This is the 'Syslet Atom' - the basic unit of execution
+ * within the syslet framework. A syslet always represents
+ * a single system-call plus its arguments, plus has conditions
+ * attached to it that allows the construction of larger
+ * programs from these atoms. User-space variables can be used
+ * (for example a loop index) via the special sys_umem*() syscalls.
+ *
+ * Arguments are implemented via pointers to arguments. This not
+ * only increases the flexibility of syslet atoms (multiple syslets
+ * can share the same variable for example), but is also an
+ * optimization: copy_uatom() will only fetch syscall parameters
+ * up until the point it meets the first NULL pointer. 50% of all
+ * syscalls have 2 or less parameters (and 90% of all syscalls have
+ * 4 or less parameters).
+ *
+ * [. Note: since the argument array is at the end of the atom, and the
+ * kernel will not touch any argument beyond the final NULL one, atoms
+ * might be packed more tightly. (the only special case exception to
+ * this rule would be SKIP_TO_NEXT_ON_STOP atoms, where the kernel will
+ * jump a full syslet_uatom number of bytes.) ]
+ */
+struct syslet_uatom {
+ unsigned long flags;
+ unsigned long nr;
+ long __user *ret_ptr;
+ struct syslet_uatom __user *next;
+ unsigned long __user *arg_ptr[6];
+ /*
+ * User-space can put anything in here, kernel will not
+ * touch it:
+ */
+ void __user *private;
+};
+
+/*
+ * Flags to modify/control syslet atom behavior:
+ */
+
+/*
+ * Immediately queue this syslet asynchronously - do not even
+ * attempt to execute it synchronously in the user context:
+ */
+#define SYSLET_ASYNC 0x00000001
+
+/*
+ * Never queue this syslet asynchronously - even if synchronous
+ * execution causes a context-switching:
+ */
+#define SYSLET_SYNC 0x00000002
+
+/*
+ * Do not queue the syslet in the completion ring when done.
+ *
+ * ( the default is that the final atom of a syslet is queued
+ * in the completion ring. )
+ *
+ * Some syscalls generate implicit completion events of their
+ * own.
+ */
+#define SYSLET_NO_COMPLETE 0x00000004
+
+/*
+ * Execution control: conditions upon the return code
+ * of the previous syslet atom. 'Stop' means syslet
+ * execution is stopped and the atom is put into the
+ * completion ring:
+ */
+#define SYSLET_STOP_ON_NONZERO 0x00000008
+#define SYSLET_STOP_ON_ZERO 0x00000010
+#define SYSLET_STOP_ON_NEGATIVE 0x00000020
+#define SYSLET_STOP_ON_NON_POSITIVE 0x00000040
+
+#define SYSLET_STOP_MASK \
+ ( SYSLET_STOP_ON_NONZERO | \
+ SYSLET_STOP_ON_ZERO | \
+ SYSLET_STOP_ON_NEGATIVE | \
+ SYSLET_STOP_ON_NON_POSITIVE )
+
+/*
+ * Special modifier to 'stop' handling: instead of stopping the
+ * execution of the syslet, the linearly next syslet is executed.
+ * (Normal execution flows along atom->next, and execution stops
+ * if atom->next is NULL or a stop condition becomes true.)
+ *
+ * This is what allows true branches of execution within syslets.
+ */
+#define SYSLET_SKIP_TO_NEXT_ON_STOP 0x00000080
+
+/*
+ * This is the (per-user-context) descriptor of the async completion
+ * ring. This gets registered via sys_async_register().
+ */
+struct async_head_user {
+ /*
+ * Pointers to completed async syslets (i.e. syslets that
+ * generated a cachemiss and went async, returning -EASYNCSYSLET
+ * to the user context by sys_async_exec()) are queued here.
+ * Syslets that were executed synchronously are not queued here.
+ *
+ * Note: the final atom that generated the exit condition is
+ * queued here. Normally this would be the last atom of a syslet.
+ */
+ struct syslet_uatom __user **completion_ring;
+ /*
+ * Ring size in bytes:
+ */
+ unsigned long ring_size_bytes;
+
+ /*
+ * Maximum number of asynchronous contexts the kernel creates.
+ *
+ * -1UL has a special meaning: the kernel manages the optimal
+ * size of the async pool.
+ *
+ * Note: this field should be valid for the lifetime of async
+ * processing, because future kernels detect changes to this
+ * field. (enabling user-space to control the size of the async
+ * pool in a low-overhead fashion)
+ */
+ unsigned long max_nr_threads;
+};
+
+#endif
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 02/11] syslets: add syslet.h include file, user API/ABI definitions [ In reply to ]
On Tue, February 13, 2007 15:20, Ingo Molnar wrote:
> +/*
> + * Execution control: conditions upon the return code
> + * of the previous syslet atom. 'Stop' means syslet
> + * execution is stopped and the atom is put into the
> + * completion ring:
> + */
> +#define SYSLET_STOP_ON_NONZERO 0x00000008
> +#define SYSLET_STOP_ON_ZERO 0x00000010
> +#define SYSLET_STOP_ON_NEGATIVE 0x00000020
> +#define SYSLET_STOP_ON_NON_POSITIVE 0x00000040

This is confusing. Why the return code of the previous syslet atom?
Wouldn't it be more clear if the flag was for the current tasklet?
Worse, what is the previous atom? Imagine some case with a loop:

A
|
B<--.
| |
C---'

What will be the previous atom of B here? It can be either A or C,
but their return values can be different and incompatible, so what
flag should B set?

> +/*
> + * Special modifier to 'stop' handling: instead of stopping the
> + * execution of the syslet, the linearly next syslet is executed.
> + * (Normal execution flows along atom->next, and execution stops
> + * if atom->next is NULL or a stop condition becomes true.)
> + *
> + * This is what allows true branches of execution within syslets.
> + */
> +#define SYSLET_SKIP_TO_NEXT_ON_STOP 0x00000080
> +

Might rename this to SYSLET_SKIP_NEXT_ON_STOP too then.

Greetings,

Indan



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 02/11] syslets: add syslet.h include file, user API/ABI definitions [ In reply to ]
* Indan Zupancic <indan@nul.nu> wrote:

> > + * Execution control: conditions upon the return code
> > + * of the previous syslet atom. 'Stop' means syslet
> > + * execution is stopped and the atom is put into the
> > + * completion ring:
> > + */
> > +#define SYSLET_STOP_ON_NONZERO 0x00000008
> > +#define SYSLET_STOP_ON_ZERO 0x00000010
> > +#define SYSLET_STOP_ON_NEGATIVE 0x00000020
> > +#define SYSLET_STOP_ON_NON_POSITIVE 0x00000040
>
> This is confusing. Why the return code of the previous syslet atom?
> Wouldn't it be more clear if the flag was for the current tasklet?
> Worse, what is the previous atom? [...]

the previously executed atom. (I have fixed up the comment in my tree to
say that.)

> [...] Imagine some case with a loop:
>
> A
> |
> B<--.
> | |
> C---'
>
> What will be the previous atom of B here? It can be either A or C, but
> their return values can be different and incompatible, so what flag
> should B set?

previous here is the previously executed atom, which is always a
specific atom. Think of atoms as 'instructions', and these condition
flags as the 'CPU flags' like 'zero' 'carry' 'sign', etc. Syslets can be
thought of as streams of simplified instructions.

> > +/*
> > + * Special modifier to 'stop' handling: instead of stopping the
> > + * execution of the syslet, the linearly next syslet is executed.
> > + * (Normal execution flows along atom->next, and execution stops
> > + * if atom->next is NULL or a stop condition becomes true.)
> > + *
> > + * This is what allows true branches of execution within syslets.
> > + */
> > +#define SYSLET_SKIP_TO_NEXT_ON_STOP 0x00000080
> > +
>
> Might rename this to SYSLET_SKIP_NEXT_ON_STOP too then.

but that's not what it does. It really 'skips to the next one on a stop
event'. I.e. if you have three consecutive atoms (consecutive in linear
memory):

atom1 returns 0
atom2 has SYSLET_STOP_ON_ZERO|SYSLET_SKIP_NEXT_ON_STOP set
atom3

then after atom1 returns 0, the SYSLET_STOP_ON_ZERO condition is
recognized as a 'stop' event - but due to the SYSLET_SKIP_NEXT_ON_STOP
flag execution does not stop (i.e. we do not return to user-space or
complete the syslet), but we continue execution at atom3.

this flag basically avoids having to add an atom->else pointer and keeps
the data structure more compressed. Two-way branches are sufficiently
rare, so i wanted to avoid the atom->else pointer.

Ingo
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 02/11] syslets: add syslet.h include file, user API/ABI definitions [ In reply to ]
On Tue, February 13, 2007 22:43, Ingo Molnar wrote:
> * Indan Zupancic <indan@nul.nu> wrote:
>> A
>> |
>> B<--.
>> | |
>> C---'
>>
>> What will be the previous atom of B here? It can be either A or C, but
>> their return values can be different and incompatible, so what flag
>> should B set?
>
> previous here is the previously executed atom, which is always a
> specific atom. Think of atoms as 'instructions', and these condition
> flags as the 'CPU flags' like 'zero' 'carry' 'sign', etc. Syslets can be
> thought of as streams of simplified instructions.

In the diagram above the previously executed atom, when handling atom B,
can be either atom A or atom C. So B doesn't know what kind of return value
to expect, because it depends on the previous atom's kind of syscall, and
not on B's return type. So I think you would want to move those return value
flags one atom earlier, in this case to A and C. So each atom will have a
flag telling what to to depending on its own return value.

>> > +/*
>> > + * Special modifier to 'stop' handling: instead of stopping the
>> > + * execution of the syslet, the linearly next syslet is executed.
>> > + * (Normal execution flows along atom->next, and execution stops
>> > + * if atom->next is NULL or a stop condition becomes true.)
>> > + *
>> > + * This is what allows true branches of execution within syslets.
>> > + */
>> > +#define SYSLET_SKIP_TO_NEXT_ON_STOP 0x00000080
>> > +
>>
>> Might rename this to SYSLET_SKIP_NEXT_ON_STOP too then.
>
> but that's not what it does. It really 'skips to the next one on a stop
> event'. I.e. if you have three consecutive atoms (consecutive in linear
> memory):
>
> atom1 returns 0
> atom2 has SYSLET_STOP_ON_ZERO|SYSLET_SKIP_NEXT_ON_STOP set
> atom3
>
> then after atom1 returns 0, the SYSLET_STOP_ON_ZERO condition is
> recognized as a 'stop' event - but due to the SYSLET_SKIP_NEXT_ON_STOP
> flag execution does not stop (i.e. we do not return to user-space or
> complete the syslet), but we continue execution at atom3.
>
> this flag basically avoids having to add an atom->else pointer and keeps
> the data structure more compressed. Two-way branches are sufficiently
> rare, so i wanted to avoid the atom->else pointer.

The flags are smart, they're just at the wrong place I think.

In your example, if atom3 has a 'next' pointing to atom2, atom2 wouldn't
know which return value it's checking: The one of atom1, or the one of
atom3? You're spreading syscall specific knowledge over multiple atoms
while that isn't necessary.

What I propose:

atom1 returns 0, has SYSLET_STOP_ON_ZERO|SYSLET_SKIP_NEXT_ON_STOP set
atom2
atom3

(You've already used my SYSLET_SKIP_NEXT_ON_STOP instead of
SYSLET_SKIP_TO_NEXT_ON_STOP. ;-)

Perhaps it's even more clear when splitting that SYSLET_STOP_* into a
SYSLET_STOP flag, and specific SYSLET_IF_* flags. Either that, or go
all the way and introduce seperate SYSLET_SKIP_NEXT_ON_*.

atom1 returns 0, has SYSLET_SKIP_NEXT|SYSLET_IF_ZERO set
atom2
atom3

Greetings,

Indan


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 02/11] syslets: add syslet.h include file, user API/ABI definitions [ In reply to ]
* Indan Zupancic <indan@nul.nu> wrote:

> What I propose:
>
> atom1 returns 0, has SYSLET_STOP_ON_ZERO|SYSLET_SKIP_NEXT_ON_STOP set
> atom2
> atom3
>
> (You've already used my SYSLET_SKIP_NEXT_ON_STOP instead of
> SYSLET_SKIP_TO_NEXT_ON_STOP. ;-)

doh. Yes. I noticed and implemented this yesterday and it's in the
submitted syslet code - but i guess i was too tired to remember my own
code - so i added the wrong comments :-/ If you look at the sample
user-space code:

init_atom(req, &req->open_file, __NR_sys_open,
&req->filename_p, &O_RDONLY_var, NULL, NULL, NULL, NULL,
&req->fd, SYSLET_STOP_ON_NEGATIVE, &req->read_file);

the 'STOP_ON_NEGATIVE' acts on that particular atom.

this indeed cleaned up things quite a bit and made the user-space syslet
code alot more straightforward. A return value can still be recovered
and examined (with a different condition and a different jump target)
arbitrary number of times via ret_ptr and via sys_umem_add().

Ingo
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 02/11] syslets: add syslet.h include file, user API/ABI definitions [ In reply to ]
Ingo Molnar writes:

> add include/linux/syslet.h which contains the user-space API/ABI
> declarations. Add the new header to include/linux/Kbuild as well.

> +struct syslet_uatom {
> + unsigned long flags;
> + unsigned long nr;
> + long __user *ret_ptr;
> + struct syslet_uatom __user *next;
> + unsigned long __user *arg_ptr[6];
> + /*
> + * User-space can put anything in here, kernel will not
> + * touch it:
> + */
> + void __user *private;
> +};

This structure, with its unsigned longs and pointers, is going to
create enormous headaches for 32-bit processes on 64-bit machines as
far as I can see---and on ppc64 machines, almost all processes are
32-bit, since there is no inherent speed penalty for running in 32-bit
mode, and some space savings.

Have you thought about how you will handle compatibility for 32-bit
processes? The issue will arise for x86_64 and ia64 (among others)
too, I would think.

Paul.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/