Hello,
is there any reason why segment splitting functions in
VM code ([madvise|mlock|mprotect]_fixup_[start|end|middle])
could not be replaced by just one function ? IMHO, it can
improve code readability/manageability.
struct vm_area_struct * split_segment(struct vm_area_struct * vma,
unsigned long start, unsigned long end)
{
struct vm_area_struct * middle_part = NULL, * end_part;
if (start == vma->vm_start && end == vma->vm_end)
return vma;
end_part = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (!end_part)
return NULL;
if (end != vma->vm_end) {
if (start != vma->vm_start) {
middle_part = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (!middle_part) {
kmem_cache_free(vm_area_cachep, end_part);
return NULL;
}
*middle_part = *vma;
middle_part->vm_start = start;
middle_part->vm_end = end;
middle_part->vm_pgoff += (start - vma->vm_start) >> PAGE_SHIFT;
middle_part->vm_raend = 0;
}
*end_part = *vma;
end_part->vm_start = end;
} else {
*end_part = *vma;
end_part->vm_start = start;
}
end_part->vm_pgoff += (end_part->vm_start - vma->vm_start) >> PAGE_SHIFT;
end_part->vm_raend = 0;
if (vma->vm_file)
atomic_add(middle_part ? 2 : 1, &vma->vm_file->f_count);
if (vma->vm_ops && vma->vm_ops->open) {
if (middle_part)
vma->vm_ops->open(middle_part);
vma->vm_ops->open(end_part);
}
vmlist_modify_lock(vma->vm_mm);
vma->vm_end = (start == vma->vm_start) ? end : start;
vma->vm_raend = 0;
insert_vm_struct(current->mm, end_part);
if (middle_part)
insert_vm_struct(current->mm, middle_part);
vmlist_modify_unlock(vma->vm_mm);
if (middle_part)
return middle_part;
if (start == vma->vm_start)
return vma;
return end_part;
}
and called from fixup function:
static int mlock_fixup(struct vm_area_struct * vma,
unsigned long start, unsigned long end, unsigned int newflags)
{
int pages;
if (newflags == vma->vm_flags)
return 0;
if (start > vma->vm_start || end < vma->vm_end) {
if (vma->vm_mm->map_count > MAX_MAP_COUNT)
return -ENOMEM;
vma = split_segment(vma, start, end);
}
if (!vma)
return -EAGAIN;
vmlist_modify_lock(vma->vm_mm);
vma->vm_flags = newflags;
vmlist_modify_unlock(vma->vm_mm);
/* keep track of amount of locked VM */
pages = (end - start) >> PAGE_SHIFT;
if (newflags & VM_LOCKED) {
pages = -pages;
make_pages_present(start, end);
}
vma->vm_mm->locked_vm -= pages;
return 0;
}
Regards, Jan
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Wed Aug 23 2000 - 21:00:06 EST