mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-23 07:01:23 +00:00
x86-32: use non-lazy io bitmap context switching
Impact: remove 32-bit optimization to prepare unification x86-32 and -64 differ in the way they context-switch tasks with io permission bitmaps. x86-64 simply copies the next tasks io bitmap into place (if any) on context switch. x86-32 invalidates the bitmap on context switch, so that the next IO instruction will fault; at that point it installs the appropriate IO bitmap. This makes context switching IO-bitmap-using tasks a bit more less expensive, at the cost of making the next IO instruction slower due to the extra fault. This tradeoff only makes sense if IO-bitmap-using processes are relatively common, but they don't actually use IO instructions very often. However, in a typical desktop system, the only process likely to be using IO bitmaps is the X server, and nothing at all on a server. Therefore the lazy context switch doesn't really win all that much, and its just a gratuitious difference from 64-bit code. This patch removes the lazy context switch, with a view to unifying this code in a later change. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
645af4e9e0
commit
db949bba3c
4 changed files with 9 additions and 90 deletions
|
@ -248,7 +248,6 @@ struct x86_hw_tss {
|
||||||
#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
|
#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
|
||||||
#define IO_BITMAP_OFFSET offsetof(struct tss_struct, io_bitmap)
|
#define IO_BITMAP_OFFSET offsetof(struct tss_struct, io_bitmap)
|
||||||
#define INVALID_IO_BITMAP_OFFSET 0x8000
|
#define INVALID_IO_BITMAP_OFFSET 0x8000
|
||||||
#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000
|
|
||||||
|
|
||||||
struct tss_struct {
|
struct tss_struct {
|
||||||
/*
|
/*
|
||||||
|
@ -263,11 +262,6 @@ struct tss_struct {
|
||||||
* be within the limit.
|
* be within the limit.
|
||||||
*/
|
*/
|
||||||
unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
|
unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
|
||||||
/*
|
|
||||||
* Cache the current maximum and the last task that used the bitmap:
|
|
||||||
*/
|
|
||||||
unsigned long io_bitmap_max;
|
|
||||||
struct thread_struct *io_bitmap_owner;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* .. and then another 0x100 bytes for the emergency kernel stack:
|
* .. and then another 0x100 bytes for the emergency kernel stack:
|
||||||
|
|
|
@ -85,19 +85,8 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
||||||
|
|
||||||
t->io_bitmap_max = bytes;
|
t->io_bitmap_max = bytes;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
|
||||||
/*
|
|
||||||
* Sets the lazy trigger so that the next I/O operation will
|
|
||||||
* reload the correct bitmap.
|
|
||||||
* Reset the owner so that a process switch will not set
|
|
||||||
* tss->io_bitmap_base to IO_BITMAP_OFFSET.
|
|
||||||
*/
|
|
||||||
tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
|
|
||||||
tss->io_bitmap_owner = NULL;
|
|
||||||
#else
|
|
||||||
/* Update the TSS: */
|
/* Update the TSS: */
|
||||||
memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated);
|
memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated);
|
||||||
#endif
|
|
||||||
|
|
||||||
put_cpu();
|
put_cpu();
|
||||||
|
|
||||||
|
|
|
@ -248,11 +248,8 @@ void exit_thread(void)
|
||||||
/*
|
/*
|
||||||
* Careful, clear this in the TSS too:
|
* Careful, clear this in the TSS too:
|
||||||
*/
|
*/
|
||||||
memset(tss->io_bitmap, 0xff, tss->io_bitmap_max);
|
memset(tss->io_bitmap, 0xff, t->io_bitmap_max);
|
||||||
t->io_bitmap_max = 0;
|
t->io_bitmap_max = 0;
|
||||||
tss->io_bitmap_owner = NULL;
|
|
||||||
tss->io_bitmap_max = 0;
|
|
||||||
tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
|
|
||||||
put_cpu();
|
put_cpu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,34 +455,19 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
|
||||||
hard_enable_TSC();
|
hard_enable_TSC();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
|
if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
|
||||||
/*
|
/*
|
||||||
* Disable the bitmap via an invalid offset. We still cache
|
* Copy the relevant range of the IO bitmap.
|
||||||
* the previous bitmap owner and the IO bitmap contents:
|
* Normally this is 128 bytes or less:
|
||||||
*/
|
*/
|
||||||
tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
|
memcpy(tss->io_bitmap, next->io_bitmap_ptr,
|
||||||
return;
|
max(prev->io_bitmap_max, next->io_bitmap_max));
|
||||||
|
} else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) {
|
||||||
|
/*
|
||||||
|
* Clear any possible leftover bits:
|
||||||
|
*/
|
||||||
|
memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (likely(next == tss->io_bitmap_owner)) {
|
|
||||||
/*
|
|
||||||
* Previous owner of the bitmap (hence the bitmap content)
|
|
||||||
* matches the next task, we dont have to do anything but
|
|
||||||
* to set a valid offset in the TSS:
|
|
||||||
*/
|
|
||||||
tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
* redundant copies when the currently switched task does not
|
|
||||||
* perform any I/O during its timeslice.
|
|
||||||
*/
|
|
||||||
tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -118,47 +118,6 @@ die_if_kernel(const char *str, struct pt_regs *regs, long err)
|
||||||
if (!user_mode_vm(regs))
|
if (!user_mode_vm(regs))
|
||||||
die(str, regs, err);
|
die(str, regs, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 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,
|
|
||||||
* we set the offset field correctly and return 1.
|
|
||||||
*/
|
|
||||||
static int lazy_iobitmap_copy(void)
|
|
||||||
{
|
|
||||||
struct thread_struct *thread;
|
|
||||||
struct tss_struct *tss;
|
|
||||||
int cpu;
|
|
||||||
|
|
||||||
cpu = get_cpu();
|
|
||||||
tss = &per_cpu(init_tss, cpu);
|
|
||||||
thread = ¤t->thread;
|
|
||||||
|
|
||||||
if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY &&
|
|
||||||
thread->io_bitmap_ptr) {
|
|
||||||
memcpy(tss->io_bitmap, thread->io_bitmap_ptr,
|
|
||||||
thread->io_bitmap_max);
|
|
||||||
/*
|
|
||||||
* If the previously set map was extending to higher ports
|
|
||||||
* than the current one, pad extra space with 0xff (no access).
|
|
||||||
*/
|
|
||||||
if (thread->io_bitmap_max < tss->io_bitmap_max) {
|
|
||||||
memset((char *) tss->io_bitmap +
|
|
||||||
thread->io_bitmap_max, 0xff,
|
|
||||||
tss->io_bitmap_max - thread->io_bitmap_max);
|
|
||||||
}
|
|
||||||
tss->io_bitmap_max = thread->io_bitmap_max;
|
|
||||||
tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
|
|
||||||
tss->io_bitmap_owner = thread;
|
|
||||||
put_cpu();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
put_cpu();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void __kprobes
|
static void __kprobes
|
||||||
|
@ -309,11 +268,6 @@ do_general_protection(struct pt_regs *regs, long error_code)
|
||||||
conditional_sti(regs);
|
conditional_sti(regs);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
if (lazy_iobitmap_copy()) {
|
|
||||||
/* restart the faulting instruction */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (regs->flags & X86_VM_MASK)
|
if (regs->flags & X86_VM_MASK)
|
||||||
goto gp_in_vm86;
|
goto gp_in_vm86;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue