This new one should be better. Using the spinlock for the SMP serialization is
ok because that's an extremely slow path.

diff -urN -X /home/andrea/bin/dontdiff 2.4.2/arch/i386/mm/fault.c 
2.4.2aa/arch/i386/mm/fault.c
--- 2.4.2/arch/i386/mm/fault.c  Thu Feb 22 03:44:53 2001
+++ 2.4.2aa/arch/i386/mm/fault.c        Sat Feb 24 05:41:11 2001
@@ -326,23 +326,27 @@
                int offset = __pgd_offset(address);
                pgd_t *pgd, *pgd_k;
                pmd_t *pmd, *pmd_k;
+               static spinlock_t lazy_vmalloc_lock = SPIN_LOCK_UNLOCKED;
+               unsigned long flags;
 
                pgd = tsk->active_mm->pgd + offset;
                pgd_k = init_mm.pgd + offset;
 
-               if (!pgd_present(*pgd)) {
-                       if (!pgd_present(*pgd_k))
-                               goto bad_area_nosemaphore;
+               spin_lock_irqsave(&lazy_vmalloc_lock, flags);
+               if (!pgd_present(*pgd) && pgd_present(*pgd_k)) {
                        set_pgd(pgd, *pgd_k);
+                       spin_unlock_irqrestore(&lazy_vmalloc_lock, flags);
                        return;
                }
-
                pmd = pmd_offset(pgd, address);
                pmd_k = pmd_offset(pgd_k, address);
 
-               if (pmd_present(*pmd) || !pmd_present(*pmd_k))
-                       goto bad_area_nosemaphore;
-               set_pmd(pmd, *pmd_k);
-               return;
+               if (!pmd_present(*pmd) && pmd_present(*pmd_k)) {
+                       set_pmd(pmd, *pmd_k);
+                       spin_unlock_irqrestore(&lazy_vmalloc_lock, flags);
+                       return;
+               }
+               spin_unlock_irqrestore(&lazy_vmalloc_lock, flags);
+               goto bad_area_nosemaphore;
        }
 }
diff -urN -X /home/andrea/bin/dontdiff 2.4.2/arch/i386/mm/init.c 
2.4.2aa/arch/i386/mm/init.c
--- 2.4.2/arch/i386/mm/init.c   Sat Feb 10 02:34:03 2001
+++ 2.4.2aa/arch/i386/mm/init.c Fri Feb 23 19:09:25 2001
@@ -116,21 +116,13 @@
        pte_t *pte;
 
        pte = (pte_t *) __get_free_page(GFP_KERNEL);
-       if (pmd_none(*pmd)) {
-               if (pte) {
-                       clear_page(pte);
-                       set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
-                       return pte + offset;
-               }
-               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table())));
-               return NULL;
+       if (pte) {
+               clear_page(pte);
+               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
+               return pte + offset;
        }
-       free_page((unsigned long)pte);
-       if (pmd_bad(*pmd)) {
-               __handle_bad_pmd_kernel(pmd);
-               return NULL;
-       }
-       return (pte_t *) pmd_page(*pmd) + offset;
+       set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table())));
+       return NULL;
 }
 
 pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
diff -urN -X /home/andrea/bin/dontdiff 2.4.2/include/asm-i386/pgalloc-3level.h 
2.4.2aa/include/asm-i386/pgalloc-3level.h
--- 2.4.2/include/asm-i386/pgalloc-3level.h     Fri Dec  3 20:12:23 1999
+++ 2.4.2aa/include/asm-i386/pgalloc-3level.h   Fri Feb 23 19:03:14 2001
@@ -53,12 +53,9 @@
                if (!page)
                        page = get_pmd_slow();
                if (page) {
-                       if (pgd_none(*pgd)) {
-                               set_pgd(pgd, __pgd(1 + __pa(page)));
-                               __flush_tlb();
-                               return page + address;
-                       } else
-                               free_pmd_fast(page);
+                       set_pgd(pgd, __pgd(1 + __pa(page)));
+                       __flush_tlb();
+                       return page + address;
                } else
                        return NULL;
        }


non pae mode is still untested but it should now have a chance to work.

Andrea
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to