From: Turns off syscall emulation patch for ptrace (SYSEMU) on. SYSEMU is a performance-patch introduced by Laurent Vivier. It changes behaviour of ptrace() and helps reducing host context switch rate. To make it working, you need a kernel patch for your host, too. See http://perso.wanadoo.fr/laurent.vivier/UML/ for further information. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton --- 25-akpm/arch/um/kernel/process.c | 35 ++++++++++++++++++++++ 25-akpm/arch/um/kernel/skas/include/ptrace-skas.h | 7 ++++ 25-akpm/arch/um/kernel/skas/process.c | 22 +++++++++++++ 3 files changed, 64 insertions(+) diff -puN arch/um/kernel/process.c~uml-use-ptrace_scemu-the-so-called-sysemu-to-reduce-syscall-cost arch/um/kernel/process.c --- 25/arch/um/kernel/process.c~uml-use-ptrace_scemu-the-so-called-sysemu-to-reduce-syscall-cost 2004-07-05 16:00:44.317283200 -0700 +++ 25-akpm/arch/um/kernel/process.c 2004-07-05 16:00:44.324282136 -0700 @@ -19,6 +19,7 @@ #include #include #include +#include #include "user_util.h" #include "kern_util.h" #include "user.h" @@ -227,6 +228,40 @@ void __init check_ptrace(void) } stop_ptraced_child(pid, stack, 0); printk("OK\n"); + +#ifdef PTRACE_SYSEMU + printk("Checking syscall emulation patch for ptrace..."); + use_sysemu = 0; + pid = start_ptraced_child(&stack); + if(ptrace(PTRACE_SYSEMU, pid, 0, 0) >= 0) { + struct user_regs_struct regs; + + if (waitpid(pid, &status, WUNTRACED) < 0) + panic("check_ptrace : wait failed, errno = %d", errno); + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) + panic("check_ptrace : expected SIGTRAP, " + "got status = %d", status); + + if (ptrace(PTRACE_GETREGS, pid, 0, ®s) < 0) + panic("check_ptrace : failed to read child " + "registers, errno = %d", errno); + regs.orig_eax = pid; + if (ptrace(PTRACE_SETREGS, pid, 0, ®s) < 0) + panic("check_ptrace : failed to modify child " + "registers, errno = %d", errno); + + stop_ptraced_child(pid, stack, 0); + + printk("OK\n"); + use_sysemu = 1; + } + else + { + printk("missing\n"); + stop_ptraced_child(pid, stack, 1); + } + +# endif /* PTRACE_SYSEMU */ } int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) diff -puN arch/um/kernel/skas/include/ptrace-skas.h~uml-use-ptrace_scemu-the-so-called-sysemu-to-reduce-syscall-cost arch/um/kernel/skas/include/ptrace-skas.h --- 25/arch/um/kernel/skas/include/ptrace-skas.h~uml-use-ptrace_scemu-the-so-called-sysemu-to-reduce-syscall-cost 2004-07-05 16:00:44.318283048 -0700 +++ 25-akpm/arch/um/kernel/skas/include/ptrace-skas.h 2004-07-05 16:00:44.324282136 -0700 @@ -10,6 +10,13 @@ #ifdef UML_CONFIG_MODE_SKAS +/* syscall emulation path in ptrace */ + +#ifndef PTRACE_SYSEMU +#define PTRACE_SYSEMU 31 +#endif +extern int use_sysemu; + #include "skas_ptregs.h" #define HOST_FRAME_SIZE 17 diff -puN arch/um/kernel/skas/process.c~uml-use-ptrace_scemu-the-so-called-sysemu-to-reduce-syscall-cost arch/um/kernel/skas/process.c --- 25/arch/um/kernel/skas/process.c~uml-use-ptrace_scemu-the-so-called-sysemu-to-reduce-syscall-cost 2004-07-05 16:00:44.320282744 -0700 +++ 25-akpm/arch/um/kernel/skas/process.c 2004-07-05 16:00:44.325281984 -0700 @@ -28,6 +28,10 @@ #include "chan_user.h" #include "signal_user.h" +#ifdef PTRACE_SYSEMU +int use_sysemu = 0; +#endif + int is_skas_winch(int pid, int fd, void *data) { if(pid != getpid()) @@ -68,6 +72,10 @@ static void handle_trap(int pid, union u return; } +#ifdef PTRACE_SYSEMU + if (!use_sysemu) + { +#endif err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); if(err < 0) panic("handle_trap - nullifying syscall failed errno = %d\n", @@ -82,6 +90,9 @@ static void handle_trap(int pid, union u if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) panic("handle_trap - failed to wait at end of syscall, " "errno = %d, status = %d\n", errno, status); +#ifdef PTRACE_SYSEMU + } +#endif handle_syscall(regs); } @@ -139,6 +150,11 @@ void userspace(union uml_pt_regs *regs) restore_registers(regs); +#ifdef PTRACE_SYSEMU + if (use_sysemu) + err = ptrace(PTRACE_SYSEMU, pid, 0, 0); + else +#endif err = ptrace(PTRACE_SYSCALL, pid, 0, 0); if(err) panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", @@ -177,6 +193,12 @@ void userspace(union uml_pt_regs *regs) restore_registers(regs); +#ifdef PTRACE_SYSEMU + if (use_sysemu) + op = singlestepping_skas() ? PTRACE_SINGLESTEP : + PTRACE_SYSEMU; + else +#endif op = singlestepping_skas() ? PTRACE_SINGLESTEP : PTRACE_SYSCALL; err = ptrace(op, pid, 0, 0); _