Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/cell: Drop support for 64K local store on 4K kernels

Back in the olden days we added support for using 64K pages to map the
SPU (Synergistic Processing Unit) local store on Cell, when the main
kernel was using 4K pages.

This was useful at the time because distros were using 4K pages, but
using 64K pages on the SPUs could reduce TLB pressure there.

However these days the number of Cell users is approaching zero, and
supporting this option adds unpleasant complexity to the memory
management code.

So drop the option, CONFIG_SPU_FS_64K_LS, and all related code.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Acked-by: Jeremy Kerr <jk@ozlabs.org>

+2 -206
-6
arch/powerpc/include/asm/spu_csa.h
··· 241 241 */ 242 242 struct spu_state { 243 243 struct spu_lscsa *lscsa; 244 - #ifdef CONFIG_SPU_FS_64K_LS 245 - int use_big_pages; 246 - /* One struct page per 64k page */ 247 - #define SPU_LSCSA_NUM_BIG_PAGES (sizeof(struct spu_lscsa) / 0x10000) 248 - struct page *lscsa_pages[SPU_LSCSA_NUM_BIG_PAGES]; 249 - #endif 250 244 struct spu_problem_collapsed prob; 251 245 struct spu_priv1_collapsed priv1; 252 246 struct spu_priv2_collapsed priv2;
-8
arch/powerpc/mm/hugetlbpage.c
··· 808 808 if ((mmu_psize = shift_to_mmu_psize(shift)) < 0) 809 809 return -EINVAL; 810 810 811 - #ifdef CONFIG_SPU_FS_64K_LS 812 - /* Disable support for 64K huge pages when 64K SPU local store 813 - * support is enabled as the current implementation conflicts. 814 - */ 815 - if (shift == PAGE_SHIFT_64K) 816 - return -EINVAL; 817 - #endif /* CONFIG_SPU_FS_64K_LS */ 818 - 819 811 BUG_ON(mmu_psize_defs[mmu_psize].shift != shift); 820 812 821 813 /* Return if huge page size has already been setup */
-15
arch/powerpc/platforms/cell/Kconfig
··· 57 57 Units on machines implementing the Broadband Processor 58 58 Architecture. 59 59 60 - config SPU_FS_64K_LS 61 - bool "Use 64K pages to map SPE local store" 62 - # we depend on PPC_MM_SLICES for now rather than selecting 63 - # it because we depend on hugetlbfs hooks being present. We 64 - # will fix that when the generic code has been improved to 65 - # not require hijacking hugetlbfs hooks. 66 - depends on SPU_FS && PPC_MM_SLICES && !PPC_64K_PAGES 67 - default y 68 - select PPC_HAS_HASH_64K 69 - help 70 - This option causes SPE local stores to be mapped in process 71 - address spaces using 64K pages while the rest of the kernel 72 - uses 4K pages. This can improve performances of applications 73 - using multiple SPEs by lowering the TLB pressure on them. 74 - 75 60 config SPU_BASE 76 61 bool 77 62 default n
-55
arch/powerpc/platforms/cell/spufs/file.c
··· 239 239 unsigned long address = (unsigned long)vmf->virtual_address; 240 240 unsigned long pfn, offset; 241 241 242 - #ifdef CONFIG_SPU_FS_64K_LS 243 - struct spu_state *csa = &ctx->csa; 244 - int psize; 245 - 246 - /* Check what page size we are using */ 247 - psize = get_slice_psize(vma->vm_mm, address); 248 - 249 - /* Some sanity checking */ 250 - BUG_ON(csa->use_big_pages != (psize == MMU_PAGE_64K)); 251 - 252 - /* Wow, 64K, cool, we need to align the address though */ 253 - if (csa->use_big_pages) { 254 - BUG_ON(vma->vm_start & 0xffff); 255 - address &= ~0xfffful; 256 - } 257 - #endif /* CONFIG_SPU_FS_64K_LS */ 258 - 259 242 offset = vmf->pgoff << PAGE_SHIFT; 260 243 if (offset >= LS_SIZE) 261 244 return VM_FAULT_SIGBUS; ··· 293 310 294 311 static int spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) 295 312 { 296 - #ifdef CONFIG_SPU_FS_64K_LS 297 - struct spu_context *ctx = file->private_data; 298 - struct spu_state *csa = &ctx->csa; 299 - 300 - /* Sanity check VMA alignment */ 301 - if (csa->use_big_pages) { 302 - pr_debug("spufs_mem_mmap 64K, start=0x%lx, end=0x%lx," 303 - " pgoff=0x%lx\n", vma->vm_start, vma->vm_end, 304 - vma->vm_pgoff); 305 - if (vma->vm_start & 0xffff) 306 - return -EINVAL; 307 - if (vma->vm_pgoff & 0xf) 308 - return -EINVAL; 309 - } 310 - #endif /* CONFIG_SPU_FS_64K_LS */ 311 - 312 313 if (!(vma->vm_flags & VM_SHARED)) 313 314 return -EINVAL; 314 315 ··· 303 336 return 0; 304 337 } 305 338 306 - #ifdef CONFIG_SPU_FS_64K_LS 307 - static unsigned long spufs_get_unmapped_area(struct file *file, 308 - unsigned long addr, unsigned long len, unsigned long pgoff, 309 - unsigned long flags) 310 - { 311 - struct spu_context *ctx = file->private_data; 312 - struct spu_state *csa = &ctx->csa; 313 - 314 - /* If not using big pages, fallback to normal MM g_u_a */ 315 - if (!csa->use_big_pages) 316 - return current->mm->get_unmapped_area(file, addr, len, 317 - pgoff, flags); 318 - 319 - /* Else, try to obtain a 64K pages slice */ 320 - return slice_get_unmapped_area(addr, len, flags, 321 - MMU_PAGE_64K, 1); 322 - } 323 - #endif /* CONFIG_SPU_FS_64K_LS */ 324 - 325 339 static const struct file_operations spufs_mem_fops = { 326 340 .open = spufs_mem_open, 327 341 .release = spufs_mem_release, ··· 310 362 .write = spufs_mem_write, 311 363 .llseek = generic_file_llseek, 312 364 .mmap = spufs_mem_mmap, 313 - #ifdef CONFIG_SPU_FS_64K_LS 314 - .get_unmapped_area = spufs_get_unmapped_area, 315 - #endif 316 365 }; 317 366 318 367 static int spufs_ps_fault(struct vm_area_struct *vma,
+2 -122
arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
··· 31 31 32 32 #include "spufs.h" 33 33 34 - static int spu_alloc_lscsa_std(struct spu_state *csa) 34 + int spu_alloc_lscsa(struct spu_state *csa) 35 35 { 36 36 struct spu_lscsa *lscsa; 37 37 unsigned char *p; ··· 48 48 return 0; 49 49 } 50 50 51 - static void spu_free_lscsa_std(struct spu_state *csa) 51 + void spu_free_lscsa(struct spu_state *csa) 52 52 { 53 53 /* Clear reserved bit before vfree. */ 54 54 unsigned char *p; ··· 61 61 62 62 vfree(csa->lscsa); 63 63 } 64 - 65 - #ifdef CONFIG_SPU_FS_64K_LS 66 - 67 - #define SPU_64K_PAGE_SHIFT 16 68 - #define SPU_64K_PAGE_ORDER (SPU_64K_PAGE_SHIFT - PAGE_SHIFT) 69 - #define SPU_64K_PAGE_COUNT (1ul << SPU_64K_PAGE_ORDER) 70 - 71 - int spu_alloc_lscsa(struct spu_state *csa) 72 - { 73 - struct page **pgarray; 74 - unsigned char *p; 75 - int i, j, n_4k; 76 - 77 - /* Check availability of 64K pages */ 78 - if (!spu_64k_pages_available()) 79 - goto fail; 80 - 81 - csa->use_big_pages = 1; 82 - 83 - pr_debug("spu_alloc_lscsa(csa=0x%p), trying to allocate 64K pages\n", 84 - csa); 85 - 86 - /* First try to allocate our 64K pages. We need 5 of them 87 - * with the current implementation. In the future, we should try 88 - * to separate the lscsa with the actual local store image, thus 89 - * allowing us to require only 4 64K pages per context 90 - */ 91 - for (i = 0; i < SPU_LSCSA_NUM_BIG_PAGES; i++) { 92 - /* XXX This is likely to fail, we should use a special pool 93 - * similar to what hugetlbfs does. 94 - */ 95 - csa->lscsa_pages[i] = alloc_pages(GFP_KERNEL, 96 - SPU_64K_PAGE_ORDER); 97 - if (csa->lscsa_pages[i] == NULL) 98 - goto fail; 99 - } 100 - 101 - pr_debug(" success ! creating vmap...\n"); 102 - 103 - /* Now we need to create a vmalloc mapping of these for the kernel 104 - * and SPU context switch code to use. Currently, we stick to a 105 - * normal kernel vmalloc mapping, which in our case will be 4K 106 - */ 107 - n_4k = SPU_64K_PAGE_COUNT * SPU_LSCSA_NUM_BIG_PAGES; 108 - pgarray = kmalloc(sizeof(struct page *) * n_4k, GFP_KERNEL); 109 - if (pgarray == NULL) 110 - goto fail; 111 - for (i = 0; i < SPU_LSCSA_NUM_BIG_PAGES; i++) 112 - for (j = 0; j < SPU_64K_PAGE_COUNT; j++) 113 - /* We assume all the struct page's are contiguous 114 - * which should be hopefully the case for an order 4 115 - * allocation.. 116 - */ 117 - pgarray[i * SPU_64K_PAGE_COUNT + j] = 118 - csa->lscsa_pages[i] + j; 119 - csa->lscsa = vmap(pgarray, n_4k, VM_USERMAP, PAGE_KERNEL); 120 - kfree(pgarray); 121 - if (csa->lscsa == NULL) 122 - goto fail; 123 - 124 - memset(csa->lscsa, 0, sizeof(struct spu_lscsa)); 125 - 126 - /* Set LS pages reserved to allow for user-space mapping. 127 - * 128 - * XXX isn't that a bit obsolete ? I think we should just 129 - * make sure the page count is high enough. Anyway, won't harm 130 - * for now 131 - */ 132 - for (p = csa->lscsa->ls; p < csa->lscsa->ls + LS_SIZE; p += PAGE_SIZE) 133 - SetPageReserved(vmalloc_to_page(p)); 134 - 135 - pr_debug(" all good !\n"); 136 - 137 - return 0; 138 - fail: 139 - pr_debug("spufs: failed to allocate lscsa 64K pages, falling back\n"); 140 - spu_free_lscsa(csa); 141 - return spu_alloc_lscsa_std(csa); 142 - } 143 - 144 - void spu_free_lscsa(struct spu_state *csa) 145 - { 146 - unsigned char *p; 147 - int i; 148 - 149 - if (!csa->use_big_pages) { 150 - spu_free_lscsa_std(csa); 151 - return; 152 - } 153 - csa->use_big_pages = 0; 154 - 155 - if (csa->lscsa == NULL) 156 - goto free_pages; 157 - 158 - for (p = csa->lscsa->ls; p < csa->lscsa->ls + LS_SIZE; p += PAGE_SIZE) 159 - ClearPageReserved(vmalloc_to_page(p)); 160 - 161 - vunmap(csa->lscsa); 162 - csa->lscsa = NULL; 163 - 164 - free_pages: 165 - 166 - for (i = 0; i < SPU_LSCSA_NUM_BIG_PAGES; i++) 167 - if (csa->lscsa_pages[i]) 168 - __free_pages(csa->lscsa_pages[i], SPU_64K_PAGE_ORDER); 169 - } 170 - 171 - #else /* CONFIG_SPU_FS_64K_LS */ 172 - 173 - int spu_alloc_lscsa(struct spu_state *csa) 174 - { 175 - return spu_alloc_lscsa_std(csa); 176 - } 177 - 178 - void spu_free_lscsa(struct spu_state *csa) 179 - { 180 - spu_free_lscsa_std(csa); 181 - } 182 - 183 - #endif /* !defined(CONFIG_SPU_FS_64K_LS) */