/* * Initial dummy version just to illustrate KSM's interface to other files. */ #include #include #include 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); }