diff options
| -rw-r--r-- | arch/powerpc/platforms/cell/Kconfig | 15 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/Makefile | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/context.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/file.c | 80 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/lscsa_alloc.c | 181 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/switch.c | 28 | ||||
| -rw-r--r-- | include/asm-powerpc/spu_csa.h | 10 |
7 files changed, 283 insertions, 37 deletions
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 82551770917c..9b2b386ccf48 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig | |||
| @@ -35,6 +35,21 @@ config SPU_FS | |||
| 35 | Units on machines implementing the Broadband Processor | 35 | Units on machines implementing the Broadband Processor |
| 36 | Architecture. | 36 | Architecture. |
| 37 | 37 | ||
| 38 | config SPU_FS_64K_LS | ||
| 39 | bool "Use 64K pages to map SPE local store" | ||
| 40 | # we depend on PPC_MM_SLICES for now rather than selecting | ||
| 41 | # it because we depend on hugetlbfs hooks being present. We | ||
| 42 | # will fix that when the generic code has been improved to | ||
| 43 | # not require hijacking hugetlbfs hooks. | ||
| 44 | depends on SPU_FS && PPC_MM_SLICES && !PPC_64K_PAGES | ||
| 45 | default y | ||
| 46 | select PPC_HAS_HASH_64K | ||
| 47 | help | ||
| 48 | This option causes SPE local stores to be mapped in process | ||
| 49 | address spaces using 64K pages while the rest of the kernel | ||
| 50 | uses 4K pages. This can improve performances of applications | ||
| 51 | using multiple SPEs by lowering the TLB pressure on them. | ||
| 52 | |||
| 38 | config SPU_BASE | 53 | config SPU_BASE |
| 39 | bool | 54 | bool |
| 40 | default n | 55 | default n |
diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile index 2cd89c11af5a..328afcf89503 100644 --- a/arch/powerpc/platforms/cell/spufs/Makefile +++ b/arch/powerpc/platforms/cell/spufs/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | obj-y += switch.o fault.o | 1 | obj-y += switch.o fault.o lscsa_alloc.o |
| 2 | 2 | ||
| 3 | obj-$(CONFIG_SPU_FS) += spufs.o | 3 | obj-$(CONFIG_SPU_FS) += spufs.o |
| 4 | spufs-y += inode.o file.o context.o syscalls.o coredump.o | 4 | spufs-y += inode.o file.o context.o syscalls.o coredump.o |
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index a87d9ca3dba2..8654749e317b 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c | |||
| @@ -36,10 +36,8 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang) | |||
| 36 | /* Binding to physical processor deferred | 36 | /* Binding to physical processor deferred |
| 37 | * until spu_activate(). | 37 | * until spu_activate(). |
| 38 | */ | 38 | */ |
| 39 | spu_init_csa(&ctx->csa); | 39 | if (spu_init_csa(&ctx->csa)) |
| 40 | if (!ctx->csa.lscsa) { | ||
| 41 | goto out_free; | 40 | goto out_free; |
| 42 | } | ||
| 43 | spin_lock_init(&ctx->mmio_lock); | 41 | spin_lock_init(&ctx->mmio_lock); |
| 44 | spin_lock_init(&ctx->mapping_lock); | 42 | spin_lock_init(&ctx->mapping_lock); |
| 45 | kref_init(&ctx->kref); | 43 | kref_init(&ctx->kref); |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index d010b2464a98..45614c73c784 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
| @@ -118,14 +118,32 @@ spufs_mem_write(struct file *file, const char __user *buffer, | |||
| 118 | static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, | 118 | static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, |
| 119 | unsigned long address) | 119 | unsigned long address) |
| 120 | { | 120 | { |
| 121 | struct spu_context *ctx = vma->vm_file->private_data; | 121 | struct spu_context *ctx = vma->vm_file->private_data; |
| 122 | unsigned long pfn, offset = address - vma->vm_start; | 122 | unsigned long pfn, offset, addr0 = address; |
| 123 | 123 | #ifdef CONFIG_SPU_FS_64K_LS | |
| 124 | offset += vma->vm_pgoff << PAGE_SHIFT; | 124 | struct spu_state *csa = &ctx->csa; |
| 125 | int psize; | ||
| 126 | |||
| 127 | /* Check what page size we are using */ | ||
| 128 | psize = get_slice_psize(vma->vm_mm, address); | ||
| 129 | |||
| 130 | /* Some sanity checking */ | ||
| 131 | BUG_ON(csa->use_big_pages != (psize == MMU_PAGE_64K)); | ||
| 132 | |||
| 133 | /* Wow, 64K, cool, we need to align the address though */ | ||
| 134 | if (csa->use_big_pages) { | ||
| 135 | BUG_ON(vma->vm_start & 0xffff); | ||
| 136 | address &= ~0xfffful; | ||
| 137 | } | ||
| 138 | #endif /* CONFIG_SPU_FS_64K_LS */ | ||
| 125 | 139 | ||
| 140 | offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); | ||
| 126 | if (offset >= LS_SIZE) | 141 | if (offset >= LS_SIZE) |
| 127 | return NOPFN_SIGBUS; | 142 | return NOPFN_SIGBUS; |
| 128 | 143 | ||
| 144 | pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n", | ||
| 145 | addr0, address, offset); | ||
| 146 | |||
| 129 | spu_acquire(ctx); | 147 | spu_acquire(ctx); |
| 130 | 148 | ||
| 131 | if (ctx->state == SPU_STATE_SAVED) { | 149 | if (ctx->state == SPU_STATE_SAVED) { |
| @@ -149,9 +167,24 @@ static struct vm_operations_struct spufs_mem_mmap_vmops = { | |||
| 149 | .nopfn = spufs_mem_mmap_nopfn, | 167 | .nopfn = spufs_mem_mmap_nopfn, |
| 150 | }; | 168 | }; |
| 151 | 169 | ||
| 152 | static int | 170 | static int spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) |
| 153 | spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) | 171 | { |
| 154 | { | 172 | #ifdef CONFIG_SPU_FS_64K_LS |
| 173 | struct spu_context *ctx = file->private_data; | ||
| 174 | struct spu_state *csa = &ctx->csa; | ||
| 175 | |||
| 176 | /* Sanity check VMA alignment */ | ||
| 177 | if (csa->use_big_pages) { | ||
| 178 | pr_debug("spufs_mem_mmap 64K, start=0x%lx, end=0x%lx," | ||
| 179 | " pgoff=0x%lx\n", vma->vm_start, vma->vm_end, | ||
| 180 | vma->vm_pgoff); | ||
| 181 | if (vma->vm_start & 0xffff) | ||
| 182 | return -EINVAL; | ||
| 183 | if (vma->vm_pgoff & 0xf) | ||
| 184 | return -EINVAL; | ||
| 185 | } | ||
| 186 | #endif /* CONFIG_SPU_FS_64K_LS */ | ||
| 187 | |||
| 155 | if (!(vma->vm_flags & VM_SHARED)) | 188 | if (!(vma->vm_flags & VM_SHARED)) |
| 156 | return -EINVAL; | 189 | return -EINVAL; |
| 157 | 190 | ||
| @@ -163,13 +196,34 @@ spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 163 | return 0; | 196 | return 0; |
| 164 | } | 197 | } |
| 165 | 198 | ||
| 199 | #ifdef CONFIG_SPU_FS_64K_LS | ||
| 200 | unsigned long spufs_get_unmapped_area(struct file *file, unsigned long addr, | ||
| 201 | unsigned long len, unsigned long pgoff, | ||
| 202 | unsigned long flags) | ||
| 203 | { | ||
| 204 | struct spu_context *ctx = file->private_data; | ||
| 205 | struct spu_state *csa = &ctx->csa; | ||
| 206 | |||
| 207 | /* If not using big pages, fallback to normal MM g_u_a */ | ||
| 208 | if (!csa->use_big_pages) | ||
| 209 | return current->mm->get_unmapped_area(file, addr, len, | ||
| 210 | pgoff, flags); | ||
| 211 | |||
| 212 | /* Else, try to obtain a 64K pages slice */ | ||
| 213 | return slice_get_unmapped_area(addr, len, flags, | ||
| 214 | MMU_PAGE_64K, 1, 0); | ||
| 215 | } | ||
| 216 | #endif /* CONFIG_SPU_FS_64K_LS */ | ||
| 217 | |||
| 166 | static const struct file_operations spufs_mem_fops = { | 218 | static const struct file_operations spufs_mem_fops = { |
| 167 | .open = spufs_mem_open, | 219 | .open = spufs_mem_open, |
| 168 | .release = spufs_mem_release, | 220 | .read = spufs_mem_read, |
| 169 | .read = spufs_mem_read, | 221 | .write = spufs_mem_write, |
| 170 | .write = spufs_mem_write, | 222 | .llseek = generic_file_llseek, |
| 171 | .llseek = generic_file_llseek, | 223 | .mmap = spufs_mem_mmap, |
| 172 | .mmap = spufs_mem_mmap, | 224 | #ifdef CONFIG_SPU_FS_64K_LS |
| 225 | .get_unmapped_area = spufs_get_unmapped_area, | ||
| 226 | #endif | ||
| 173 | }; | 227 | }; |
| 174 | 228 | ||
| 175 | static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, | 229 | static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, |
diff --git a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c new file mode 100644 index 000000000000..f4b3c052dabf --- /dev/null +++ b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c | |||
| @@ -0,0 +1,181 @@ | |||
| 1 | /* | ||
| 2 | * SPU local store allocation routines | ||
| 3 | * | ||
| 4 | * Copyright 2007 Benjamin Herrenschmidt, IBM Corp. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 9 | * any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #undef DEBUG | ||
| 22 | |||
| 23 | #include <linux/kernel.h> | ||
| 24 | #include <linux/mm.h> | ||
| 25 | #include <linux/vmalloc.h> | ||
| 26 | |||
| 27 | #include <asm/spu.h> | ||
| 28 | #include <asm/spu_csa.h> | ||
| 29 | #include <asm/mmu.h> | ||
| 30 | |||
| 31 | static int spu_alloc_lscsa_std(struct spu_state *csa) | ||
| 32 | { | ||
| 33 | struct spu_lscsa *lscsa; | ||
| 34 | unsigned char *p; | ||
| 35 | |||
| 36 | lscsa = vmalloc(sizeof(struct spu_lscsa)); | ||
| 37 | if (!lscsa) | ||
| 38 | return -ENOMEM; | ||
| 39 | memset(lscsa, 0, sizeof(struct spu_lscsa)); | ||
| 40 | csa->lscsa = lscsa; | ||
| 41 | |||
| 42 | /* Set LS pages reserved to allow for user-space mapping. */ | ||
| 43 | for (p = lscsa->ls; p < lscsa->ls + LS_SIZE; p += PAGE_SIZE) | ||
| 44 | SetPageReserved(vmalloc_to_page(p)); | ||
| 45 | |||
| 46 | return 0; | ||
| 47 | } | ||
| 48 | |||
| 49 | static void spu_free_lscsa_std(struct spu_state *csa) | ||
| 50 | { | ||
| 51 | /* Clear reserved bit before vfree. */ | ||
| 52 | unsigned char *p; | ||
| 53 | |||
| 54 | if (csa->lscsa == NULL) | ||
| 55 | return; | ||
| 56 | |||
| 57 | for (p = csa->lscsa->ls; p < csa->lscsa->ls + LS_SIZE; p += PAGE_SIZE) | ||
| 58 | ClearPageReserved(vmalloc_to_page(p)); | ||
| 59 | |||
| 60 | vfree(csa->lscsa); | ||
| 61 | } | ||
| 62 | |||
| 63 | #ifdef CONFIG_SPU_FS_64K_LS | ||
| 64 | |||
| 65 | #define SPU_64K_PAGE_SHIFT 16 | ||
| 66 | #define SPU_64K_PAGE_ORDER (SPU_64K_PAGE_SHIFT - PAGE_SHIFT) | ||
| 67 | #define SPU_64K_PAGE_COUNT (1ul << SPU_64K_PAGE_ORDER) | ||
| 68 | |||
| 69 | int spu_alloc_lscsa(struct spu_state *csa) | ||
| 70 | { | ||
| 71 | struct page **pgarray; | ||
| 72 | unsigned char *p; | ||
| 73 | int i, j, n_4k; | ||
| 74 | |||
| 75 | /* Check availability of 64K pages */ | ||
| 76 | if (mmu_psize_defs[MMU_PAGE_64K].shift == 0) | ||
| 77 | goto fail; | ||
| 78 | |||
| 79 | csa->use_big_pages = 1; | ||
| 80 | |||
| 81 | pr_debug("spu_alloc_lscsa(csa=0x%p), trying to allocate 64K pages\n", | ||
| 82 | csa); | ||
| 83 | |||
| 84 | /* First try to allocate our 64K pages. We need 5 of them | ||
| 85 | * with the current implementation. In the future, we should try | ||
| 86 | * to separate the lscsa with the actual local store image, thus | ||
| 87 | * allowing us to require only 4 64K pages per context | ||
| 88 | */ | ||
| 89 | for (i = 0; i < SPU_LSCSA_NUM_BIG_PAGES; i++) { | ||
| 90 | /* XXX This is likely to fail, we should use a special pool | ||
| 91 | * similiar to what hugetlbfs does. | ||
| 92 | */ | ||
| 93 | csa->lscsa_pages[i] = alloc_pages(GFP_KERNEL, | ||
| 94 | SPU_64K_PAGE_ORDER); | ||
| 95 | if (csa->lscsa_pages[i] == NULL) | ||
| 96 | goto fail; | ||
| 97 | } | ||
| 98 | |||
| 99 | pr_debug(" success ! creating vmap...\n"); | ||
| 100 | |||
| 101 | /* Now we need to create a vmalloc mapping of these for the kernel | ||
| 102 | * and SPU context switch code to use. Currently, we stick to a | ||
| 103 | * normal kernel vmalloc mapping, which in our case will be 4K | ||
| 104 | */ | ||
| 105 | n_4k = SPU_64K_PAGE_COUNT * SPU_LSCSA_NUM_BIG_PAGES; | ||
| 106 | pgarray = kmalloc(sizeof(struct page *) * n_4k, GFP_KERNEL); | ||
| 107 | if (pgarray == NULL) | ||
| 108 | goto fail; | ||
| 109 | for (i = 0; i < SPU_LSCSA_NUM_BIG_PAGES; i++) | ||
| 110 | for (j = 0; j < SPU_64K_PAGE_COUNT; j++) | ||
| 111 | /* We assume all the struct page's are contiguous | ||
| 112 | * which should be hopefully the case for an order 4 | ||
| 113 | * allocation.. | ||
| 114 | */ | ||
| 115 | pgarray[i * SPU_64K_PAGE_COUNT + j] = | ||
| 116 | csa->lscsa_pages[i] + j; | ||
| 117 | csa->lscsa = vmap(pgarray, n_4k, VM_USERMAP, PAGE_KERNEL); | ||
| 118 | kfree(pgarray); | ||
| 119 | if (csa->lscsa == NULL) | ||
| 120 | goto fail; | ||
| 121 | |||
| 122 | memset(csa->lscsa, 0, sizeof(struct spu_lscsa)); | ||
| 123 | |||
| 124 | /* Set LS pages reserved to allow for user-space mapping. | ||
| 125 | * | ||
| 126 | * XXX isn't that a bit obsolete ? I think we should just | ||
| 127 | * make sure the page count is high enough. Anyway, won't harm | ||
| 128 | * for now | ||
| 129 | */ | ||
| 130 | for (p = csa->lscsa->ls; p < csa->lscsa->ls + LS_SIZE; p += PAGE_SIZE) | ||
| 131 | SetPageReserved(vmalloc_to_page(p)); | ||
| 132 | |||
| 133 | pr_debug(" all good !\n"); | ||
| 134 | |||
| 135 | return 0; | ||
| 136 | fail: | ||
| 137 | pr_debug("spufs: failed to allocate lscsa 64K pages, falling back\n"); | ||
| 138 | spu_free_lscsa(csa); | ||
| 139 | return spu_alloc_lscsa_std(csa); | ||
| 140 | } | ||
| 141 | |||
| 142 | void spu_free_lscsa(struct spu_state *csa) | ||
| 143 | { | ||
| 144 | unsigned char *p; | ||
| 145 | int i; | ||
| 146 | |||
| 147 | if (!csa->use_big_pages) { | ||
| 148 | spu_free_lscsa_std(csa); | ||
| 149 | return; | ||
| 150 | } | ||
| 151 | csa->use_big_pages = 0; | ||
| 152 | |||
| 153 | if (csa->lscsa == NULL) | ||
| 154 | goto free_pages; | ||
| 155 | |||
| 156 | for (p = csa->lscsa->ls; p < csa->lscsa->ls + LS_SIZE; p += PAGE_SIZE) | ||
| 157 | ClearPageReserved(vmalloc_to_page(p)); | ||
| 158 | |||
| 159 | vunmap(csa->lscsa); | ||
| 160 | csa->lscsa = NULL; | ||
| 161 | |||
| 162 | free_pages: | ||
| 163 | |||
| 164 | for (i = 0; i < SPU_LSCSA_NUM_BIG_PAGES; i++) | ||
| 165 | if (csa->lscsa_pages[i]) | ||
| 166 | __free_pages(csa->lscsa_pages[i], SPU_64K_PAGE_ORDER); | ||
| 167 | } | ||
| 168 | |||
| 169 | #else /* CONFIG_SPU_FS_64K_LS */ | ||
| 170 | |||
| 171 | int spu_alloc_lscsa(struct spu_state *csa) | ||
| 172 | { | ||
| 173 | return spu_alloc_lscsa_std(csa); | ||
| 174 | } | ||
| 175 | |||
| 176 | void spu_free_lscsa(struct spu_state *csa) | ||
| 177 | { | ||
| 178 | spu_free_lscsa_std(csa); | ||
| 179 | } | ||
| 180 | |||
| 181 | #endif /* !defined(CONFIG_SPU_FS_64K_LS) */ | ||
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 29dc59cefc38..71a0b41adb8c 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c | |||
| @@ -2188,40 +2188,30 @@ static void init_priv2(struct spu_state *csa) | |||
| 2188 | * as it is by far the largest of the context save regions, | 2188 | * as it is by far the largest of the context save regions, |
| 2189 | * and may need to be pinned or otherwise specially aligned. | 2189 | * and may need to be pinned or otherwise specially aligned. |
| 2190 | */ | 2190 | */ |
| 2191 | void spu_init_csa(struct spu_state *csa) | 2191 | int spu_init_csa(struct spu_state *csa) |
| 2192 | { | 2192 | { |
| 2193 | struct spu_lscsa *lscsa; | 2193 | int rc; |
| 2194 | unsigned char *p; | ||
| 2195 | 2194 | ||
| 2196 | if (!csa) | 2195 | if (!csa) |
| 2197 | return; | 2196 | return -EINVAL; |
| 2198 | memset(csa, 0, sizeof(struct spu_state)); | 2197 | memset(csa, 0, sizeof(struct spu_state)); |
| 2199 | 2198 | ||
| 2200 | lscsa = vmalloc(sizeof(struct spu_lscsa)); | 2199 | rc = spu_alloc_lscsa(csa); |
| 2201 | if (!lscsa) | 2200 | if (rc) |
| 2202 | return; | 2201 | return rc; |
| 2203 | 2202 | ||
| 2204 | memset(lscsa, 0, sizeof(struct spu_lscsa)); | ||
| 2205 | csa->lscsa = lscsa; | ||
| 2206 | spin_lock_init(&csa->register_lock); | 2203 | spin_lock_init(&csa->register_lock); |
| 2207 | 2204 | ||
| 2208 | /* Set LS pages reserved to allow for user-space mapping. */ | ||
| 2209 | for (p = lscsa->ls; p < lscsa->ls + LS_SIZE; p += PAGE_SIZE) | ||
| 2210 | SetPageReserved(vmalloc_to_page(p)); | ||
| 2211 | |||
| 2212 | init_prob(csa); | 2205 | init_prob(csa); |
| 2213 | init_priv1(csa); | 2206 | init_priv1(csa); |
| 2214 | init_priv2(csa); | 2207 | init_priv2(csa); |
| 2208 | |||
| 2209 | return 0; | ||
| 2215 | } | 2210 | } |
| 2216 | EXPORT_SYMBOL_GPL(spu_init_csa); | 2211 | EXPORT_SYMBOL_GPL(spu_init_csa); |
| 2217 | 2212 | ||
| 2218 | void spu_fini_csa(struct spu_state *csa) | 2213 | void spu_fini_csa(struct spu_state *csa) |
| 2219 | { | 2214 | { |
| 2220 | /* Clear reserved bit before vfree. */ | 2215 | spu_free_lscsa(csa); |
| 2221 | unsigned char *p; | ||
| 2222 | for (p = csa->lscsa->ls; p < csa->lscsa->ls + LS_SIZE; p += PAGE_SIZE) | ||
| 2223 | ClearPageReserved(vmalloc_to_page(p)); | ||
| 2224 | |||
| 2225 | vfree(csa->lscsa); | ||
| 2226 | } | 2216 | } |
| 2227 | EXPORT_SYMBOL_GPL(spu_fini_csa); | 2217 | EXPORT_SYMBOL_GPL(spu_fini_csa); |
diff --git a/include/asm-powerpc/spu_csa.h b/include/asm-powerpc/spu_csa.h index 02e56a6685a2..c48ae185c874 100644 --- a/include/asm-powerpc/spu_csa.h +++ b/include/asm-powerpc/spu_csa.h | |||
| @@ -235,6 +235,12 @@ struct spu_priv2_collapsed { | |||
| 235 | */ | 235 | */ |
| 236 | struct spu_state { | 236 | struct spu_state { |
| 237 | struct spu_lscsa *lscsa; | 237 | struct spu_lscsa *lscsa; |
| 238 | #ifdef CONFIG_SPU_FS_64K_LS | ||
| 239 | int use_big_pages; | ||
| 240 | /* One struct page per 64k page */ | ||
| 241 | #define SPU_LSCSA_NUM_BIG_PAGES (sizeof(struct spu_lscsa) / 0x10000) | ||
| 242 | struct page *lscsa_pages[SPU_LSCSA_NUM_BIG_PAGES]; | ||
| 243 | #endif | ||
| 238 | struct spu_problem_collapsed prob; | 244 | struct spu_problem_collapsed prob; |
| 239 | struct spu_priv1_collapsed priv1; | 245 | struct spu_priv1_collapsed priv1; |
| 240 | struct spu_priv2_collapsed priv2; | 246 | struct spu_priv2_collapsed priv2; |
| @@ -247,12 +253,14 @@ struct spu_state { | |||
| 247 | spinlock_t register_lock; | 253 | spinlock_t register_lock; |
| 248 | }; | 254 | }; |
| 249 | 255 | ||
| 250 | extern void spu_init_csa(struct spu_state *csa); | 256 | extern int spu_init_csa(struct spu_state *csa); |
| 251 | extern void spu_fini_csa(struct spu_state *csa); | 257 | extern void spu_fini_csa(struct spu_state *csa); |
| 252 | extern int spu_save(struct spu_state *prev, struct spu *spu); | 258 | extern int spu_save(struct spu_state *prev, struct spu *spu); |
| 253 | extern int spu_restore(struct spu_state *new, struct spu *spu); | 259 | extern int spu_restore(struct spu_state *new, struct spu *spu); |
| 254 | extern int spu_switch(struct spu_state *prev, struct spu_state *new, | 260 | extern int spu_switch(struct spu_state *prev, struct spu_state *new, |
| 255 | struct spu *spu); | 261 | struct spu *spu); |
| 262 | extern int spu_alloc_lscsa(struct spu_state *csa); | ||
| 263 | extern void spu_free_lscsa(struct spu_state *csa); | ||
| 256 | 264 | ||
| 257 | #endif /* !__SPU__ */ | 265 | #endif /* !__SPU__ */ |
| 258 | #endif /* __KERNEL__ */ | 266 | #endif /* __KERNEL__ */ |
