diff options
author | Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> | 2006-03-31 05:30:21 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-31 15:18:52 -0500 |
commit | 972410b0232e97609fcefc8e408fe3037fcd607b (patch) | |
tree | 2de18ed5d823dc7e24c0171f720f6354a9cd57e4 /arch/um | |
parent | fbdf2161552a2065047e5df2dbf9ebf69d66a0e9 (diff) |
[PATCH] uml: clean arch_switch usage
Call arch_switch also in switch_to_skas, even if it's, for now, a no-op for
that case (and mark this in the comment); this will change soon.
Also, arch_switch for TT mode is actually useless when the PT proxy (a
complicate debugging instrumentation for TT mode) is not enabled. In fact, it
only calls update_debugregs, which checks debugregs_seq against seq (to check
if the registers are up-to-date - seq here means a "version number" of the
registers).
If the ptrace proxy is not enabled, debugregs_seq always stays 0 and
update_debugregs will be a no-op. So, optimize this out (the compiler can't
do it).
Also, I've been disappointed by the fact that it would make a lot of sense if,
after calling a successful
update_debugregs(current->thread.arch.debugregs_seq),
current->thread.arch.debugregs_seq were updated with the new debugregs_seq.
But this is not done. Is this a bug or a feature? For all purposes, it seems
a bug (otherwise the whole mechanism does not make sense, which is also a
possibility to check), which causes some performance only problems (not
correctness), since we write_debugregs when not needed.
Also, as suggested by Jeff, remove a redundant enabling of SIGVTALRM,
comprised in the subsequent local_irq_enable(). I'm just a bit dubious if
ordering matters there...
Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Acked-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/include/kern_util.h | 6 | ||||
-rw-r--r-- | arch/um/include/sysdep-i386/ptrace.h | 5 | ||||
-rw-r--r-- | arch/um/kernel/skas/process_kern.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/tt/process_kern.c | 10 | ||||
-rw-r--r-- | arch/um/sys-i386/ptrace.c | 8 | ||||
-rw-r--r-- | arch/um/sys-i386/ptrace_user.c | 10 |
6 files changed, 35 insertions, 6 deletions
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 07176d92e1c9..42557130a408 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h | |||
@@ -116,7 +116,11 @@ extern void *get_current(void); | |||
116 | extern struct task_struct *get_task(int pid, int require); | 116 | extern struct task_struct *get_task(int pid, int require); |
117 | extern void machine_halt(void); | 117 | extern void machine_halt(void); |
118 | extern int is_syscall(unsigned long addr); | 118 | extern int is_syscall(unsigned long addr); |
119 | extern void arch_switch(void); | 119 | |
120 | extern void arch_switch_to_tt(struct task_struct *from, struct task_struct *to); | ||
121 | |||
122 | extern void arch_switch_to_skas(struct task_struct *from, struct task_struct *to); | ||
123 | |||
120 | extern void free_irq(unsigned int, void *); | 124 | extern void free_irq(unsigned int, void *); |
121 | extern int cpu(void); | 125 | extern int cpu(void); |
122 | 126 | ||
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h index c8ee9559f3ab..6670cc992ecb 100644 --- a/arch/um/include/sysdep-i386/ptrace.h +++ b/arch/um/include/sysdep-i386/ptrace.h | |||
@@ -14,7 +14,12 @@ | |||
14 | #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) | 14 | #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) |
15 | #define MAX_REG_OFFSET (UM_FRAME_SIZE) | 15 | #define MAX_REG_OFFSET (UM_FRAME_SIZE) |
16 | 16 | ||
17 | #ifdef UML_CONFIG_PT_PROXY | ||
17 | extern void update_debugregs(int seq); | 18 | extern void update_debugregs(int seq); |
19 | #else | ||
20 | static inline void update_debugregs(int seq) {} | ||
21 | #endif | ||
22 | |||
18 | 23 | ||
19 | /* syscall emulation path in ptrace */ | 24 | /* syscall emulation path in ptrace */ |
20 | 25 | ||
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index 3f70a2e12f06..14360ac17f02 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c | |||
@@ -35,6 +35,8 @@ void switch_to_skas(void *prev, void *next) | |||
35 | switch_threads(&from->thread.mode.skas.switch_buf, | 35 | switch_threads(&from->thread.mode.skas.switch_buf, |
36 | to->thread.mode.skas.switch_buf); | 36 | to->thread.mode.skas.switch_buf); |
37 | 37 | ||
38 | arch_switch_to_skas(current->thread.prev_sched, current); | ||
39 | |||
38 | if(current->pid == 0) | 40 | if(current->pid == 0) |
39 | switch_timers(1); | 41 | switch_timers(1); |
40 | } | 42 | } |
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 295c1ac817b3..a9c1443fc548 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c | |||
@@ -51,6 +51,13 @@ void switch_to_tt(void *prev, void *next) | |||
51 | 51 | ||
52 | c = 0; | 52 | c = 0; |
53 | 53 | ||
54 | /* Notice that here we "up" the semaphore on which "to" is waiting, and | ||
55 | * below (the read) we wait on this semaphore (which is implemented by | ||
56 | * switch_pipe) and go sleeping. Thus, after that, we have resumed in | ||
57 | * "to", and can't use any more the value of "from" (which is outdated), | ||
58 | * nor the value in "to" (since it was the task which stole us the CPU, | ||
59 | * which we don't care about). */ | ||
60 | |||
54 | err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); | 61 | err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); |
55 | if(err != sizeof(c)) | 62 | if(err != sizeof(c)) |
56 | panic("write of switch_pipe failed, err = %d", -err); | 63 | panic("write of switch_pipe failed, err = %d", -err); |
@@ -77,7 +84,7 @@ void switch_to_tt(void *prev, void *next) | |||
77 | change_sig(SIGALRM, alrm); | 84 | change_sig(SIGALRM, alrm); |
78 | change_sig(SIGPROF, prof); | 85 | change_sig(SIGPROF, prof); |
79 | 86 | ||
80 | arch_switch(); | 87 | arch_switch_to_tt(prev_sched, current); |
81 | 88 | ||
82 | flush_tlb_all(); | 89 | flush_tlb_all(); |
83 | local_irq_restore(flags); | 90 | local_irq_restore(flags); |
@@ -141,7 +148,6 @@ static void new_thread_handler(int sig) | |||
141 | set_cmdline("(kernel thread)"); | 148 | set_cmdline("(kernel thread)"); |
142 | 149 | ||
143 | change_sig(SIGUSR1, 1); | 150 | change_sig(SIGUSR1, 1); |
144 | change_sig(SIGVTALRM, 1); | ||
145 | change_sig(SIGPROF, 1); | 151 | change_sig(SIGPROF, 1); |
146 | local_irq_enable(); | 152 | local_irq_enable(); |
147 | if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf)) | 153 | if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf)) |
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index ff94eded93eb..927fcd955651 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c | |||
@@ -15,9 +15,13 @@ | |||
15 | #include "sysdep/sigcontext.h" | 15 | #include "sysdep/sigcontext.h" |
16 | #include "sysdep/sc.h" | 16 | #include "sysdep/sc.h" |
17 | 17 | ||
18 | void arch_switch(void) | 18 | void arch_switch_to_tt(struct task_struct *from, struct task_struct *to) |
19 | { | ||
20 | update_debugregs(to->thread.arch.debugregs_seq); | ||
21 | } | ||
22 | |||
23 | void arch_switch_to_skas(struct task_struct *from, struct task_struct *to) | ||
19 | { | 24 | { |
20 | update_debugregs(current->thread.arch.debugregs_seq); | ||
21 | } | 25 | } |
22 | 26 | ||
23 | int is_syscall(unsigned long addr) | 27 | int is_syscall(unsigned long addr) |
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c index 7c376c95de50..9f3bd8ed78f5 100644 --- a/arch/um/sys-i386/ptrace_user.c +++ b/arch/um/sys-i386/ptrace_user.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include "sysdep/thread.h" | 14 | #include "sysdep/thread.h" |
15 | #include "user.h" | 15 | #include "user.h" |
16 | #include "os.h" | 16 | #include "os.h" |
17 | #include "uml-config.h" | ||
17 | 18 | ||
18 | int ptrace_getregs(long pid, unsigned long *regs_out) | 19 | int ptrace_getregs(long pid, unsigned long *regs_out) |
19 | { | 20 | { |
@@ -43,6 +44,7 @@ int ptrace_setfpregs(long pid, unsigned long *regs) | |||
43 | return 0; | 44 | return 0; |
44 | } | 45 | } |
45 | 46 | ||
47 | /* All the below stuff is of interest for TT mode only */ | ||
46 | static void write_debugregs(int pid, unsigned long *regs) | 48 | static void write_debugregs(int pid, unsigned long *regs) |
47 | { | 49 | { |
48 | struct user *dummy; | 50 | struct user *dummy; |
@@ -75,7 +77,6 @@ static void read_debugregs(int pid, unsigned long *regs) | |||
75 | 77 | ||
76 | /* Accessed only by the tracing thread */ | 78 | /* Accessed only by the tracing thread */ |
77 | static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 }; | 79 | static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 }; |
78 | static int debugregs_seq = 0; | ||
79 | 80 | ||
80 | void arch_enter_kernel(void *task, int pid) | 81 | void arch_enter_kernel(void *task, int pid) |
81 | { | 82 | { |
@@ -89,6 +90,11 @@ void arch_leave_kernel(void *task, int pid) | |||
89 | write_debugregs(pid, TASK_DEBUGREGS(task)); | 90 | write_debugregs(pid, TASK_DEBUGREGS(task)); |
90 | } | 91 | } |
91 | 92 | ||
93 | #ifdef UML_CONFIG_PT_PROXY | ||
94 | /* Accessed only by the tracing thread */ | ||
95 | static int debugregs_seq; | ||
96 | |||
97 | /* Only called by the ptrace proxy */ | ||
92 | void ptrace_pokeuser(unsigned long addr, unsigned long data) | 98 | void ptrace_pokeuser(unsigned long addr, unsigned long data) |
93 | { | 99 | { |
94 | if((addr < offsetof(struct user, u_debugreg[0])) || | 100 | if((addr < offsetof(struct user, u_debugreg[0])) || |
@@ -109,6 +115,7 @@ static void update_debugregs_cb(void *arg) | |||
109 | write_debugregs(pid, kernel_debugregs); | 115 | write_debugregs(pid, kernel_debugregs); |
110 | } | 116 | } |
111 | 117 | ||
118 | /* Optimized out in its header when not defined */ | ||
112 | void update_debugregs(int seq) | 119 | void update_debugregs(int seq) |
113 | { | 120 | { |
114 | int me; | 121 | int me; |
@@ -118,6 +125,7 @@ void update_debugregs(int seq) | |||
118 | me = os_getpid(); | 125 | me = os_getpid(); |
119 | initial_thread_cb(update_debugregs_cb, &me); | 126 | initial_thread_cb(update_debugregs_cb, &me); |
120 | } | 127 | } |
128 | #endif | ||
121 | 129 | ||
122 | /* | 130 | /* |
123 | * Overrides for Emacs so that we follow Linus's tabbing style. | 131 | * Overrides for Emacs so that we follow Linus's tabbing style. |