]> git.hungrycats.org Git - linux/commitdiff
[PATCH] 2.5.20 x86 iobitmap cleanup
authorBenjamin LaHaise <bcrl@redhat.com>
Thu, 13 Jun 2002 03:36:00 +0000 (20:36 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Thu, 13 Jun 2002 03:36:00 +0000 (20:36 -0700)
This makes the IO bitmap allocations a separately allocated structure,
shrinking the default task size.

We alloc it in sys_ioperm() and copy_thread() and frees in
exit_thread().  It also gets rid of the IO_BITMAP_SIZE+1 crap, as only
the tss actually needs the tail long, and we weren't copying it into the
bitmap anyways.

arch/i386/kernel/ioport.c
arch/i386/kernel/process.c
include/asm-i386/processor.h

index 070667cbf4a8a9834cd7976605342269c30ee437..f1ecf08cea0ebe715ee5ea60aef3f854688653f1 100644 (file)
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
-#include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/stddef.h>
+#include <linux/slab.h>
 
 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
 static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
@@ -66,12 +66,16 @@ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
         * IO bitmap up. ioperm() is much less timing critical than clone(),
         * this is why we delay this operation until now:
         */
-       if (!t->ioperm) {
+       if (!t->ts_io_bitmap) {
+               unsigned long *bitmap;
+               bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
+               if (!bitmap)
+                       return -ENOMEM;
                /*
                 * just in case ...
                 */
-               memset(t->io_bitmap,0xff,(IO_BITMAP_SIZE+1)*4);
-               t->ioperm = 1;
+               memset(bitmap, 0xff, IO_BITMAP_BYTES);
+               t->ts_io_bitmap = bitmap;
                /*
                 * this activates it in the TSS
                 */
@@ -81,7 +85,7 @@ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
        /*
         * do it in the per-thread copy and in the TSS ...
         */
-       set_bitmap(t->io_bitmap, from, num, !turn_on);
+       set_bitmap(t->ts_io_bitmap, from, num, !turn_on);
        set_bitmap(tss->io_bitmap, from, num, !turn_on);
 
        return 0;
index ad92945381e351ee3bc14cb94f24490964f6017f..57bc712dbc6640c8ea4919bebc1f2017cbfcbbfe 100644 (file)
@@ -509,7 +509,13 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
  */
 void exit_thread(void)
 {
-       /* nothing to do ... */
+       struct task_struct *tsk = current;
+
+       /* The process may have allocated an io port bitmap... nuke it. */
+       if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
+               kfree(tsk->thread.ts_io_bitmap);
+               tsk->thread.ts_io_bitmap = NULL;
+       }
 }
 
 void flush_thread(void)
@@ -549,6 +555,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
        struct task_struct * p, struct pt_regs * regs)
 {
        struct pt_regs * childregs;
+       struct task_struct *tsk;
 
        childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
        struct_cpy(childregs, regs);
@@ -563,8 +570,17 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
        savesegment(fs,p->thread.fs);
        savesegment(gs,p->thread.gs);
 
-       unlazy_fpu(current);
-       struct_cpy(&p->thread.i387, &current->thread.i387);
+       tsk = current;
+       unlazy_fpu(tsk);
+       struct_cpy(&p->thread.i387, &tsk->thread.i387);
+
+       if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
+               p->thread.ts_io_bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
+               if (!p->thread.ts_io_bitmap)
+                       return -ENOMEM;
+               memcpy(p->thread.ts_io_bitmap, tsk->thread.ts_io_bitmap,
+                       IO_BITMAP_BYTES);
+       }
 
        return 0;
 }
@@ -685,8 +701,8 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
                loaddebug(next, 7);
        }
 
-       if (unlikely(prev->ioperm || next->ioperm)) {
-               if (next->ioperm) {
+       if (unlikely(prev->ts_io_bitmap || next->ts_io_bitmap)) {
+               if (next->ts_io_bitmap) {
                        /*
                         * 4 cachelines copy ... not good, but not that
                         * bad either. Anyone got something better?
@@ -695,8 +711,8 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
                         * and playing VM tricks to switch the IO bitmap
                         * is not really acceptable.]
                         */
-                       memcpy(tss->io_bitmap, next->io_bitmap,
-                                IO_BITMAP_SIZE*sizeof(unsigned long));
+                       memcpy(tss->io_bitmap, next->ts_io_bitmap,
+                               IO_BITMAP_BYTES);
                        tss->bitmap = IO_BITMAP_OFFSET;
                } else
                        /*
index 37c4d2fc2fc7f9274c751d1a6377ed1bfd581c71..e9e980d0c93acc362c6300aeb285aec3346a7219 100644 (file)
@@ -267,6 +267,7 @@ extern unsigned int mca_pentium_flag;
  * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
  */
 #define IO_BITMAP_SIZE 32
+#define IO_BITMAP_BYTES        (IO_BITMAP_SIZE * 4)
 #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
 #define INVALID_IO_BITMAP_OFFSET 0x8000
 
@@ -370,8 +371,7 @@ struct thread_struct {
        unsigned long           screen_bitmap;
        unsigned long           v86flags, v86mask, v86mode, saved_esp0;
 /* IO permissions */
-       int             ioperm;
-       unsigned long   io_bitmap[IO_BITMAP_SIZE+1];
+       unsigned long   *ts_io_bitmap;
 };
 
 #define INIT_THREAD  {                                         \
@@ -381,7 +381,7 @@ struct thread_struct {
        0, 0, 0,                                                \
        { { 0, }, },            /* 387 state */                 \
        0,0,0,0,0,0,                                            \
-       0,{~0,}                 /* io permissions */            \
+       NULL,                   /* io permissions */            \
 }
 
 #define INIT_TSS  {                                            \