Commit f3406c52 authored by Paolo \'Blaisorblade\' Giarrusso's avatar Paolo \'Blaisorblade\' Giarrusso Committed by Linus Torvalds

[PATCH] uml: Use PTRACE_SCEMU (the so-called SYSEMU) to reduce syscall cost.

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: default avatarPaolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
Cc: Jeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b7d06f1b
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <asm/sigcontext.h> #include <asm/sigcontext.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/user.h>
#include "user_util.h" #include "user_util.h"
#include "kern_util.h" #include "kern_util.h"
#include "user.h" #include "user.h"
...@@ -227,6 +228,40 @@ void __init check_ptrace(void) ...@@ -227,6 +228,40 @@ void __init check_ptrace(void)
} }
stop_ptraced_child(pid, stack, 0); stop_ptraced_child(pid, stack, 0);
printk("OK\n"); 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, &regs) < 0)
panic("check_ptrace : failed to read child "
"registers, errno = %d", errno);
regs.orig_eax = pid;
if (ptrace(PTRACE_SETREGS, pid, 0, &regs) < 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) int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
......
...@@ -10,6 +10,13 @@ ...@@ -10,6 +10,13 @@
#ifdef UML_CONFIG_MODE_SKAS #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" #include "skas_ptregs.h"
#define HOST_FRAME_SIZE 17 #define HOST_FRAME_SIZE 17
......
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
#include "chan_user.h" #include "chan_user.h"
#include "signal_user.h" #include "signal_user.h"
#ifdef PTRACE_SYSEMU
int use_sysemu = 0;
#endif
int is_skas_winch(int pid, int fd, void *data) int is_skas_winch(int pid, int fd, void *data)
{ {
if(pid != getpid()) if(pid != getpid())
...@@ -68,6 +72,10 @@ static void handle_trap(int pid, union uml_pt_regs *regs) ...@@ -68,6 +72,10 @@ static void handle_trap(int pid, union uml_pt_regs *regs)
return; return;
} }
#ifdef PTRACE_SYSEMU
if (!use_sysemu)
{
#endif
err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
if(err < 0) if(err < 0)
panic("handle_trap - nullifying syscall failed errno = %d\n", panic("handle_trap - nullifying syscall failed errno = %d\n",
...@@ -82,6 +90,9 @@ static void handle_trap(int pid, union uml_pt_regs *regs) ...@@ -82,6 +90,9 @@ static void handle_trap(int pid, union uml_pt_regs *regs)
if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
panic("handle_trap - failed to wait at end of syscall, " panic("handle_trap - failed to wait at end of syscall, "
"errno = %d, status = %d\n", errno, status); "errno = %d, status = %d\n", errno, status);
#ifdef PTRACE_SYSEMU
}
#endif
handle_syscall(regs); handle_syscall(regs);
} }
...@@ -139,6 +150,11 @@ void userspace(union uml_pt_regs *regs) ...@@ -139,6 +150,11 @@ void userspace(union uml_pt_regs *regs)
restore_registers(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); err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
if(err) if(err)
panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", panic("userspace - PTRACE_SYSCALL failed, errno = %d\n",
...@@ -177,6 +193,12 @@ void userspace(union uml_pt_regs *regs) ...@@ -177,6 +193,12 @@ void userspace(union uml_pt_regs *regs)
restore_registers(regs); restore_registers(regs);
#ifdef PTRACE_SYSEMU
if (use_sysemu)
op = singlestepping_skas() ? PTRACE_SINGLESTEP :
PTRACE_SYSEMU;
else
#endif
op = singlestepping_skas() ? PTRACE_SINGLESTEP : op = singlestepping_skas() ? PTRACE_SINGLESTEP :
PTRACE_SYSCALL; PTRACE_SYSCALL;
err = ptrace(op, pid, 0, 0); err = ptrace(op, pid, 0, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment