lkml.org 
[lkml]   [2001]   [Mar]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject2.4.3-pre6 alpha pte/pmd_alloc update
    Surprisingly, it works on lx164. :-)

    Ivan.

    On Mon, Mar 19, 2001 at 06:46:17PM -0800, Linus Torvalds wrote:
    > This has only been tested on i386 without PAE, and is known to break other
    > architectures. Ingo, mind checking what PAE needs? Generally, the changes
    > are simple, and really only implies changing the pte/pmd allocation
    > functions to _only_ allocate (ie removing the stuff that actually modifies
    > the page tables, as that is now handled by generic code), and to make sure
    > that the "pgd/pmd_populate()" functions do the right thing.
    >
    > I have also removed the xxx_kernel() functions - for architectures that
    > need them, I suspect that the right approach is to just make the
    > "populate" funtions notice when "mm" is "init_mm", the kernel context.
    > That removed a lot of duplicate code that had little good reason.

    diff -urp 2.4.3p6/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c
    --- 2.4.3p6/arch/alpha/mm/init.c Wed Nov 29 09:43:39 2000
    +++ linux/arch/alpha/mm/init.c Wed Mar 21 20:04:21 2001
    @@ -43,20 +43,6 @@ struct thread_struct original_pcb;
    struct pgtable_cache_struct quicklists;
    #endif

    -void
    -__bad_pmd(pgd_t *pgd)
    -{
    - printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd));
    - pgd_set(pgd, BAD_PAGETABLE);
    -}
    -
    -void
    -__bad_pte(pmd_t *pmd)
    -{
    - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
    - pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
    -}
    -
    pgd_t *
    get_pgd_slow(void)
    {
    @@ -80,66 +66,26 @@ get_pgd_slow(void)
    return ret;
    }

    -pmd_t *
    -get_pmd_slow(pgd_t *pgd, unsigned long offset)
    -{
    - pmd_t *pmd;
    -
    - pmd = (pmd_t *) __get_free_page(GFP_KERNEL);
    - if (pgd_none(*pgd)) {
    - if (pmd) {
    - clear_page((void *)pmd);
    - pgd_set(pgd, pmd);
    - return pmd + offset;
    - }
    - pgd_set(pgd, BAD_PAGETABLE);
    - return NULL;
    - }
    - free_page((unsigned long)pmd);
    - if (pgd_bad(*pgd)) {
    - __bad_pmd(pgd);
    - return NULL;
    - }
    - return (pmd_t *) pgd_page(*pgd) + offset;
    -}
    -
    -pte_t *
    -get_pte_slow(pmd_t *pmd, unsigned long offset)
    -{
    - pte_t *pte;
    -
    - pte = (pte_t *) __get_free_page(GFP_KERNEL);
    - if (pmd_none(*pmd)) {
    - if (pte) {
    - clear_page((void *)pte);
    - pmd_set(pmd, pte);
    - return pte + offset;
    - }
    - pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
    - return NULL;
    - }
    - free_page((unsigned long)pte);
    - if (pmd_bad(*pmd)) {
    - __bad_pte(pmd);
    - return NULL;
    - }
    - return (pte_t *) pmd_page(*pmd) + offset;
    -}
    -
    int do_check_pgt_cache(int low, int high)
    {
    int freed = 0;
    - if(pgtable_cache_size > high) {
    - do {
    - if(pgd_quicklist)
    - free_pgd_slow(get_pgd_fast()), freed++;
    - if(pmd_quicklist)
    - free_pmd_slow(get_pmd_fast()), freed++;
    - if(pte_quicklist)
    - free_pte_slow(get_pte_fast()), freed++;
    - } while(pgtable_cache_size > low);
    - }
    - return freed;
    + if(pgtable_cache_size > high) {
    + do {
    + if(pgd_quicklist) {
    + free_pgd_slow(get_pgd_fast());
    + freed++;
    + }
    + if(pmd_quicklist) {
    + pmd_free_slow(pmd_alloc_one_fast());
    + freed++;
    + }
    + if(pte_quicklist) {
    + pte_free_slow(pte_alloc_one_fast());
    + freed++;
    + }
    + } while(pgtable_cache_size > low);
    + }
    + return freed;
    }

    /*
    diff -urp 2.4.3p6/include/asm-alpha/pgalloc.h linux/include/asm-alpha/pgalloc.h
    --- 2.4.3p6/include/asm-alpha/pgalloc.h Sat Dec 30 01:07:23 2000
    +++ linux/include/asm-alpha/pgalloc.h Wed Mar 21 19:48:27 2001
    @@ -241,6 +241,9 @@ extern struct pgtable_cache_struct {
    #define pte_quicklist (quicklists.pte_cache)
    #define pgtable_cache_size (quicklists.pgtable_cache_sz)

    +#define pmd_populate(pmd, pte) pmd_set(pmd, pte)
    +#define pgd_populate(pgd, pmd) pgd_set(pgd, pmd)
    +
    extern pgd_t *get_pgd_slow(void);

    static inline pgd_t *get_pgd_fast(void)
    @@ -268,9 +271,15 @@ static inline void free_pgd_slow(pgd_t *
    free_page((unsigned long)pgd);
    }

    -extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_premasked);
    +static inline pmd_t *pmd_alloc_one(void)
    +{
    + pmd_t *ret = (pmd_t *)__get_free_page(GFP_KERNEL);
    + if (ret)
    + clear_page(ret);
    + return ret;
    +}

    -static inline pmd_t *get_pmd_fast(void)
    +static inline pmd_t *pmd_alloc_one_fast(void)
    {
    unsigned long *ret;

    @@ -282,21 +291,27 @@ static inline pmd_t *get_pmd_fast(void)
    return (pmd_t *)ret;
    }

    -static inline void free_pmd_fast(pmd_t *pmd)
    +static inline void pmd_free_fast(pmd_t *pmd)
    {
    *(unsigned long *)pmd = (unsigned long) pte_quicklist;
    pte_quicklist = (unsigned long *) pmd;
    pgtable_cache_size++;
    }

    -static inline void free_pmd_slow(pmd_t *pmd)
    +static inline void pmd_free_slow(pmd_t *pmd)
    {
    free_page((unsigned long)pmd);
    }

    -extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
    +static inline pte_t *pte_alloc_one(void)
    +{
    + pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL);
    + if (pte)
    + clear_page(pte);
    + return pte;
    +}

    -static inline pte_t *get_pte_fast(void)
    +static inline pte_t *pte_alloc_one_fast(void)
    {
    unsigned long *ret;

    @@ -308,66 +323,22 @@ static inline pte_t *get_pte_fast(void)
    return (pte_t *)ret;
    }

    -static inline void free_pte_fast(pte_t *pte)
    +static inline void pte_free_fast(pte_t *pte)
    {
    *(unsigned long *)pte = (unsigned long) pte_quicklist;
    pte_quicklist = (unsigned long *) pte;
    pgtable_cache_size++;
    }

    -static inline void free_pte_slow(pte_t *pte)
    +static inline void pte_free_slow(pte_t *pte)
    {
    free_page((unsigned long)pte);
    }

    -extern void __bad_pte(pmd_t *pmd);
    -extern void __bad_pmd(pgd_t *pgd);
    -
    -#define pte_free_kernel(pte) free_pte_fast(pte)
    -#define pte_free(pte) free_pte_fast(pte)
    -#define pmd_free_kernel(pmd) free_pmd_fast(pmd)
    -#define pmd_free(pmd) free_pmd_fast(pmd)
    +#define pte_free(pte) pte_free_fast(pte)
    +#define pmd_free(pmd) pmd_free_fast(pmd)
    #define pgd_free(pgd) free_pgd_fast(pgd)
    #define pgd_alloc() get_pgd_fast()
    -
    -static inline pte_t * pte_alloc(pmd_t *pmd, unsigned long address)
    -{
    - address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
    - if (pmd_none(*pmd)) {
    - pte_t *page = get_pte_fast();
    -
    - if (!page)
    - return get_pte_slow(pmd, address);
    - pmd_set(pmd, page);
    - return page + address;
    - }
    - if (pmd_bad(*pmd)) {
    - __bad_pte(pmd);
    - return NULL;
    - }
    - return (pte_t *) pmd_page(*pmd) + address;
    -}
    -
    -static inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address)
    -{
    - address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
    - if (pgd_none(*pgd)) {
    - pmd_t *page = get_pmd_fast();
    -
    - if (!page)
    - return get_pmd_slow(pgd, address);
    - pgd_set(pgd, page);
    - return page + address;
    - }
    - if (pgd_bad(*pgd)) {
    - __bad_pmd(pgd);
    - return NULL;
    - }
    - return (pmd_t *) pgd_page(*pgd) + address;
    -}
    -
    -#define pte_alloc_kernel pte_alloc
    -#define pmd_alloc_kernel pmd_alloc

    extern int do_check_pgt_cache(int, int);

    -
    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/
    \
     
     \ /
      Last update: 2005-03-22 13:29    [W:5.227 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site