// insert_vma_struct -insert vma in mm's list link void insert_vma_struct(struct mm_struct *mm, struct vma_struct *vma) { assert(vma->vm_start < vma->vm_end); list_entry_t *list = &(mm->mmap_list); list_entry_t *le_prev = list, *le_next; list_entry_t *le = list; while ((le = list_next(le)) != list) { struct vma_struct *mmap_prev = le2vma(le, list_link); if (mmap_prev->vm_start > vma->vm_start) { break; } le_prev = le; } le_next = list_next(le_prev); /* check overlap */ if (le_prev != list) { check_vma_overlap(le2vma(le_prev, list_link), vma); } if (le_next != list) { check_vma_overlap(vma, le2vma(le_next, list_link)); } vma->vm_mm = mm; list_add_after(le_prev, &(vma->list_link)); mm->map_count ++; }
// insert_vma_struct -insert vma in mm's rb tree link & list link void insert_vma_struct(struct mm_struct *mm, struct vma_struct *vma) { assert(vma->vm_start < vma->vm_end); list_entry_t *list = &(mm->mmap_list); list_entry_t *le_prev = list, *le_next; if (mm->mmap_tree != NULL) { struct vma_struct *mmap_prev; insert_vma_rb(mm->mmap_tree, vma, &mmap_prev); if (mmap_prev != NULL) { le_prev = &(mmap_prev->list_link); } } else { list_entry_t *le = list; while ((le = list_next(le)) != list) { struct vma_struct *mmap_prev = le2vma(le, list_link); if (mmap_prev->vm_start > vma->vm_start) { break; } le_prev = le; } } le_next = list_next(le_prev); /* check overlap */ if (le_prev != list) { check_vma_overlap(le2vma(le_prev, list_link), vma); } if (le_next != list) { check_vma_overlap(vma, le2vma(le_next, list_link)); } vma->vm_mm = mm; list_add_after(le_prev, &(vma->list_link)); mm->map_count ++; if (mm->mmap_tree == NULL && mm->map_count >= RB_MIN_MAP_COUNT) { /* try to build red-black tree now, but may fail. */ mm->mmap_tree = rb_tree_create(vma_compare); if (mm->mmap_tree != NULL) { list_entry_t *list = &(mm->mmap_list), *le = list; while ((le = list_next(le)) != list) { insert_vma_rb(mm->mmap_tree, le2vma(le, list_link), NULL); } } } }