X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=syslet.h;h=16f81d2f52ec446c447abaf0a3ad9294a3dde9a5;hp=d89abd440822f0fcf74c9cb7c3cb3c9670749a02;hb=2ba1c290d09af6d630d84a58b97b8032f73bc2ce;hpb=ad18c1ecc367c55e4d10acb05790be2c946053e2 diff --git a/syslet.h b/syslet.h index d89abd44..16f81d2f 100644 --- a/syslet.h +++ b/syslet.h @@ -1,140 +1,50 @@ -#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 - * - * User-space API/ABI definitions: - */ +#ifndef _SYSLET_H_ +#define _SYSLET_H_ -#ifndef __user -# define __user -#endif +#include "kcompat.h" -/* - * 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; +struct syslet_frame { + u64 ip; + u64 sp; }; -/* - * 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 +struct syslet_args { + u64 ring_ptr; + u64 caller_data; + struct syslet_frame frame; +}; -/* - * 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 +struct syslet_completion { + u64 status; + u64 caller_data; +}; -/* - * 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 +struct syslet_ring { + u32 kernel_head; + u32 user_tail; + u32 elements; + u32 wait_group; + struct syslet_completion comp[0]; +}; -#define SYSLET_STOP_MASK \ - ( SYSLET_STOP_ON_NONZERO | \ - SYSLET_STOP_ON_ZERO | \ - SYSLET_STOP_ON_NEGATIVE | \ - SYSLET_STOP_ON_NON_POSITIVE ) +#ifdef __x86_64__ +#define __NR_syslet_ring_wait 287 +#elif defined __i386__ +#define __NR_syslet_ring_wait 326 +#endif -/* - * 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 +#define ESYSLETPENDING 132 -/* - * 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; +typedef void (*syslet_return_func_t)(void); - /* - * 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; -}; +void fill_syslet_args(struct syslet_args *args, struct syslet_ring *ring, + uint64_t caller_data, syslet_return_func_t func, + void *stack) +{ + args->ring_ptr = (u64)(unsigned long)ring; + args->caller_data = caller_data; + args->frame.ip = (u64)(unsigned long)func; + args->frame.sp = (u64)(unsigned long)stack; +} #endif