diff options
author | Jens Axboe <axboe@fb.com> | 2014-09-11 19:31:18 +0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-09-11 19:31:18 +0400 |
commit | b207892b061da7608878e273ae22ba9bf9be264b (patch) | |
tree | 51daa46b89b83cad422941f52110b19571b85b79 /arch/xtensa/mm/highmem.c | |
parent | 018a17bdc8658ad448497c84d4ba21b6985820ec (diff) | |
parent | a516440542afcb9647f88d12c35640baf02d07ea (diff) | |
download | linux-b207892b061da7608878e273ae22ba9bf9be264b.tar.xz |
Merge branch 'for-linus' into for-3.18/core
A bit of churn on the for-linus side that would be nice to have
in the core bits for 3.18, so pull it in to catch us up and make
forward progress easier.
Signed-off-by: Jens Axboe <axboe@fb.com>
Conflicts:
block/scsi_ioctl.c
Diffstat (limited to 'arch/xtensa/mm/highmem.c')
-rw-r--r-- | arch/xtensa/mm/highmem.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/arch/xtensa/mm/highmem.c b/arch/xtensa/mm/highmem.c index 17a8c0d6fd17..8cfb71ec0937 100644 --- a/arch/xtensa/mm/highmem.c +++ b/arch/xtensa/mm/highmem.c @@ -14,23 +14,45 @@ static pte_t *kmap_pte; +#if DCACHE_WAY_SIZE > PAGE_SIZE +unsigned int last_pkmap_nr_arr[DCACHE_N_COLORS]; +wait_queue_head_t pkmap_map_wait_arr[DCACHE_N_COLORS]; + +static void __init kmap_waitqueues_init(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(pkmap_map_wait_arr); ++i) + init_waitqueue_head(pkmap_map_wait_arr + i); +} +#else +static inline void kmap_waitqueues_init(void) +{ +} +#endif + +static inline enum fixed_addresses kmap_idx(int type, unsigned long color) +{ + return (type + KM_TYPE_NR * smp_processor_id()) * DCACHE_N_COLORS + + color; +} + void *kmap_atomic(struct page *page) { enum fixed_addresses idx; unsigned long vaddr; - int type; pagefault_disable(); if (!PageHighMem(page)) return page_address(page); - type = kmap_atomic_idx_push(); - idx = type + KM_TYPE_NR * smp_processor_id(); + idx = kmap_idx(kmap_atomic_idx_push(), + DCACHE_ALIAS(page_to_phys(page))); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); #ifdef CONFIG_DEBUG_HIGHMEM - BUG_ON(!pte_none(*(kmap_pte - idx))); + BUG_ON(!pte_none(*(kmap_pte + idx))); #endif - set_pte(kmap_pte - idx, mk_pte(page, PAGE_KERNEL_EXEC)); + set_pte(kmap_pte + idx, mk_pte(page, PAGE_KERNEL_EXEC)); return (void *)vaddr; } @@ -38,12 +60,10 @@ EXPORT_SYMBOL(kmap_atomic); void __kunmap_atomic(void *kvaddr) { - int idx, type; - if (kvaddr >= (void *)FIXADDR_START && kvaddr < (void *)FIXADDR_TOP) { - type = kmap_atomic_idx(); - idx = type + KM_TYPE_NR * smp_processor_id(); + int idx = kmap_idx(kmap_atomic_idx(), + DCACHE_ALIAS((unsigned long)kvaddr)); /* * Force other mappings to Oops if they'll try to access this @@ -51,7 +71,7 @@ void __kunmap_atomic(void *kvaddr) * is a bad idea also, in case the page changes cacheability * attributes or becomes a protected page in a hypervisor. */ - pte_clear(&init_mm, kvaddr, kmap_pte - idx); + pte_clear(&init_mm, kvaddr, kmap_pte + idx); local_flush_tlb_kernel_range((unsigned long)kvaddr, (unsigned long)kvaddr + PAGE_SIZE); @@ -69,4 +89,5 @@ void __init kmap_init(void) /* cache the first kmap pte */ kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); kmap_pte = kmap_get_fixmap_pte(kmap_vstart); + kmap_waitqueues_init(); } |