diff options
| -rw-r--r-- | mm/vmalloc.c | 48 | 
1 files changed, 26 insertions, 22 deletions
| diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 69511e663234..4ecbbded98f2 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <asm/atomic.h> | 29 | #include <asm/atomic.h> | 
| 30 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> | 
| 31 | #include <asm/tlbflush.h> | 31 | #include <asm/tlbflush.h> | 
| 32 | #include <asm/shmparam.h> | ||
| 32 | 33 | ||
| 33 | 34 | ||
| 34 | /*** Page table manipulation functions ***/ | 35 | /*** Page table manipulation functions ***/ | 
| @@ -1156,12 +1157,11 @@ static void insert_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va, | |||
| 1156 | } | 1157 | } | 
| 1157 | 1158 | ||
| 1158 | static struct vm_struct *__get_vm_area_node(unsigned long size, | 1159 | static struct vm_struct *__get_vm_area_node(unsigned long size, | 
| 1159 | unsigned long flags, unsigned long start, unsigned long end, | 1160 | unsigned long align, unsigned long flags, unsigned long start, | 
| 1160 | int node, gfp_t gfp_mask, void *caller) | 1161 | unsigned long end, int node, gfp_t gfp_mask, void *caller) | 
| 1161 | { | 1162 | { | 
| 1162 | static struct vmap_area *va; | 1163 | static struct vmap_area *va; | 
| 1163 | struct vm_struct *area; | 1164 | struct vm_struct *area; | 
| 1164 | unsigned long align = 1; | ||
| 1165 | 1165 | ||
| 1166 | BUG_ON(in_interrupt()); | 1166 | BUG_ON(in_interrupt()); | 
| 1167 | if (flags & VM_IOREMAP) { | 1167 | if (flags & VM_IOREMAP) { | 
| @@ -1201,7 +1201,7 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, | |||
| 1201 | struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, | 1201 | struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, | 
| 1202 | unsigned long start, unsigned long end) | 1202 | unsigned long start, unsigned long end) | 
| 1203 | { | 1203 | { | 
| 1204 | return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL, | 1204 | return __get_vm_area_node(size, 1, flags, start, end, -1, GFP_KERNEL, | 
| 1205 | __builtin_return_address(0)); | 1205 | __builtin_return_address(0)); | 
| 1206 | } | 1206 | } | 
| 1207 | EXPORT_SYMBOL_GPL(__get_vm_area); | 1207 | EXPORT_SYMBOL_GPL(__get_vm_area); | 
| @@ -1210,7 +1210,7 @@ struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags, | |||
| 1210 | unsigned long start, unsigned long end, | 1210 | unsigned long start, unsigned long end, | 
| 1211 | void *caller) | 1211 | void *caller) | 
| 1212 | { | 1212 | { | 
| 1213 | return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL, | 1213 | return __get_vm_area_node(size, 1, flags, start, end, -1, GFP_KERNEL, | 
| 1214 | caller); | 1214 | caller); | 
| 1215 | } | 1215 | } | 
| 1216 | 1216 | ||
| @@ -1225,22 +1225,22 @@ struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags, | |||
| 1225 | */ | 1225 | */ | 
| 1226 | struct vm_struct *get_vm_area(unsigned long size, unsigned long flags) | 1226 | struct vm_struct *get_vm_area(unsigned long size, unsigned long flags) | 
| 1227 | { | 1227 | { | 
| 1228 | return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, | 1228 | return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END, | 
| 1229 | -1, GFP_KERNEL, __builtin_return_address(0)); | 1229 | -1, GFP_KERNEL, __builtin_return_address(0)); | 
| 1230 | } | 1230 | } | 
| 1231 | 1231 | ||
| 1232 | struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags, | 1232 | struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags, | 
| 1233 | void *caller) | 1233 | void *caller) | 
| 1234 | { | 1234 | { | 
| 1235 | return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, | 1235 | return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END, | 
| 1236 | -1, GFP_KERNEL, caller); | 1236 | -1, GFP_KERNEL, caller); | 
| 1237 | } | 1237 | } | 
| 1238 | 1238 | ||
| 1239 | struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, | 1239 | struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, | 
| 1240 | int node, gfp_t gfp_mask) | 1240 | int node, gfp_t gfp_mask) | 
| 1241 | { | 1241 | { | 
| 1242 | return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node, | 1242 | return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END, | 
| 1243 | gfp_mask, __builtin_return_address(0)); | 1243 | node, gfp_mask, __builtin_return_address(0)); | 
| 1244 | } | 1244 | } | 
| 1245 | 1245 | ||
| 1246 | static struct vm_struct *find_vm_area(const void *addr) | 1246 | static struct vm_struct *find_vm_area(const void *addr) | 
| @@ -1403,7 +1403,8 @@ void *vmap(struct page **pages, unsigned int count, | |||
| 1403 | } | 1403 | } | 
| 1404 | EXPORT_SYMBOL(vmap); | 1404 | EXPORT_SYMBOL(vmap); | 
| 1405 | 1405 | ||
| 1406 | static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, | 1406 | static void *__vmalloc_node(unsigned long size, unsigned long align, | 
| 1407 | gfp_t gfp_mask, pgprot_t prot, | ||
| 1407 | int node, void *caller); | 1408 | int node, void *caller); | 
| 1408 | static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, | 1409 | static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, | 
| 1409 | pgprot_t prot, int node, void *caller) | 1410 | pgprot_t prot, int node, void *caller) | 
| @@ -1417,7 +1418,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, | |||
| 1417 | area->nr_pages = nr_pages; | 1418 | area->nr_pages = nr_pages; | 
| 1418 | /* Please note that the recursion is strictly bounded. */ | 1419 | /* Please note that the recursion is strictly bounded. */ | 
| 1419 | if (array_size > PAGE_SIZE) { | 1420 | if (array_size > PAGE_SIZE) { | 
| 1420 | pages = __vmalloc_node(array_size, gfp_mask | __GFP_ZERO, | 1421 | pages = __vmalloc_node(array_size, 1, gfp_mask | __GFP_ZERO, | 
| 1421 | PAGE_KERNEL, node, caller); | 1422 | PAGE_KERNEL, node, caller); | 
| 1422 | area->flags |= VM_VPAGES; | 1423 | area->flags |= VM_VPAGES; | 
| 1423 | } else { | 1424 | } else { | 
| @@ -1476,6 +1477,7 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot) | |||
| 1476 | /** | 1477 | /** | 
| 1477 | * __vmalloc_node - allocate virtually contiguous memory | 1478 | * __vmalloc_node - allocate virtually contiguous memory | 
| 1478 | * @size: allocation size | 1479 | * @size: allocation size | 
| 1480 | * @align: desired alignment | ||
| 1479 | * @gfp_mask: flags for the page level allocator | 1481 | * @gfp_mask: flags for the page level allocator | 
| 1480 | * @prot: protection mask for the allocated pages | 1482 | * @prot: protection mask for the allocated pages | 
| 1481 | * @node: node to use for allocation or -1 | 1483 | * @node: node to use for allocation or -1 | 
| @@ -1485,8 +1487,9 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot) | |||
| 1485 | * allocator with @gfp_mask flags. Map them into contiguous | 1487 | * allocator with @gfp_mask flags. Map them into contiguous | 
| 1486 | * kernel virtual space, using a pagetable protection of @prot. | 1488 | * kernel virtual space, using a pagetable protection of @prot. | 
| 1487 | */ | 1489 | */ | 
| 1488 | static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, | 1490 | static void *__vmalloc_node(unsigned long size, unsigned long align, | 
| 1489 | int node, void *caller) | 1491 | gfp_t gfp_mask, pgprot_t prot, | 
| 1492 | int node, void *caller) | ||
| 1490 | { | 1493 | { | 
| 1491 | struct vm_struct *area; | 1494 | struct vm_struct *area; | 
| 1492 | void *addr; | 1495 | void *addr; | 
| @@ -1496,8 +1499,8 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, | |||
| 1496 | if (!size || (size >> PAGE_SHIFT) > totalram_pages) | 1499 | if (!size || (size >> PAGE_SHIFT) > totalram_pages) | 
| 1497 | return NULL; | 1500 | return NULL; | 
| 1498 | 1501 | ||
| 1499 | area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END, | 1502 | area = __get_vm_area_node(size, align, VM_ALLOC, VMALLOC_START, | 
| 1500 | node, gfp_mask, caller); | 1503 | VMALLOC_END, node, gfp_mask, caller); | 
| 1501 | 1504 | ||
| 1502 | if (!area) | 1505 | if (!area) | 
| 1503 | return NULL; | 1506 | return NULL; | 
| @@ -1516,7 +1519,7 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, | |||
| 1516 | 1519 | ||
| 1517 | void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) | 1520 | void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) | 
| 1518 | { | 1521 | { | 
| 1519 | return __vmalloc_node(size, gfp_mask, prot, -1, | 1522 | return __vmalloc_node(size, 1, gfp_mask, prot, -1, | 
| 1520 | __builtin_return_address(0)); | 1523 | __builtin_return_address(0)); | 
| 1521 | } | 1524 | } | 
| 1522 | EXPORT_SYMBOL(__vmalloc); | 1525 | EXPORT_SYMBOL(__vmalloc); | 
| @@ -1532,7 +1535,7 @@ EXPORT_SYMBOL(__vmalloc); | |||
| 1532 | */ | 1535 | */ | 
| 1533 | void *vmalloc(unsigned long size) | 1536 | void *vmalloc(unsigned long size) | 
| 1534 | { | 1537 | { | 
| 1535 | return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, | 1538 | return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, | 
| 1536 | -1, __builtin_return_address(0)); | 1539 | -1, __builtin_return_address(0)); | 
| 1537 | } | 1540 | } | 
| 1538 | EXPORT_SYMBOL(vmalloc); | 1541 | EXPORT_SYMBOL(vmalloc); | 
| @@ -1549,7 +1552,8 @@ void *vmalloc_user(unsigned long size) | |||
| 1549 | struct vm_struct *area; | 1552 | struct vm_struct *area; | 
| 1550 | void *ret; | 1553 | void *ret; | 
| 1551 | 1554 | ||
| 1552 | ret = __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, | 1555 | ret = __vmalloc_node(size, SHMLBA, | 
| 1556 | GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, | ||
| 1553 | PAGE_KERNEL, -1, __builtin_return_address(0)); | 1557 | PAGE_KERNEL, -1, __builtin_return_address(0)); | 
| 1554 | if (ret) { | 1558 | if (ret) { | 
| 1555 | area = find_vm_area(ret); | 1559 | area = find_vm_area(ret); | 
| @@ -1572,7 +1576,7 @@ EXPORT_SYMBOL(vmalloc_user); | |||
| 1572 | */ | 1576 | */ | 
| 1573 | void *vmalloc_node(unsigned long size, int node) | 1577 | void *vmalloc_node(unsigned long size, int node) | 
| 1574 | { | 1578 | { | 
| 1575 | return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, | 1579 | return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, | 
| 1576 | node, __builtin_return_address(0)); | 1580 | node, __builtin_return_address(0)); | 
| 1577 | } | 1581 | } | 
| 1578 | EXPORT_SYMBOL(vmalloc_node); | 1582 | EXPORT_SYMBOL(vmalloc_node); | 
| @@ -1595,7 +1599,7 @@ EXPORT_SYMBOL(vmalloc_node); | |||
| 1595 | 1599 | ||
| 1596 | void *vmalloc_exec(unsigned long size) | 1600 | void *vmalloc_exec(unsigned long size) | 
| 1597 | { | 1601 | { | 
| 1598 | return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC, | 1602 | return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC, | 
| 1599 | -1, __builtin_return_address(0)); | 1603 | -1, __builtin_return_address(0)); | 
| 1600 | } | 1604 | } | 
| 1601 | 1605 | ||
| @@ -1616,7 +1620,7 @@ void *vmalloc_exec(unsigned long size) | |||
| 1616 | */ | 1620 | */ | 
| 1617 | void *vmalloc_32(unsigned long size) | 1621 | void *vmalloc_32(unsigned long size) | 
| 1618 | { | 1622 | { | 
| 1619 | return __vmalloc_node(size, GFP_VMALLOC32, PAGE_KERNEL, | 1623 | return __vmalloc_node(size, 1, GFP_VMALLOC32, PAGE_KERNEL, | 
| 1620 | -1, __builtin_return_address(0)); | 1624 | -1, __builtin_return_address(0)); | 
| 1621 | } | 1625 | } | 
| 1622 | EXPORT_SYMBOL(vmalloc_32); | 1626 | EXPORT_SYMBOL(vmalloc_32); | 
| @@ -1633,7 +1637,7 @@ void *vmalloc_32_user(unsigned long size) | |||
| 1633 | struct vm_struct *area; | 1637 | struct vm_struct *area; | 
| 1634 | void *ret; | 1638 | void *ret; | 
| 1635 | 1639 | ||
| 1636 | ret = __vmalloc_node(size, GFP_VMALLOC32 | __GFP_ZERO, PAGE_KERNEL, | 1640 | ret = __vmalloc_node(size, 1, GFP_VMALLOC32 | __GFP_ZERO, PAGE_KERNEL, | 
| 1637 | -1, __builtin_return_address(0)); | 1641 | -1, __builtin_return_address(0)); | 
| 1638 | if (ret) { | 1642 | if (ret) { | 
| 1639 | area = find_vm_area(ret); | 1643 | area = find_vm_area(ret); | 
