diff options
Diffstat (limited to 'mm/vmalloc.c')
| -rw-r--r-- | mm/vmalloc.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 30f826d484f0..7465f22fec0c 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
| @@ -77,7 +77,6 @@ static void vunmap_page_range(unsigned long addr, unsigned long end) | |||
| 77 | 77 | ||
| 78 | BUG_ON(addr >= end); | 78 | BUG_ON(addr >= end); |
| 79 | pgd = pgd_offset_k(addr); | 79 | pgd = pgd_offset_k(addr); |
| 80 | flush_cache_vunmap(addr, end); | ||
| 81 | do { | 80 | do { |
| 82 | next = pgd_addr_end(addr, end); | 81 | next = pgd_addr_end(addr, end); |
| 83 | if (pgd_none_or_clear_bad(pgd)) | 82 | if (pgd_none_or_clear_bad(pgd)) |
| @@ -152,11 +151,12 @@ static int vmap_pud_range(pgd_t *pgd, unsigned long addr, | |||
| 152 | * | 151 | * |
| 153 | * Ie. pte at addr+N*PAGE_SIZE shall point to pfn corresponding to pages[N] | 152 | * Ie. pte at addr+N*PAGE_SIZE shall point to pfn corresponding to pages[N] |
| 154 | */ | 153 | */ |
| 155 | static int vmap_page_range(unsigned long addr, unsigned long end, | 154 | static int vmap_page_range(unsigned long start, unsigned long end, |
| 156 | pgprot_t prot, struct page **pages) | 155 | pgprot_t prot, struct page **pages) |
| 157 | { | 156 | { |
| 158 | pgd_t *pgd; | 157 | pgd_t *pgd; |
| 159 | unsigned long next; | 158 | unsigned long next; |
| 159 | unsigned long addr = start; | ||
| 160 | int err = 0; | 160 | int err = 0; |
| 161 | int nr = 0; | 161 | int nr = 0; |
| 162 | 162 | ||
| @@ -168,7 +168,7 @@ static int vmap_page_range(unsigned long addr, unsigned long end, | |||
| 168 | if (err) | 168 | if (err) |
| 169 | break; | 169 | break; |
| 170 | } while (pgd++, addr = next, addr != end); | 170 | } while (pgd++, addr = next, addr != end); |
| 171 | flush_cache_vmap(addr, end); | 171 | flush_cache_vmap(start, end); |
| 172 | 172 | ||
| 173 | if (unlikely(err)) | 173 | if (unlikely(err)) |
| 174 | return err; | 174 | return err; |
| @@ -543,9 +543,10 @@ static void purge_vmap_area_lazy(void) | |||
| 543 | } | 543 | } |
| 544 | 544 | ||
| 545 | /* | 545 | /* |
| 546 | * Free and unmap a vmap area | 546 | * Free and unmap a vmap area, caller ensuring flush_cache_vunmap had been |
| 547 | * called for the correct range previously. | ||
| 547 | */ | 548 | */ |
| 548 | static void free_unmap_vmap_area(struct vmap_area *va) | 549 | static void free_unmap_vmap_area_noflush(struct vmap_area *va) |
| 549 | { | 550 | { |
| 550 | va->flags |= VM_LAZY_FREE; | 551 | va->flags |= VM_LAZY_FREE; |
| 551 | atomic_add((va->va_end - va->va_start) >> PAGE_SHIFT, &vmap_lazy_nr); | 552 | atomic_add((va->va_end - va->va_start) >> PAGE_SHIFT, &vmap_lazy_nr); |
| @@ -553,6 +554,15 @@ static void free_unmap_vmap_area(struct vmap_area *va) | |||
| 553 | try_purge_vmap_area_lazy(); | 554 | try_purge_vmap_area_lazy(); |
| 554 | } | 555 | } |
| 555 | 556 | ||
| 557 | /* | ||
| 558 | * Free and unmap a vmap area | ||
| 559 | */ | ||
| 560 | static void free_unmap_vmap_area(struct vmap_area *va) | ||
| 561 | { | ||
| 562 | flush_cache_vunmap(va->va_start, va->va_end); | ||
| 563 | free_unmap_vmap_area_noflush(va); | ||
| 564 | } | ||
| 565 | |||
| 556 | static struct vmap_area *find_vmap_area(unsigned long addr) | 566 | static struct vmap_area *find_vmap_area(unsigned long addr) |
| 557 | { | 567 | { |
| 558 | struct vmap_area *va; | 568 | struct vmap_area *va; |
| @@ -734,7 +744,7 @@ static void free_vmap_block(struct vmap_block *vb) | |||
| 734 | spin_unlock(&vmap_block_tree_lock); | 744 | spin_unlock(&vmap_block_tree_lock); |
| 735 | BUG_ON(tmp != vb); | 745 | BUG_ON(tmp != vb); |
| 736 | 746 | ||
| 737 | free_unmap_vmap_area(vb->va); | 747 | free_unmap_vmap_area_noflush(vb->va); |
| 738 | call_rcu(&vb->rcu_head, rcu_free_vb); | 748 | call_rcu(&vb->rcu_head, rcu_free_vb); |
| 739 | } | 749 | } |
| 740 | 750 | ||
| @@ -796,6 +806,9 @@ static void vb_free(const void *addr, unsigned long size) | |||
| 796 | 806 | ||
| 797 | BUG_ON(size & ~PAGE_MASK); | 807 | BUG_ON(size & ~PAGE_MASK); |
| 798 | BUG_ON(size > PAGE_SIZE*VMAP_MAX_ALLOC); | 808 | BUG_ON(size > PAGE_SIZE*VMAP_MAX_ALLOC); |
| 809 | |||
| 810 | flush_cache_vunmap((unsigned long)addr, (unsigned long)addr + size); | ||
| 811 | |||
| 799 | order = get_order(size); | 812 | order = get_order(size); |
| 800 | 813 | ||
| 801 | offset = (unsigned long)addr & (VMAP_BLOCK_SIZE - 1); | 814 | offset = (unsigned long)addr & (VMAP_BLOCK_SIZE - 1); |
| @@ -1705,7 +1718,7 @@ static int s_show(struct seq_file *m, void *p) | |||
| 1705 | v->addr, v->addr + v->size, v->size); | 1718 | v->addr, v->addr + v->size, v->size); |
| 1706 | 1719 | ||
| 1707 | if (v->caller) { | 1720 | if (v->caller) { |
| 1708 | char buff[2 * KSYM_NAME_LEN]; | 1721 | char buff[KSYM_SYMBOL_LEN]; |
| 1709 | 1722 | ||
| 1710 | seq_putc(m, ' '); | 1723 | seq_putc(m, ' '); |
| 1711 | sprint_symbol(buff, (unsigned long)v->caller); | 1724 | sprint_symbol(buff, (unsigned long)v->caller); |
