On Fri, Jul 12, 2019 at 08:02:13PM +0800, Pengfei Li wrote: > +++ b/include/linux/vmalloc.h > @@ -51,15 +51,37 @@ struct vmap_area { > unsigned long va_start; > unsigned long va_end; > > - /* > - * Largest available free size in subtree. > - */ > - unsigned long subtree_max_size; > - unsigned long flags; > - struct rb_node rb_node; /* address sorted rbtree */ > - struct list_head list; /* address sorted list */ > - struct llist_node purge_list; /* "lazy purge" list */ > - struct vm_struct *vm; > + union { > + /* In rbtree and list sorted by address */ > + struct { > + union { > + /* > + * In "busy" rbtree and list. > + * rbtree root: vmap_area_root > + * list head: vmap_area_list > + */ > + struct vm_struct *vm; > + > + /* > + * In "free" rbtree and list. > + * rbtree root: free_vmap_area_root > + * list head: free_vmap_area_list > + */ > + unsigned long subtree_max_size; > + }; > + > + struct rb_node rb_node; > + struct list_head list; > + }; > + > + /* > + * In "lazy purge" list. > + * llist head: vmap_purge_list > + */ > + struct { > + struct llist_node purge_list; > + };
I don't think you need struct union struct union. Because llist_node is just a pointer, you can get the same savings with just: union { struct llist_node purge_list; struct vm_struct *vm; unsigned long subtree_max_size; };