Messages in this thread | | | Date | Mon, 23 Aug 2004 21:53:14 -0400 | From | Brian Gerst <> | Subject | Re: [patch] lazy TSS's I/O bitmap copy ... |
| |
Davide Libenzi wrote: > The following patch implements a lazy I/O bitmap copy for the i386 > architecture. With I/O bitmaps now reaching considerable sizes, if the > switched task does not perform any I/O operation, we can save the copy > altogether. In my box X is working fine with the following patch, even if > more test would be required. > > > Signed-off-by: Davide Libenzi <davidel@xmailserver.org> > > > - Davide > > > > arch/i386/kernel/process.c | 33 +++++++++++---------------------- > arch/i386/kernel/traps.c | 20 ++++++++++++++++++++ > include/asm-i386/processor.h | 1 + > 3 files changed, 32 insertions(+), 22 deletions(-) > > > > Index: arch/i386/kernel/process.c > =================================================================== > RCS file: /usr/src/bkcvs/linux-2.5/arch/i386/kernel/process.c,v > retrieving revision 1.82 > diff -u -r1.82 process.c > --- a/arch/i386/kernel/process.c 14 Jul 2004 16:27:05 -0000 1.82 > +++ b/arch/i386/kernel/process.c 23 Aug 2004 19:33:12 -0000 > @@ -551,28 +551,17 @@ > loaddebug(next, 7); > } > > - if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) { > - if (next->io_bitmap_ptr) { > - /* > - * 4 cachelines copy ... not good, but not that > - * bad either. Anyone got something better? > - * This only affects processes which use ioperm(). > - * [Putting the TSSs into 4k-tlb mapped regions > - * and playing VM tricks to switch the IO bitmap > - * is not really acceptable.] > - */ > - memcpy(tss->io_bitmap, next->io_bitmap_ptr, > - IO_BITMAP_BYTES); > - tss->io_bitmap_base = IO_BITMAP_OFFSET; > - } else > - /* > - * a bitmap offset pointing outside of the TSS limit > - * causes a nicely controllable SIGSEGV if a process > - * tries to use a port IO instruction. The first > - * sys_ioperm() call sets up the bitmap properly. > - */ > - tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET; > - } > + /* > + * Lazy TSS's I/O bitmap copy. We set an invalid offset here and > + * we let the task to get a GPF in case an I/O instruction is performed. > + * The handler of the GPF will verify that the faulting task has a valid > + * I/O bitmap and, it true, does the real copy and restart the instruction. > + * This will save us for redoundant copies when the currently switched task > + * does not perform any I/O during its timeslice. > + */ > + tss->io_bitmap_base = next->io_bitmap_ptr ? INVALID_IO_BITMAP_OFFSET_LAZY: > + INVALID_IO_BITMAP_OFFSET; > + > return prev_p; > } > > Index: arch/i386/kernel/traps.c > =================================================================== > RCS file: /usr/src/bkcvs/linux-2.5/arch/i386/kernel/traps.c,v > retrieving revision 1.77 > diff -u -r1.77 traps.c > --- a/arch/i386/kernel/traps.c 13 Jul 2004 18:02:33 -0000 1.77 > +++ b/arch/i386/kernel/traps.c 23 Aug 2004 19:34:52 -0000 > @@ -431,6 +431,26 @@ > > asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) > { > + int cpu = smp_processor_id(); > + struct tss_struct *tss = init_tss + cpu; > + struct task_struct *tsk = current; > + struct thread_struct *tsk_th = &tsk->thread; > + > + /* > + * Perform the lazy TSS's I/O bitmap copy. If the TSS has an > + * invalid offset set (the LAZY one) and the faulting thread has > + * a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS > + * and we set the offset field correctly. Then we let the CPU to > + * restart the faulting instruction. > + */ > + if (tss->io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY && > + tsk_th->io_bitmap_ptr) { > + memcpy(tss->io_bitmap, tsk_th->io_bitmap_ptr, > + IO_BITMAP_BYTES); > + tss->io_bitmap_base = IO_BITMAP_OFFSET; > + return; > + } > + > if (regs->eflags & X86_EFLAGS_IF) > local_irq_enable(); > > Index: include/asm-i386/processor.h > =================================================================== > RCS file: /usr/src/bkcvs/linux-2.5/include/asm-i386/processor.h,v > retrieving revision 1.68 > diff -u -r1.68 processor.h > --- a/include/asm-i386/processor.h 27 Jun 2004 17:53:48 -0000 1.68 > +++ b/include/asm-i386/processor.h 23 Aug 2004 19:32:58 -0000 > @@ -304,6 +304,7 @@ > #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) > #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) > #define INVALID_IO_BITMAP_OFFSET 0x8000 > +#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000 > > struct i387_fsave_struct { > long cwd; > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ >
Use get/put_cpu() in the GPF handler to prevent preemption while handling the TSS.
-- Brian Gerst - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |