@@ -68,16 +68,8 @@ struct vmap_area {
struct rb_node rb_node; /* address sorted rbtree */
struct list_head list; /* address sorted list */
- /*
- * The following two variables can be packed, because
- * a vmap_area object can be either:
- * 1) in "free" tree (root is free_vmap_area_root)
- * 2) or "busy" tree (root is vmap_area_root)
- */
- union {
- unsigned long subtree_max_size; /* in "free" tree */
- struct vm_struct *vm; /* in "busy" tree */
- };
+ unsigned long subtree_max_size;
+ struct vm_struct *vm;
};
/* archs that select HAVE_ARCH_HUGE_VMAP should override one or more of these */
@@ -1428,6 +1428,7 @@ adjust_va_to_fit_type(struct rb_root *root, struct list_head *head,
*/
lva->va_start = va->va_start;
lva->va_end = nva_start_addr;
+ lva->vm = va->vm;
/*
* Shrink this VA to remaining size.
@@ -3394,10 +3395,19 @@ void vfree_exec(const void *addr)
spin_unlock(&vmap_area_lock);
spin_lock(&free_text_area_lock);
- merge_or_add_vmap_area_augment(va,
+ va = merge_or_add_vmap_area_augment(va,
&free_text_area_root, &free_text_area_list);
+ if (va) {
+ struct vm_struct *vm = va->vm;
+
+ if (vm != &text_tail_vm) {
+ va = __find_vmap_area((unsigned long)vm->addr,
+ free_text_area_root.rb_node);
+ if (va->va_start == (unsigned long)vm->addr)
+ pr_info("%s TODO: free vm->addr %px\n", __func__, vm->addr);
+ }
+ }
spin_unlock(&free_text_area_lock);
- /* TODO: when the whole vm_struct is not in use, free it */
}
/**