|
@@ -0,0 +1,56 @@
|
|
|
+/*
|
|
|
+ * Initial dummy version just to illustrate KSM's interface to other files.
|
|
|
+ */
|
|
|
+
|
|
|
+#include <linux/errno.h>
|
|
|
+#include <linux/mman.h>
|
|
|
+#include <linux/ksm.h>
|
|
|
+
|
|
|
+int ksm_madvise(struct vm_area_struct *vma, unsigned long start,
|
|
|
+ unsigned long end, int advice, unsigned long *vm_flags)
|
|
|
+{
|
|
|
+ struct mm_struct *mm = vma->vm_mm;
|
|
|
+
|
|
|
+ switch (advice) {
|
|
|
+ case MADV_MERGEABLE:
|
|
|
+ /*
|
|
|
+ * Be somewhat over-protective for now!
|
|
|
+ */
|
|
|
+ if (*vm_flags & (VM_MERGEABLE | VM_SHARED | VM_MAYSHARE |
|
|
|
+ VM_PFNMAP | VM_IO | VM_DONTEXPAND |
|
|
|
+ VM_RESERVED | VM_HUGETLB | VM_INSERTPAGE |
|
|
|
+ VM_MIXEDMAP | VM_SAO))
|
|
|
+ return 0; /* just ignore the advice */
|
|
|
+
|
|
|
+ if (!test_bit(MMF_VM_MERGEABLE, &mm->flags))
|
|
|
+ if (__ksm_enter(mm) < 0)
|
|
|
+ return -EAGAIN;
|
|
|
+
|
|
|
+ *vm_flags |= VM_MERGEABLE;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case MADV_UNMERGEABLE:
|
|
|
+ if (!(*vm_flags & VM_MERGEABLE))
|
|
|
+ return 0; /* just ignore the advice */
|
|
|
+
|
|
|
+ /* Unmerge any merged pages here */
|
|
|
+
|
|
|
+ *vm_flags &= ~VM_MERGEABLE;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int __ksm_enter(struct mm_struct *mm)
|
|
|
+{
|
|
|
+ /* Allocate a structure to track mm and link it into KSM's list */
|
|
|
+ set_bit(MMF_VM_MERGEABLE, &mm->flags);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void __ksm_exit(struct mm_struct *mm)
|
|
|
+{
|
|
|
+ /* Unlink and free all KSM's structures which track this mm */
|
|
|
+ clear_bit(MMF_VM_MERGEABLE, &mm->flags);
|
|
|
+}
|