aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephane Eranian <eranian@hpl.hp.com>2006-07-09 21:12:39 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-09 21:47:12 -0400
commitb3cf257623fabd8f1ee6700a6d328cc1c5da5a1d (patch)
tree28b98f21dd108864d2edc11d179cb48c118b2cf8
parent09075ef0fd585fb093bb9a6cd1240272114f89cf (diff)
[PATCH] i386: use thread_info flags for debug regs and IO bitmaps
Use thread info flags to track use of debug registers and IO bitmaps. - add TIF_DEBUG to track when debug registers are active - add TIF_IO_BITMAP to track when I/O bitmap is used - modify __switch_to() to use the new TIF flags Performance tested on Pentium II, ten runs of LMbench context switch benchmark (smaller is better:) before after avg 3.65 3.39 min 3.55 3.33 Signed-off-by: Stephane Eranian <eranian@hpl.hp.com> Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Acked-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/i386/kernel/ioport.c1
-rw-r--r--arch/i386/kernel/process.c50
-rw-r--r--arch/i386/kernel/ptrace.c5
-rw-r--r--include/asm-i386/thread_info.h7
4 files changed, 41 insertions, 22 deletions
diff --git a/arch/i386/kernel/ioport.c b/arch/i386/kernel/ioport.c
index 79026f026b85..498e8bc197d5 100644
--- a/arch/i386/kernel/ioport.c
+++ b/arch/i386/kernel/ioport.c
@@ -79,6 +79,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
79 79
80 memset(bitmap, 0xff, IO_BITMAP_BYTES); 80 memset(bitmap, 0xff, IO_BITMAP_BYTES);
81 t->io_bitmap_ptr = bitmap; 81 t->io_bitmap_ptr = bitmap;
82 set_thread_flag(TIF_IO_BITMAP);
82 } 83 }
83 84
84 /* 85 /*
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 94e2c87edeaa..923bb292f47f 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -359,16 +359,16 @@ EXPORT_SYMBOL(kernel_thread);
359 */ 359 */
360void exit_thread(void) 360void exit_thread(void)
361{ 361{
362 struct task_struct *tsk = current;
363 struct thread_struct *t = &tsk->thread;
364
365 /* The process may have allocated an io port bitmap... nuke it. */ 362 /* The process may have allocated an io port bitmap... nuke it. */
366 if (unlikely(NULL != t->io_bitmap_ptr)) { 363 if (unlikely(test_thread_flag(TIF_IO_BITMAP))) {
364 struct task_struct *tsk = current;
365 struct thread_struct *t = &tsk->thread;
367 int cpu = get_cpu(); 366 int cpu = get_cpu();
368 struct tss_struct *tss = &per_cpu(init_tss, cpu); 367 struct tss_struct *tss = &per_cpu(init_tss, cpu);
369 368
370 kfree(t->io_bitmap_ptr); 369 kfree(t->io_bitmap_ptr);
371 t->io_bitmap_ptr = NULL; 370 t->io_bitmap_ptr = NULL;
371 clear_thread_flag(TIF_IO_BITMAP);
372 /* 372 /*
373 * Careful, clear this in the TSS too: 373 * Careful, clear this in the TSS too:
374 */ 374 */
@@ -387,6 +387,7 @@ void flush_thread(void)
387 387
388 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8); 388 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
389 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); 389 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
390 clear_tsk_thread_flag(tsk, TIF_DEBUG);
390 /* 391 /*
391 * Forget coprocessor state.. 392 * Forget coprocessor state..
392 */ 393 */
@@ -431,7 +432,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
431 savesegment(gs,p->thread.gs); 432 savesegment(gs,p->thread.gs);
432 433
433 tsk = current; 434 tsk = current;
434 if (unlikely(NULL != tsk->thread.io_bitmap_ptr)) { 435 if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
435 p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); 436 p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
436 if (!p->thread.io_bitmap_ptr) { 437 if (!p->thread.io_bitmap_ptr) {
437 p->thread.io_bitmap_max = 0; 438 p->thread.io_bitmap_max = 0;
@@ -439,6 +440,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
439 } 440 }
440 memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr, 441 memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr,
441 IO_BITMAP_BYTES); 442 IO_BITMAP_BYTES);
443 set_tsk_thread_flag(p, TIF_IO_BITMAP);
442 } 444 }
443 445
444 /* 446 /*
@@ -533,10 +535,24 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
533 return 1; 535 return 1;
534} 536}
535 537
536static inline void 538static noinline void __switch_to_xtra(struct task_struct *next_p,
537handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss) 539 struct tss_struct *tss)
538{ 540{
539 if (!next->io_bitmap_ptr) { 541 struct thread_struct *next;
542
543 next = &next_p->thread;
544
545 if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
546 set_debugreg(next->debugreg[0], 0);
547 set_debugreg(next->debugreg[1], 1);
548 set_debugreg(next->debugreg[2], 2);
549 set_debugreg(next->debugreg[3], 3);
550 /* no 4 and 5 */
551 set_debugreg(next->debugreg[6], 6);
552 set_debugreg(next->debugreg[7], 7);
553 }
554
555 if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
540 /* 556 /*
541 * Disable the bitmap via an invalid offset. We still cache 557 * Disable the bitmap via an invalid offset. We still cache
542 * the previous bitmap owner and the IO bitmap contents: 558 * the previous bitmap owner and the IO bitmap contents:
@@ -544,6 +560,7 @@ handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss)
544 tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET; 560 tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
545 return; 561 return;
546 } 562 }
563
547 if (likely(next == tss->io_bitmap_owner)) { 564 if (likely(next == tss->io_bitmap_owner)) {
548 /* 565 /*
549 * Previous owner of the bitmap (hence the bitmap content) 566 * Previous owner of the bitmap (hence the bitmap content)
@@ -671,20 +688,11 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
671 set_iopl_mask(next->iopl); 688 set_iopl_mask(next->iopl);
672 689
673 /* 690 /*
674 * Now maybe reload the debug registers 691 * Now maybe handle debug registers and/or IO bitmaps
675 */ 692 */
676 if (unlikely(next->debugreg[7])) { 693 if (unlikely((task_thread_info(next_p)->flags & _TIF_WORK_CTXSW))
677 set_debugreg(next->debugreg[0], 0); 694 || test_tsk_thread_flag(prev_p, TIF_IO_BITMAP))
678 set_debugreg(next->debugreg[1], 1); 695 __switch_to_xtra(next_p, tss);
679 set_debugreg(next->debugreg[2], 2);
680 set_debugreg(next->debugreg[3], 3);
681 /* no 4 and 5 */
682 set_debugreg(next->debugreg[6], 6);
683 set_debugreg(next->debugreg[7], 7);
684 }
685
686 if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr))
687 handle_io_bitmap(next, tss);
688 696
689 disable_tsc(prev_p, next_p); 697 disable_tsc(prev_p, next_p);
690 698
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index fd7eaf7866e0..d3db03f4085d 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -468,8 +468,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
468 for(i=0; i<4; i++) 468 for(i=0; i<4; i++)
469 if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1) 469 if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
470 goto out_tsk; 470 goto out_tsk;
471 if (data)
472 set_tsk_thread_flag(child, TIF_DEBUG);
473 else
474 clear_tsk_thread_flag(child, TIF_DEBUG);
471 } 475 }
472
473 addr -= (long) &dummy->u_debugreg; 476 addr -= (long) &dummy->u_debugreg;
474 addr = addr >> 2; 477 addr = addr >> 2;
475 child->thread.debugreg[addr] = data; 478 child->thread.debugreg[addr] = data;
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index 2833fa2c0dd0..54d6d7aea938 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -140,6 +140,8 @@ static inline struct thread_info *current_thread_info(void)
140#define TIF_SECCOMP 8 /* secure computing */ 140#define TIF_SECCOMP 8 /* secure computing */
141#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ 141#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
142#define TIF_MEMDIE 16 142#define TIF_MEMDIE 16
143#define TIF_DEBUG 17 /* uses debug registers */
144#define TIF_IO_BITMAP 18 /* uses I/O bitmap */
143 145
144#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 146#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
145#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) 147#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
@@ -151,6 +153,8 @@ static inline struct thread_info *current_thread_info(void)
151#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 153#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
152#define _TIF_SECCOMP (1<<TIF_SECCOMP) 154#define _TIF_SECCOMP (1<<TIF_SECCOMP)
153#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) 155#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
156#define _TIF_DEBUG (1<<TIF_DEBUG)
157#define _TIF_IO_BITMAP (1<<TIF_IO_BITMAP)
154 158
155/* work to do on interrupt/exception return */ 159/* work to do on interrupt/exception return */
156#define _TIF_WORK_MASK \ 160#define _TIF_WORK_MASK \
@@ -159,6 +163,9 @@ static inline struct thread_info *current_thread_info(void)
159/* work to do on any return to u-space */ 163/* work to do on any return to u-space */
160#define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP) 164#define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP)
161 165
166/* flags to check in __switch_to() */
167#define _TIF_WORK_CTXSW (_TIF_DEBUG|_TIF_IO_BITMAP)
168
162/* 169/*
163 * Thread-synchronous status. 170 * Thread-synchronous status.
164 * 171 *