|
@@ -3,6 +3,7 @@
|
|
|
#ifdef __KERNEL__
|
|
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
+#include <linux/mmdebug.h>
|
|
|
#include <asm/processor.h> /* For TASK_SIZE */
|
|
|
#include <asm/mmu.h>
|
|
|
#include <asm/page.h>
|
|
@@ -33,10 +34,73 @@ static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
|
|
|
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
|
|
|
static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
|
|
|
static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
|
|
|
-static inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
|
|
|
static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
|
|
|
static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
|
|
|
|
|
|
+#ifdef CONFIG_NUMA_BALANCING
|
|
|
+
|
|
|
+static inline int pte_present(pte_t pte)
|
|
|
+{
|
|
|
+ return pte_val(pte) & (_PAGE_PRESENT | _PAGE_NUMA);
|
|
|
+}
|
|
|
+
|
|
|
+#define pte_numa pte_numa
|
|
|
+static inline int pte_numa(pte_t pte)
|
|
|
+{
|
|
|
+ return (pte_val(pte) &
|
|
|
+ (_PAGE_NUMA|_PAGE_PRESENT)) == _PAGE_NUMA;
|
|
|
+}
|
|
|
+
|
|
|
+#define pte_mknonnuma pte_mknonnuma
|
|
|
+static inline pte_t pte_mknonnuma(pte_t pte)
|
|
|
+{
|
|
|
+ pte_val(pte) &= ~_PAGE_NUMA;
|
|
|
+ pte_val(pte) |= _PAGE_PRESENT | _PAGE_ACCESSED;
|
|
|
+ return pte;
|
|
|
+}
|
|
|
+
|
|
|
+#define pte_mknuma pte_mknuma
|
|
|
+static inline pte_t pte_mknuma(pte_t pte)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * We should not set _PAGE_NUMA on non present ptes. Also clear the
|
|
|
+ * present bit so that hash_page will return 1 and we collect this
|
|
|
+ * as numa fault.
|
|
|
+ */
|
|
|
+ if (pte_present(pte)) {
|
|
|
+ pte_val(pte) |= _PAGE_NUMA;
|
|
|
+ pte_val(pte) &= ~_PAGE_PRESENT;
|
|
|
+ } else
|
|
|
+ VM_BUG_ON(1);
|
|
|
+ return pte;
|
|
|
+}
|
|
|
+
|
|
|
+#define pmd_numa pmd_numa
|
|
|
+static inline int pmd_numa(pmd_t pmd)
|
|
|
+{
|
|
|
+ return pte_numa(pmd_pte(pmd));
|
|
|
+}
|
|
|
+
|
|
|
+#define pmd_mknonnuma pmd_mknonnuma
|
|
|
+static inline pmd_t pmd_mknonnuma(pmd_t pmd)
|
|
|
+{
|
|
|
+ return pte_pmd(pte_mknonnuma(pmd_pte(pmd)));
|
|
|
+}
|
|
|
+
|
|
|
+#define pmd_mknuma pmd_mknuma
|
|
|
+static inline pmd_t pmd_mknuma(pmd_t pmd)
|
|
|
+{
|
|
|
+ return pte_pmd(pte_mknuma(pmd_pte(pmd)));
|
|
|
+}
|
|
|
+
|
|
|
+# else
|
|
|
+
|
|
|
+static inline int pte_present(pte_t pte)
|
|
|
+{
|
|
|
+ return pte_val(pte) & _PAGE_PRESENT;
|
|
|
+}
|
|
|
+#endif /* CONFIG_NUMA_BALANCING */
|
|
|
+
|
|
|
/* Conversion functions: convert a page and protection to a page entry,
|
|
|
* and a page entry and page directory to the page they refer to.
|
|
|
*
|