How is vmap_area inserted and can map_areas overlap?
I am browsing the code static void __insert_vmap_area(struct vmap_area *va) { struct rb_node **p = &vmap_area_root.rb_node; struct rb_node *parent = NULL; struct rb_node *tmp; while (*p) { struct vmap_area *tmp_va; parent = *p; tmp_va = rb_entry(parent, struct vmap_area, rb_node); if (va->va_start < tmp_va->va_end) p = &(*p)->rb_left; else if (va->va_end > tmp_va->va_start) p = &(*p)->rb_right; else BUG(); } rb_link_node(&va->rb_node, parent, p); rb_insert_color(&va->rb_node, &vmap_area_root); /* address-sort this list */ tmp = rb_prev(&va->rb_node); if (tmp) { struct vmap_area *prev; prev = rb_entry(tmp, struct vmap_area, rb_node); list_add_rcu(&va->list, &prev->list); } else list_add_rcu(&va->list, &vmap_area_list); } As far as I can know map_area is a range for the vmalloc to alloc non-contigious memory, which confuses me is that why not use va->va_start > tmp_va->va_start and va->va_end < tmp_va->va_end to insert a new vmap_area. Can a virtual address mapping overlap? One more question In alloc_map_area, I found this part of code. /* from the starting point, walk areas until a suitable hole is found */ while (addr + size > first->va_start && addr + size <= vend) { if (addr + cached_hole_size < first->va_start) /* cached_hole_size */ cached_hole_size = first->va_start - addr; addr = ALIGN(first->va_end, align); if (addr + size < addr) goto overflow; if (list_is_last(&first->list, &vmap_area_list)) goto found; first = list_next_entry(first, list); } It seems like just inert a map_area at the end of list, what dose suitable hole means? Why not add this? if(addr+size < first->va_start) goto notound
Replace miss typing va->va_start > tmp_va->va_start and va->va_end < tmp_va->va_end with va->va_start > tmp_va->va_end and va->va_end < tmp_va->va_end. It ensures va and tmp never overlap.
On Sep 4, 2016, at 9:29 PM, Peng Gao <peng.gao.dut@gmail.com> wrote:
I am browsing the code
static void __insert_vmap_area(struct vmap_area *va) { struct rb_node **p = &vmap_area_root.rb_node; struct rb_node *parent = NULL; struct rb_node *tmp;
while (*p) { struct vmap_area *tmp_va;
parent = *p; tmp_va = rb_entry(parent, struct vmap_area, rb_node); if (va->va_start < tmp_va->va_end) p = &(*p)->rb_left; else if (va->va_end > tmp_va->va_start) p = &(*p)->rb_right; else BUG(); }
rb_link_node(&va->rb_node, parent, p); rb_insert_color(&va->rb_node, &vmap_area_root);
/* address-sort this list */ tmp = rb_prev(&va->rb_node); if (tmp) { struct vmap_area *prev; prev = rb_entry(tmp, struct vmap_area, rb_node); list_add_rcu(&va->list, &prev->list); } else list_add_rcu(&va->list, &vmap_area_list); }
As far as I can know map_area is a range for the vmalloc to alloc non-contigious memory, which confuses me is that why not use va->va_start > tmp_va->va_start and va->va_end < tmp_va->va_end to insert a new vmap_area. Can a virtual address mapping overlap?
One more question
In alloc_map_area, I found this part of code.
/* from the starting point, walk areas until a suitable hole is found */ while (addr + size > first->va_start && addr + size <= vend) { if (addr + cached_hole_size < first->va_start) /* cached_hole_size */ cached_hole_size = first->va_start - addr; addr = ALIGN(first->va_end, align); if (addr + size < addr) goto overflow;
if (list_is_last(&first->list, &vmap_area_list)) goto found;
first = list_next_entry(first, list); }
It seems like just inert a map_area at the end of list, what dose suitable hole means? Why not add this?
if(addr+size < first->va_start) goto notound
Replace miss typing va->va_start > tmp_va->va_start and va->va_end < tmp_va->va_end with va->va_start > tmp_va->va_end and va->va_end < tmp_va->va_start. It ensures va and tmp never overlap. On Sep 4, 2016, at 9:29 PM, Peng Gao <peng.gao.dut@gmail.com> wrote: I am browsing the code static void __insert_vmap_area(struct vmap_area *va) { struct rb_node **p = &vmap_area_root.rb_node; struct rb_node *parent = NULL; struct rb_node *tmp; while (*p) { struct vmap_area *tmp_va; parent = *p; tmp_va = rb_entry(parent, struct vmap_area, rb_node); if (va->va_start < tmp_va->va_end) p = &(*p)->rb_left; else if (va->va_end > tmp_va->va_start) p = &(*p)->rb_right; else BUG(); } rb_link_node(&va->rb_node, parent, p); rb_insert_color(&va->rb_node, &vmap_area_root); /* address-sort this list */ tmp = rb_prev(&va->rb_node); if (tmp) { struct vmap_area *prev; prev = rb_entry(tmp, struct vmap_area, rb_node); list_add_rcu(&va->list, &prev->list); } else list_add_rcu(&va->list, &vmap_area_list); } As far as I can know map_area is a range for the vmalloc to alloc non-contigious memory, which confuses me is that why not use va->va_start > tmp_va->va_start and va->va_end < tmp_va->va_end to insert a new vmap_area. Can a virtual address mapping overlap? One more question In alloc_map_area, I found this part of code. /* from the starting point, walk areas until a suitable hole is found */ while (addr + size > first->va_start && addr + size <= vend) { if (addr + cached_hole_size < first->va_start) /* cached_hole_size */ cached_hole_size = first->va_start - addr; addr = ALIGN(first->va_end, align); if (addr + size < addr) goto overflow; if (list_is_last(&first->list, &vmap_area_list)) goto found; first = list_next_entry(first, list); } It seems like just inert a map_area at the end of list, what dose suitable hole means? Why not add this? if(addr+size < first->va_start) goto notound
participants (1)
-
Peng Gao