VM segment splitting

From: Jan Astalos (astalos.ui@savba.sk)
Date: Tue Aug 22 2000 - 01:50:37 EST


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