Add sha256 and sha512 checksums
[fio.git] / syslet.h
1 #ifndef _LINUX_SYSLET_H
2 #define _LINUX_SYSLET_H
3 /*
4  * The syslet subsystem - asynchronous syscall execution support.
5  *
6  * Started by Ingo Molnar:
7  *
8  *  Copyright (C) 2007 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
9  *
10  * User-space API/ABI definitions:
11  */
12
13 #ifndef __user
14 # define __user
15 #endif
16
17 /*
18  * This is the 'Syslet Atom' - the basic unit of execution
19  * within the syslet framework. A syslet always represents
20  * a single system-call plus its arguments, plus has conditions
21  * attached to it that allows the construction of larger
22  * programs from these atoms. User-space variables can be used
23  * (for example a loop index) via the special sys_umem*() syscalls.
24  *
25  * Arguments are implemented via pointers to arguments. This not
26  * only increases the flexibility of syslet atoms (multiple syslets
27  * can share the same variable for example), but is also an
28  * optimization: copy_uatom() will only fetch syscall parameters
29  * up until the point it meets the first NULL pointer. 50% of all
30  * syscalls have 2 or less parameters (and 90% of all syscalls have
31  * 4 or less parameters).
32  *
33  * [ Note: since the argument array is at the end of the atom, and the
34  *   kernel will not touch any argument beyond the final NULL one, atoms
35  *   might be packed more tightly. (the only special case exception to
36  *   this rule would be SKIP_TO_NEXT_ON_STOP atoms, where the kernel will
37  *   jump a full syslet_uatom number of bytes.) ]
38  */
39 struct syslet_uatom {
40         unsigned long                           flags;
41         unsigned long                           nr;
42         long __user                             *ret_ptr;
43         struct syslet_uatom     __user          *next;
44         unsigned long           __user          *arg_ptr[6];
45         /*
46          * User-space can put anything in here, kernel will not
47          * touch it:
48          */
49         void __user                             *private;
50 };
51
52 /*
53  * Flags to modify/control syslet atom behavior:
54  */
55
56 /*
57  * Immediately queue this syslet asynchronously - do not even
58  * attempt to execute it synchronously in the user context:
59  */
60 #define SYSLET_ASYNC                            0x00000001
61
62 /*
63  * Never queue this syslet asynchronously - even if synchronous
64  * execution causes a context-switching:
65  */
66 #define SYSLET_SYNC                             0x00000002
67
68 /*
69  * Do not queue the syslet in the completion ring when done.
70  *
71  * ( the default is that the final atom of a syslet is queued
72  *   in the completion ring. )
73  *
74  * Some syscalls generate implicit completion events of their
75  * own.
76  */
77 #define SYSLET_NO_COMPLETE                      0x00000004
78
79 /*
80  * Execution control: conditions upon the return code
81  * of the just executed syslet atom. 'Stop' means syslet
82  * execution is stopped and the atom is put into the
83  * completion ring:
84  */
85 #define SYSLET_STOP_ON_NONZERO                  0x00000008
86 #define SYSLET_STOP_ON_ZERO                     0x00000010
87 #define SYSLET_STOP_ON_NEGATIVE                 0x00000020
88 #define SYSLET_STOP_ON_NON_POSITIVE             0x00000040
89
90 #define SYSLET_STOP_MASK                                \
91         (       SYSLET_STOP_ON_NONZERO          |       \
92                 SYSLET_STOP_ON_ZERO             |       \
93                 SYSLET_STOP_ON_NEGATIVE         |       \
94                 SYSLET_STOP_ON_NON_POSITIVE             )
95
96 /*
97  * Special modifier to 'stop' handling: instead of stopping the
98  * execution of the syslet, the linearly next syslet is executed.
99  * (Normal execution flows along atom->next, and execution stops
100  *  if atom->next is NULL or a stop condition becomes true.)
101  *
102  * This is what allows true branches of execution within syslets.
103  */
104 #define SYSLET_SKIP_TO_NEXT_ON_STOP             0x00000080
105
106 /*
107  * This is the (per-user-context) descriptor of the async completion
108  * ring. This gets passed in to sys_async_exec():
109  */
110 struct async_head_user {
111         /*
112          * Current completion ring index - managed by the kernel:
113          */
114         unsigned long                           kernel_ring_idx;
115         /*
116          * User-side ring index:
117          */
118         unsigned long                           user_ring_idx;
119
120         /*
121          * Ring of pointers to completed async syslets (i.e. syslets that
122          * generated a cachemiss and went async, returning -EASYNCSYSLET
123          * to the user context by sys_async_exec()) are queued here.
124          * Syslets that were executed synchronously (cached) are not
125          * queued here.
126          *
127          * Note: the final atom that generated the exit condition is
128          * queued here. Normally this would be the last atom of a syslet.
129          */
130         struct syslet_uatom __user              **completion_ring;
131
132         /*
133          * Ring size in bytes:
134          */
135         unsigned long                           ring_size_bytes;
136
137         /*
138          * The head task can become a cachemiss thread later on
139          * too, if it blocks - so it needs its separate thread
140          * stack and start address too:
141          */
142         unsigned long                           head_stack;
143         unsigned long                           head_eip;
144
145         /*
146          * Newly started async kernel threads will take their
147          * user stack and user start address from here. User-space
148          * code has to check for new_thread_stack going to NULL
149          * and has to refill it with a new stack if that happens.
150          */
151         unsigned long                           new_thread_stack;
152         unsigned long                           new_thread_eip;
153 };
154
155 #endif