57 строки
1.3 KiB
C
57 строки
1.3 KiB
C
|
/*
|
||
|
* 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);
|
||
|
}
|