diff options
Diffstat (limited to 'mm/vmalloc.c')
-rw-r--r-- | mm/vmalloc.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index f8189a4b3e13..2eb461c3a46e 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
@@ -1122,13 +1122,34 @@ EXPORT_SYMBOL_GPL(map_vm_area); | |||
1122 | DEFINE_RWLOCK(vmlist_lock); | 1122 | DEFINE_RWLOCK(vmlist_lock); |
1123 | struct vm_struct *vmlist; | 1123 | struct vm_struct *vmlist; |
1124 | 1124 | ||
1125 | static void insert_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va, | ||
1126 | unsigned long flags, void *caller) | ||
1127 | { | ||
1128 | struct vm_struct *tmp, **p; | ||
1129 | |||
1130 | vm->flags = flags; | ||
1131 | vm->addr = (void *)va->va_start; | ||
1132 | vm->size = va->va_end - va->va_start; | ||
1133 | vm->caller = caller; | ||
1134 | va->private = vm; | ||
1135 | va->flags |= VM_VM_AREA; | ||
1136 | |||
1137 | write_lock(&vmlist_lock); | ||
1138 | for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) { | ||
1139 | if (tmp->addr >= vm->addr) | ||
1140 | break; | ||
1141 | } | ||
1142 | vm->next = *p; | ||
1143 | *p = vm; | ||
1144 | write_unlock(&vmlist_lock); | ||
1145 | } | ||
1146 | |||
1125 | static struct vm_struct *__get_vm_area_node(unsigned long size, | 1147 | static struct vm_struct *__get_vm_area_node(unsigned long size, |
1126 | unsigned long flags, unsigned long start, unsigned long end, | 1148 | unsigned long flags, unsigned long start, unsigned long end, |
1127 | int node, gfp_t gfp_mask, void *caller) | 1149 | int node, gfp_t gfp_mask, void *caller) |
1128 | { | 1150 | { |
1129 | static struct vmap_area *va; | 1151 | static struct vmap_area *va; |
1130 | struct vm_struct *area; | 1152 | struct vm_struct *area; |
1131 | struct vm_struct *tmp, **p; | ||
1132 | unsigned long align = 1; | 1153 | unsigned long align = 1; |
1133 | 1154 | ||
1134 | BUG_ON(in_interrupt()); | 1155 | BUG_ON(in_interrupt()); |
@@ -1147,7 +1168,7 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, | |||
1147 | if (unlikely(!size)) | 1168 | if (unlikely(!size)) |
1148 | return NULL; | 1169 | return NULL; |
1149 | 1170 | ||
1150 | area = kmalloc_node(sizeof(*area), gfp_mask & GFP_RECLAIM_MASK, node); | 1171 | area = kzalloc_node(sizeof(*area), gfp_mask & GFP_RECLAIM_MASK, node); |
1151 | if (unlikely(!area)) | 1172 | if (unlikely(!area)) |
1152 | return NULL; | 1173 | return NULL; |
1153 | 1174 | ||
@@ -1162,25 +1183,7 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, | |||
1162 | return NULL; | 1183 | return NULL; |
1163 | } | 1184 | } |
1164 | 1185 | ||
1165 | area->flags = flags; | 1186 | insert_vmalloc_vm(area, va, flags, caller); |
1166 | area->addr = (void *)va->va_start; | ||
1167 | area->size = size; | ||
1168 | area->pages = NULL; | ||
1169 | area->nr_pages = 0; | ||
1170 | area->phys_addr = 0; | ||
1171 | area->caller = caller; | ||
1172 | va->private = area; | ||
1173 | va->flags |= VM_VM_AREA; | ||
1174 | |||
1175 | write_lock(&vmlist_lock); | ||
1176 | for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) { | ||
1177 | if (tmp->addr >= area->addr) | ||
1178 | break; | ||
1179 | } | ||
1180 | area->next = *p; | ||
1181 | *p = area; | ||
1182 | write_unlock(&vmlist_lock); | ||
1183 | |||
1184 | return area; | 1187 | return area; |
1185 | } | 1188 | } |
1186 | 1189 | ||