#endif
 
 struct vm_struct {
+       /* keep next,addr,size together to speedup lookups */
+       struct vm_struct        *next;
        void                    *addr;
        unsigned long           size;
        unsigned long           flags;
        struct page             **pages;
        unsigned int            nr_pages;
        unsigned long           phys_addr;
-       struct vm_struct        *next;
 };
 
 /*
 
        if (unlikely(!area))
                return NULL;
 
-       if (unlikely(!size)) {
-               kfree (area);
+       if (unlikely(!size))
                return NULL;
-       }
 
        /*
         * We always allocate a guard page.
        void *ret;
 
        ret = __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
-       write_lock(&vmlist_lock);
-       area = __find_vm_area(ret);
-       area->flags |= VM_USERMAP;
-       write_unlock(&vmlist_lock);
-
+       if (ret) {
+               write_lock(&vmlist_lock);
+               area = __find_vm_area(ret);
+               area->flags |= VM_USERMAP;
+               write_unlock(&vmlist_lock);
+       }
        return ret;
 }
 EXPORT_SYMBOL(vmalloc_user);
        void *ret;
 
        ret = __vmalloc(size, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
-       write_lock(&vmlist_lock);
-       area = __find_vm_area(ret);
-       area->flags |= VM_USERMAP;
-       write_unlock(&vmlist_lock);
-
+       if (ret) {
+               write_lock(&vmlist_lock);
+               area = __find_vm_area(ret);
+               area->flags |= VM_USERMAP;
+               write_unlock(&vmlist_lock);
+       }
        return ret;
 }
 EXPORT_SYMBOL(vmalloc_32_user);