patch-2.3.29 linux/include/asm-ppc/pgalloc.h

Next file: linux/include/asm-ppc/pgtable.h
Previous file: linux/include/asm-m68k/signal.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.28/linux/include/asm-ppc/pgalloc.h linux/include/asm-ppc/pgalloc.h
@@ -0,0 +1,151 @@
+#ifndef _PPC_PGALLOC_H
+#define _PPC_PGALLOC_H
+
+
+
+/* We don't use pmd cache, so this is a dummy routine */
+extern __inline__ pmd_t *get_pmd_fast(void)
+{
+	return (pmd_t *)0;
+}
+
+extern __inline__ void free_pmd_fast(pmd_t *pmd)
+{
+}
+
+extern __inline__ void free_pmd_slow(pmd_t *pmd)
+{
+}
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+extern inline void pmd_free(pmd_t * pmd)
+{
+}
+
+extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
+{
+	return (pmd_t *) pgd;
+}
+
+#define pmd_free_kernel		pmd_free
+#define pmd_alloc_kernel	pmd_alloc
+#define pte_alloc_kernel	pte_alloc
+
+extern __inline__ pgd_t *get_pgd_slow(void)
+{
+	pgd_t *ret, *init;
+	/*if ( (ret = (pgd_t *)get_zero_page_fast()) == NULL )*/
+	if ( (ret = (pgd_t *)__get_free_page(GFP_KERNEL)) != NULL )
+		memset (ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+	if (ret) {
+		init = pgd_offset(&init_mm, 0);
+		memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+			(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+	}
+	return ret;
+}
+
+extern __inline__ pgd_t *get_pgd_fast(void)
+{
+        unsigned long *ret;
+
+        if((ret = pgd_quicklist) != NULL) {
+                pgd_quicklist = (unsigned long *)(*ret);
+                ret[0] = ret[1];
+                pgtable_cache_size--;
+        } else
+                ret = (unsigned long *)get_pgd_slow();
+        return (pgd_t *)ret;
+}
+
+extern __inline__ void free_pgd_fast(pgd_t *pgd)
+{
+        *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
+        pgd_quicklist = (unsigned long *) pgd;
+        pgtable_cache_size++;
+}
+
+extern __inline__ void free_pgd_slow(pgd_t *pgd)
+{
+	free_page((unsigned long)pgd);
+}
+
+extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
+
+extern __inline__ pte_t *get_pte_fast(void)
+{
+        unsigned long *ret;
+
+        if((ret = (unsigned long *)pte_quicklist) != NULL) {
+                pte_quicklist = (unsigned long *)(*ret);
+                ret[0] = ret[1];
+                pgtable_cache_size--;
+	}
+        return (pte_t *)ret;
+}
+
+extern __inline__ void free_pte_fast(pte_t *pte)
+{
+        *(unsigned long *)pte = (unsigned long) pte_quicklist;
+        pte_quicklist = (unsigned long *) pte;
+        pgtable_cache_size++;
+}
+
+extern __inline__ void free_pte_slow(pte_t *pte)
+{
+	free_page((unsigned long)pte);
+}
+#define pte_free_kernel(pte)    free_pte_fast(pte)
+#define pte_free(pte)           free_pte_fast(pte)
+#define pgd_free(pgd)           free_pgd_fast(pgd)
+#define pgd_alloc()             get_pgd_fast()
+
+extern 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 = (pte_t *) get_pte_fast();
+		
+		if (!page)
+			return get_pte_slow(pmd, address);
+		pmd_val(*pmd) = (unsigned long) page;
+		return page + address;
+	}
+	if (pmd_bad(*pmd)) {
+		__bad_pte(pmd);
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + address;
+}
+
+extern int do_check_pgt_cache(int, int);
+
+extern __inline__ pte_t *find_pte(struct mm_struct *mm,unsigned long va)
+{
+	pgd_t *dir;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	va &= PAGE_MASK;
+	
+	dir = pgd_offset( mm, va );
+	if (dir)
+	{
+		pmd = pmd_offset(dir, va & PAGE_MASK);
+		if (pmd && pmd_present(*pmd))
+		{
+			pte = pte_offset(pmd, va);
+			if (pte && pte_present(*pte))
+			{			
+				pte_uncache(*pte);
+				flush_tlb_page(find_vma(mm,va),va);
+			}
+		}
+	}
+	return pte;
+}
+
+#endif /* _PPC_PGALLOC_H */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)