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

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc

* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc:
[POWERPC] cell: fix bugs found by sparse
[POWERPC] spiderpic: enable new style devtree support
[POWERPC] Update cell_defconfig
[POWERPC] spufs: add infrastructure for finding elf objects
[POWERPC] spufs: support new OF device tree format
[POWERPC] spufs: add support for read/write on cntl
[POWERPC] spufs: remove support for ancient firmware
[POWERPC] spufs: make mailbox functions handle multiple elements
[POWERPC] spufs: use correct pg_prot for mapping SPU local store
[POWERPC] spufs: Add infrastructure needed for gang scheduling
[POWERPC] spufs: implement error event delivery to user space
[POWERPC] spufs: fix context switch during page fault
[POWERPC] spufs: scheduler support for NUMA.
[POWERPC] spufs: cell spu problem state mapping updates

+1035 -514
+46 -14
arch/powerpc/configs/cell_defconfig
··· 1 1 # 2 2 # Automatically generated make config: don't edit 3 - # Linux kernel version: 2.6.18-rc6 4 - # Sun Sep 10 10:20:32 2006 3 + # Linux kernel version: 2.6.18 4 + # Wed Oct 4 15:30:50 2006 5 5 # 6 6 CONFIG_PPC64=y 7 7 CONFIG_64BIT=y ··· 22 22 CONFIG_PPC_OF=y 23 23 CONFIG_PPC_UDBG_16550=y 24 24 # CONFIG_GENERIC_TBSYNC is not set 25 + CONFIG_AUDIT_ARCH=y 25 26 # CONFIG_DEFAULT_UIMAGE is not set 26 27 27 28 # ··· 53 52 CONFIG_LOCALVERSION_AUTO=y 54 53 CONFIG_SWAP=y 55 54 CONFIG_SYSVIPC=y 55 + # CONFIG_IPC_NS is not set 56 56 # CONFIG_POSIX_MQUEUE is not set 57 57 # CONFIG_BSD_PROCESS_ACCT is not set 58 58 # CONFIG_TASKSTATS is not set 59 - CONFIG_SYSCTL=y 59 + # CONFIG_UTS_NS is not set 60 60 # CONFIG_AUDIT is not set 61 61 CONFIG_IKCONFIG=y 62 62 CONFIG_IKCONFIG_PROC=y ··· 65 63 # CONFIG_RELAY is not set 66 64 CONFIG_INITRAMFS_SOURCE="" 67 65 CONFIG_CC_OPTIMIZE_FOR_SIZE=y 66 + CONFIG_SYSCTL=y 68 67 # CONFIG_EMBEDDED is not set 68 + # CONFIG_SYSCTL_SYSCALL is not set 69 69 CONFIG_KALLSYMS=y 70 70 # CONFIG_KALLSYMS_ALL is not set 71 71 # CONFIG_KALLSYMS_EXTRA_PASS is not set ··· 76 72 CONFIG_BUG=y 77 73 CONFIG_ELF_CORE=y 78 74 CONFIG_BASE_FULL=y 79 - CONFIG_RT_MUTEXES=y 80 75 CONFIG_FUTEX=y 81 76 CONFIG_EPOLL=y 82 77 CONFIG_SHMEM=y 83 78 CONFIG_SLAB=y 84 79 CONFIG_VM_EVENT_COUNTERS=y 80 + CONFIG_RT_MUTEXES=y 85 81 # CONFIG_TINY_SHMEM is not set 86 82 CONFIG_BASE_SMALL=0 87 83 # CONFIG_SLOB is not set ··· 100 96 # 101 97 # Block layer 102 98 # 99 + CONFIG_BLOCK=y 103 100 # CONFIG_BLK_DEV_IO_TRACE is not set 104 101 105 102 # ··· 120 115 # Platform support 121 116 # 122 117 CONFIG_PPC_MULTIPLATFORM=y 123 - # CONFIG_PPC_ISERIES is not set 124 118 # CONFIG_EMBEDDED6xx is not set 125 119 # CONFIG_APUS is not set 126 120 # CONFIG_PPC_PSERIES is not set 121 + # CONFIG_PPC_ISERIES is not set 127 122 # CONFIG_PPC_PMAC is not set 128 123 # CONFIG_PPC_MAPLE is not set 124 + # CONFIG_PPC_PASEMI is not set 129 125 CONFIG_PPC_CELL=y 130 126 CONFIG_PPC_CELL_NATIVE=y 131 127 CONFIG_PPC_IBM_CELL_BLADE=y ··· 148 142 # 149 143 CONFIG_SPU_FS=m 150 144 CONFIG_SPU_BASE=y 151 - CONFIG_SPUFS_MMAP=y 152 145 CONFIG_CBE_RAS=y 153 146 154 147 # ··· 163 158 CONFIG_PREEMPT_BKL=y 164 159 CONFIG_BINFMT_ELF=y 165 160 CONFIG_BINFMT_MISC=m 166 - CONFIG_FORCE_MAX_ZONEORDER=13 161 + CONFIG_FORCE_MAX_ZONEORDER=9 167 162 # CONFIG_IOMMU_VMERGE is not set 168 163 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y 169 164 CONFIG_KEXEC=y ··· 173 168 CONFIG_NODES_SHIFT=4 174 169 CONFIG_ARCH_SELECT_MEMORY_MODEL=y 175 170 CONFIG_ARCH_SPARSEMEM_ENABLE=y 171 + CONFIG_ARCH_POPULATES_NODE_MAP=y 176 172 CONFIG_SELECT_MEMORY_MODEL=y 177 173 # CONFIG_FLATMEM_MANUAL is not set 178 174 # CONFIG_DISCONTIGMEM_MANUAL is not set ··· 184 178 # CONFIG_SPARSEMEM_STATIC is not set 185 179 CONFIG_SPARSEMEM_EXTREME=y 186 180 CONFIG_MEMORY_HOTPLUG=y 181 + CONFIG_MEMORY_HOTPLUG_SPARSE=y 187 182 CONFIG_SPLIT_PTLOCK_CPUS=4 188 183 CONFIG_MIGRATION=y 189 184 CONFIG_RESOURCES_64BIT=y 190 - CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y 191 185 CONFIG_ARCH_MEMORY_PROBE=y 192 - # CONFIG_PPC_64K_PAGES is not set 186 + CONFIG_PPC_64K_PAGES=y 193 187 CONFIG_SCHED_SMT=y 194 188 CONFIG_PROC_DEVICETREE=y 195 189 # CONFIG_CMDLINE_BOOL is not set ··· 207 201 CONFIG_PCI=y 208 202 CONFIG_PCI_DOMAINS=y 209 203 CONFIG_PCIEPORTBUS=y 204 + # CONFIG_PCI_MULTITHREAD_PROBE is not set 210 205 # CONFIG_PCI_DEBUG is not set 211 206 212 207 # ··· 235 228 CONFIG_UNIX=y 236 229 CONFIG_XFRM=y 237 230 # CONFIG_XFRM_USER is not set 231 + # CONFIG_XFRM_SUB_POLICY is not set 238 232 # CONFIG_NET_KEY is not set 239 233 CONFIG_INET=y 240 234 CONFIG_IP_MULTICAST=y ··· 257 249 CONFIG_INET_DIAG=y 258 250 CONFIG_INET_TCP_DIAG=y 259 251 # CONFIG_TCP_CONG_ADVANCED is not set 260 - CONFIG_TCP_CONG_BIC=y 252 + CONFIG_TCP_CONG_CUBIC=y 253 + CONFIG_DEFAULT_TCP_CONG="cubic" 261 254 262 255 # 263 256 # IP: Virtual Server Configuration ··· 270 261 CONFIG_INET6_AH=m 271 262 CONFIG_INET6_ESP=m 272 263 CONFIG_INET6_IPCOMP=m 264 + # CONFIG_IPV6_MIP6 is not set 273 265 CONFIG_INET6_XFRM_TUNNEL=m 274 266 CONFIG_INET6_TUNNEL=m 275 267 CONFIG_INET6_XFRM_MODE_TRANSPORT=y 276 268 CONFIG_INET6_XFRM_MODE_TUNNEL=y 269 + # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set 277 270 CONFIG_IPV6_TUNNEL=m 271 + # CONFIG_IPV6_SUBTREES is not set 272 + # CONFIG_IPV6_MULTIPLE_TABLES is not set 278 273 # CONFIG_NETWORK_SECMARK is not set 279 274 CONFIG_NETFILTER=y 280 275 # CONFIG_NETFILTER_DEBUG is not set ··· 335 322 # CONFIG_ATALK is not set 336 323 # CONFIG_X25 is not set 337 324 # CONFIG_LAPB is not set 338 - # CONFIG_NET_DIVERT is not set 339 325 # CONFIG_ECONET is not set 340 326 # CONFIG_WAN_ROUTER is not set 341 327 ··· 446 434 # CONFIG_BLK_DEV_CS5530 is not set 447 435 # CONFIG_BLK_DEV_HPT34X is not set 448 436 # CONFIG_BLK_DEV_HPT366 is not set 437 + # CONFIG_BLK_DEV_JMICRON is not set 449 438 # CONFIG_BLK_DEV_SC1200 is not set 450 439 # CONFIG_BLK_DEV_PIIX is not set 451 440 # CONFIG_BLK_DEV_IT821X is not set ··· 469 456 # 470 457 # CONFIG_RAID_ATTRS is not set 471 458 # CONFIG_SCSI is not set 459 + # CONFIG_SCSI_NETLINK is not set 460 + 461 + # 462 + # Serial ATA (prod) and Parallel ATA (experimental) drivers 463 + # 464 + # CONFIG_ATA is not set 472 465 473 466 # 474 467 # Multi-device support (RAID and LVM) ··· 489 470 # CONFIG_MD_MULTIPATH is not set 490 471 # CONFIG_MD_FAULTY is not set 491 472 CONFIG_BLK_DEV_DM=m 473 + # CONFIG_DM_DEBUG is not set 492 474 CONFIG_DM_CRYPT=m 493 475 CONFIG_DM_SNAPSHOT=m 494 476 CONFIG_DM_MIRROR=m ··· 524 504 # CONFIG_DUMMY is not set 525 505 CONFIG_BONDING=y 526 506 # CONFIG_EQUALIZER is not set 527 - # CONFIG_TUN is not set 507 + CONFIG_TUN=y 528 508 529 509 # 530 510 # ARCnet devices ··· 572 552 # CONFIG_TIGON3 is not set 573 553 # CONFIG_BNX2 is not set 574 554 CONFIG_SPIDER_NET=m 575 - # CONFIG_MV643XX_ETH is not set 555 + # CONFIG_QLA3XXX is not set 576 556 577 557 # 578 558 # Ethernet (10000 Mbit) ··· 619 599 # Input device support 620 600 # 621 601 CONFIG_INPUT=y 602 + # CONFIG_INPUT_FF_MEMLESS is not set 622 603 623 604 # 624 605 # Userland interfaces ··· 886 865 CONFIG_INFINIBAND_ADDR_TRANS=y 887 866 CONFIG_INFINIBAND_MTHCA=m 888 867 CONFIG_INFINIBAND_MTHCA_DEBUG=y 868 + # CONFIG_INFINIBAND_AMSO1100 is not set 889 869 CONFIG_INFINIBAND_IPOIB=m 890 870 CONFIG_INFINIBAND_IPOIB_DEBUG=y 891 871 CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y ··· 938 916 # CONFIG_QUOTA is not set 939 917 CONFIG_DNOTIFY=y 940 918 # CONFIG_AUTOFS_FS is not set 941 - # CONFIG_AUTOFS4_FS is not set 919 + CONFIG_AUTOFS4_FS=m 942 920 # CONFIG_FUSE_FS is not set 943 921 944 922 # ··· 965 943 # 966 944 CONFIG_PROC_FS=y 967 945 CONFIG_PROC_KCORE=y 946 + CONFIG_PROC_SYSCTL=y 968 947 CONFIG_SYSFS=y 969 948 CONFIG_TMPFS=y 949 + # CONFIG_TMPFS_POSIX_ACL is not set 970 950 CONFIG_HUGETLBFS=y 971 951 CONFIG_HUGETLB_PAGE=y 972 952 CONFIG_RAMFS=y ··· 1108 1084 # Kernel hacking 1109 1085 # 1110 1086 # CONFIG_PRINTK_TIME is not set 1087 + # CONFIG_ENABLE_MUST_CHECK is not set 1111 1088 CONFIG_MAGIC_SYSRQ=y 1112 1089 # CONFIG_UNUSED_SYMBOLS is not set 1113 1090 CONFIG_DEBUG_KERNEL=y ··· 1127 1102 # CONFIG_DEBUG_INFO is not set 1128 1103 CONFIG_DEBUG_FS=y 1129 1104 # CONFIG_DEBUG_VM is not set 1105 + # CONFIG_DEBUG_LIST is not set 1130 1106 # CONFIG_FORCED_INLINING is not set 1131 1107 # CONFIG_RCU_TORTURE_TEST is not set 1132 1108 # CONFIG_DEBUG_STACKOVERFLOW is not set ··· 1149 1123 # Cryptographic options 1150 1124 # 1151 1125 CONFIG_CRYPTO=y 1126 + CONFIG_CRYPTO_ALGAPI=y 1127 + CONFIG_CRYPTO_BLKCIPHER=m 1128 + CONFIG_CRYPTO_HASH=y 1129 + # CONFIG_CRYPTO_MANAGER is not set 1152 1130 CONFIG_CRYPTO_HMAC=y 1153 1131 # CONFIG_CRYPTO_NULL is not set 1154 1132 # CONFIG_CRYPTO_MD4 is not set ··· 1162 1132 # CONFIG_CRYPTO_SHA512 is not set 1163 1133 # CONFIG_CRYPTO_WP512 is not set 1164 1134 # CONFIG_CRYPTO_TGR192 is not set 1135 + CONFIG_CRYPTO_ECB=m 1136 + CONFIG_CRYPTO_CBC=m 1165 1137 CONFIG_CRYPTO_DES=m 1166 1138 # CONFIG_CRYPTO_BLOWFISH is not set 1167 1139 # CONFIG_CRYPTO_TWOFISH is not set
-5
arch/powerpc/platforms/cell/Kconfig
··· 16 16 bool 17 17 default n 18 18 19 - config SPUFS_MMAP 20 - bool 21 - depends on SPU_FS && SPARSEMEM 22 - default y 23 - 24 19 config CBE_RAS 25 20 bool "RAS features for bare metal Cell BE" 26 21 default y
+7 -3
arch/powerpc/platforms/cell/interrupt.c
··· 101 101 static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc, 102 102 struct pt_regs *regs) 103 103 { 104 - struct cbe_iic_regs *node_iic = desc->handler_data; 104 + struct cbe_iic_regs __iomem *node_iic = (void __iomem *)desc->handler_data; 105 105 unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC; 106 106 unsigned long bits, ack; 107 107 int cascade; ··· 320 320 struct device_node *dn; 321 321 struct resource r0, r1; 322 322 unsigned int node, cascade, found = 0; 323 - struct cbe_iic_regs *node_iic; 323 + struct cbe_iic_regs __iomem *node_iic; 324 324 const u32 *np; 325 325 326 326 for (dn = NULL; ··· 357 357 cascade = irq_create_mapping(iic_host, cascade); 358 358 if (cascade == NO_IRQ) 359 359 continue; 360 - set_irq_data(cascade, node_iic); 360 + /* 361 + * irq_data is a generic pointer that gets passed back 362 + * to us later, so the forced cast is fine. 363 + */ 364 + set_irq_data(cascade, (void __force *)node_iic); 361 365 set_irq_chained_handler(cascade , iic_ioexc_cascade); 362 366 out_be64(&node_iic->iic_ir, 363 367 (1 << 12) /* priority */ |
+4 -4
arch/powerpc/platforms/cell/iommu.c
··· 345 345 346 346 /* node 0 */ 347 347 iommu = &cell_iommus[0]; 348 - iommu->mapped_base = ioremap(0x20000511000, 0x1000); 349 - iommu->mapped_mmio_base = ioremap(0x20000510000, 0x1000); 348 + iommu->mapped_base = ioremap(0x20000511000ul, 0x1000); 349 + iommu->mapped_mmio_base = ioremap(0x20000510000ul, 0x1000); 350 350 351 351 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); 352 352 ··· 358 358 359 359 /* node 1 */ 360 360 iommu = &cell_iommus[1]; 361 - iommu->mapped_base = ioremap(0x30000511000, 0x1000); 362 - iommu->mapped_mmio_base = ioremap(0x30000510000, 0x1000); 361 + iommu->mapped_base = ioremap(0x30000511000ul, 0x1000); 362 + iommu->mapped_mmio_base = ioremap(0x30000510000ul, 0x1000); 363 363 364 364 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); 365 365
+2 -4
arch/powerpc/platforms/cell/spider-pic.c
··· 244 244 int imaplen, intsize, unit; 245 245 struct device_node *iic; 246 246 247 - #if 0 /* Enable that when we have a way to retreive the node as well */ 248 247 /* First, we check wether we have a real "interrupts" in the device 249 248 * tree in case the device-tree is ever fixed 250 249 */ ··· 251 252 if (of_irq_map_one(pic->of_node, 0, &oirq) == 0) { 252 253 virq = irq_create_of_mapping(oirq.controller, oirq.specifier, 253 254 oirq.size); 254 - goto bail; 255 + return virq; 255 256 } 256 - #endif 257 257 258 258 /* Now do the horrible hacks */ 259 259 tmp = get_property(pic->of_node, "#interrupt-cells", NULL); ··· 367 369 } else if (device_is_compatible(dn, "sti,platform-spider-pic") 368 370 && (chip < 2)) { 369 371 static long hard_coded_pics[] = 370 - { 0x24000008000, 0x34000008000 }; 372 + { 0x24000008000ul, 0x34000008000ul}; 371 373 r.start = hard_coded_pics[chip]; 372 374 } else 373 375 continue;
+131 -37
arch/powerpc/platforms/cell/spu_base.c
··· 25 25 #include <linux/interrupt.h> 26 26 #include <linux/list.h> 27 27 #include <linux/module.h> 28 + #include <linux/pci.h> 28 29 #include <linux/poll.h> 29 30 #include <linux/ptrace.h> 30 31 #include <linux/slab.h> 31 32 #include <linux/wait.h> 32 33 34 + #include <asm/firmware.h> 33 35 #include <asm/io.h> 34 36 #include <asm/prom.h> 35 37 #include <linux/mutex.h> ··· 48 46 static int __spu_trap_invalid_dma(struct spu *spu) 49 47 { 50 48 pr_debug("%s\n", __FUNCTION__); 51 - force_sig(SIGBUS, /* info, */ current); 49 + spu->dma_callback(spu, SPE_EVENT_INVALID_DMA); 52 50 return 0; 53 51 } 54 52 55 53 static int __spu_trap_dma_align(struct spu *spu) 56 54 { 57 55 pr_debug("%s\n", __FUNCTION__); 58 - force_sig(SIGBUS, /* info, */ current); 56 + spu->dma_callback(spu, SPE_EVENT_DMA_ALIGNMENT); 59 57 return 0; 60 58 } 61 59 62 60 static int __spu_trap_error(struct spu *spu) 63 61 { 64 62 pr_debug("%s\n", __FUNCTION__); 65 - force_sig(SIGILL, /* info, */ current); 63 + spu->dma_callback(spu, SPE_EVENT_SPE_ERROR); 66 64 return 0; 67 65 } 68 66 ··· 319 317 free_irq(spu->irqs[2], spu); 320 318 } 321 319 322 - static LIST_HEAD(spu_list); 320 + static struct list_head spu_list[MAX_NUMNODES]; 323 321 static DEFINE_MUTEX(spu_mutex); 324 322 325 323 static void spu_init_channels(struct spu *spu) ··· 356 354 } 357 355 } 358 356 359 - struct spu *spu_alloc(void) 357 + struct spu *spu_alloc_node(int node) 360 358 { 361 - struct spu *spu; 359 + struct spu *spu = NULL; 362 360 363 361 mutex_lock(&spu_mutex); 364 - if (!list_empty(&spu_list)) { 365 - spu = list_entry(spu_list.next, struct spu, list); 362 + if (!list_empty(&spu_list[node])) { 363 + spu = list_entry(spu_list[node].next, struct spu, list); 366 364 list_del_init(&spu->list); 367 - pr_debug("Got SPU %x %d\n", spu->isrc, spu->number); 368 - } else { 369 - pr_debug("No SPU left\n"); 370 - spu = NULL; 365 + pr_debug("Got SPU %x %d %d\n", 366 + spu->isrc, spu->number, spu->node); 367 + spu_init_channels(spu); 371 368 } 372 369 mutex_unlock(&spu_mutex); 373 370 374 - if (spu) 375 - spu_init_channels(spu); 371 + return spu; 372 + } 373 + EXPORT_SYMBOL_GPL(spu_alloc_node); 374 + 375 + struct spu *spu_alloc(void) 376 + { 377 + struct spu *spu = NULL; 378 + int node; 379 + 380 + for (node = 0; node < MAX_NUMNODES; node++) { 381 + spu = spu_alloc_node(node); 382 + if (spu) 383 + break; 384 + } 376 385 377 386 return spu; 378 387 } 379 - EXPORT_SYMBOL_GPL(spu_alloc); 380 388 381 389 void spu_free(struct spu *spu) 382 390 { 383 391 mutex_lock(&spu_mutex); 384 - list_add_tail(&spu->list, &spu_list); 392 + list_add_tail(&spu->list, &spu_list[spu->node]); 385 393 mutex_unlock(&spu_mutex); 386 394 } 387 395 EXPORT_SYMBOL_GPL(spu_free); ··· 578 566 } 579 567 580 568 /* This function shall be abstracted for HV platforms */ 581 - static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) 569 + static int __init spu_map_interrupts_old(struct spu *spu, struct device_node *np) 582 570 { 583 571 unsigned int isrc; 584 572 const u32 *tmp; ··· 602 590 return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; 603 591 } 604 592 605 - static int __init spu_map_device(struct spu *spu, struct device_node *node) 593 + static int __init spu_map_device_old(struct spu *spu, struct device_node *node) 606 594 { 607 595 const char *prop; 608 596 int ret; ··· 644 632 out_unmap: 645 633 spu_unmap(spu); 646 634 out: 635 + return ret; 636 + } 637 + 638 + static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) 639 + { 640 + struct of_irq oirq; 641 + int ret; 642 + int i; 643 + 644 + for (i=0; i < 3; i++) { 645 + ret = of_irq_map_one(np, i, &oirq); 646 + if (ret) 647 + goto err; 648 + 649 + ret = -EINVAL; 650 + spu->irqs[i] = irq_create_of_mapping(oirq.controller, 651 + oirq.specifier, oirq.size); 652 + if (spu->irqs[i] == NO_IRQ) 653 + goto err; 654 + } 655 + return 0; 656 + 657 + err: 658 + pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, spu->name); 659 + for (; i >= 0; i--) { 660 + if (spu->irqs[i] != NO_IRQ) 661 + irq_dispose_mapping(spu->irqs[i]); 662 + } 663 + return ret; 664 + } 665 + 666 + static int spu_map_resource(struct device_node *node, int nr, 667 + void __iomem** virt, unsigned long *phys) 668 + { 669 + struct resource resource = { }; 670 + int ret; 671 + 672 + ret = of_address_to_resource(node, 0, &resource); 673 + if (ret) 674 + goto out; 675 + 676 + if (phys) 677 + *phys = resource.start; 678 + *virt = ioremap(resource.start, resource.end - resource.start); 679 + if (!*virt) 680 + ret = -EINVAL; 681 + 682 + out: 683 + return ret; 684 + } 685 + 686 + static int __init spu_map_device(struct spu *spu, struct device_node *node) 687 + { 688 + int ret = -ENODEV; 689 + spu->name = get_property(node, "name", NULL); 690 + if (!spu->name) 691 + goto out; 692 + 693 + ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store, 694 + &spu->local_store_phys); 695 + if (ret) 696 + goto out; 697 + ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem, 698 + &spu->problem_phys); 699 + if (ret) 700 + goto out_unmap; 701 + ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2, 702 + NULL); 703 + if (ret) 704 + goto out_unmap; 705 + 706 + if (!firmware_has_feature(FW_FEATURE_LPAR)) 707 + ret = spu_map_resource(node, 3, (void __iomem**)&spu->priv1, 708 + NULL); 709 + if (ret) 710 + goto out_unmap; 711 + return 0; 712 + 713 + out_unmap: 714 + spu_unmap(spu); 715 + out: 716 + pr_debug("failed to map spe %s: %d\n", spu->name, ret); 647 717 return ret; 648 718 } 649 719 ··· 782 688 goto out; 783 689 784 690 ret = spu_map_device(spu, spe); 691 + /* try old method */ 692 + if (ret) 693 + ret = spu_map_device_old(spu, spe); 785 694 if (ret) 786 695 goto out_free; 787 696 ··· 793 696 if (spu->nid == -1) 794 697 spu->nid = 0; 795 698 ret = spu_map_interrupts(spu, spe); 699 + if (ret) 700 + ret = spu_map_interrupts_old(spu, spe); 796 701 if (ret) 797 702 goto out_unmap; 798 703 spin_lock_init(&spu->register_lock); ··· 805 706 spu->number = number++; 806 707 ret = spu_request_irqs(spu); 807 708 if (ret) 808 - goto out_unmap; 709 + goto out_unlock; 809 710 810 711 ret = spu_create_sysdev(spu); 811 712 if (ret) 812 713 goto out_free_irqs; 813 714 814 - list_add(&spu->list, &spu_list); 715 + list_add(&spu->list, &spu_list[spu->node]); 815 716 mutex_unlock(&spu_mutex); 816 717 817 718 pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n", ··· 821 722 822 723 out_free_irqs: 823 724 spu_free_irqs(spu); 824 - 825 - out_unmap: 725 + out_unlock: 826 726 mutex_unlock(&spu_mutex); 727 + out_unmap: 827 728 spu_unmap(spu); 828 729 out_free: 829 730 kfree(spu); ··· 844 745 static void cleanup_spu_base(void) 845 746 { 846 747 struct spu *spu, *tmp; 748 + int node; 749 + 847 750 mutex_lock(&spu_mutex); 848 - list_for_each_entry_safe(spu, tmp, &spu_list, list) 849 - destroy_spu(spu); 751 + for (node = 0; node < MAX_NUMNODES; node++) { 752 + list_for_each_entry_safe(spu, tmp, &spu_list[node], list) 753 + destroy_spu(spu); 754 + } 850 755 mutex_unlock(&spu_mutex); 851 756 sysdev_class_unregister(&spu_sysdev_class); 852 757 } ··· 859 756 static int __init init_spu_base(void) 860 757 { 861 758 struct device_node *node; 862 - int ret; 759 + int i, ret; 863 760 864 761 /* create sysdev class for spus */ 865 762 ret = sysdev_class_register(&spu_sysdev_class); 866 763 if (ret) 867 764 return ret; 868 765 766 + for (i = 0; i < MAX_NUMNODES; i++) 767 + INIT_LIST_HEAD(&spu_list[i]); 768 + 869 769 ret = -ENODEV; 870 770 for (node = of_find_node_by_type(NULL, "spe"); 871 771 node; node = of_find_node_by_type(node, "spe")) { 872 - ret = create_spu(node); 873 - if (ret) { 874 - printk(KERN_WARNING "%s: Error initializing %s\n", 875 - __FUNCTION__, node->name); 876 - cleanup_spu_base(); 877 - break; 878 - } 879 - } 880 - /* in some old firmware versions, the spe is called 'spc', so we 881 - look for that as well */ 882 - for (node = of_find_node_by_type(NULL, "spc"); 883 - node; node = of_find_node_by_type(node, "spc")) { 884 772 ret = create_spu(node); 885 773 if (ret) { 886 774 printk(KERN_WARNING "%s: Error initializing %s\n",
+1 -1
arch/powerpc/platforms/cell/spufs/Makefile
··· 2 2 3 3 obj-$(CONFIG_SPU_FS) += spufs.o 4 4 spufs-y += inode.o file.o context.o syscalls.o 5 - spufs-y += sched.o backing_ops.o hw_ops.o run.o 5 + spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o 6 6 7 7 # Rules to build switch.o with the help of SPU tool chain 8 8 SPU_CROSS := spu-
+5 -1
arch/powerpc/platforms/cell/spufs/context.c
··· 27 27 #include <asm/spu_csa.h> 28 28 #include "spufs.h" 29 29 30 - struct spu_context *alloc_spu_context(void) 30 + struct spu_context *alloc_spu_context(struct spu_gang *gang) 31 31 { 32 32 struct spu_context *ctx; 33 33 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); ··· 51 51 ctx->state = SPU_STATE_SAVED; 52 52 ctx->ops = &spu_backing_ops; 53 53 ctx->owner = get_task_mm(current); 54 + if (gang) 55 + spu_gang_add_ctx(gang, ctx); 54 56 goto out; 55 57 out_free: 56 58 kfree(ctx); ··· 69 67 spu_deactivate(ctx); 70 68 up_write(&ctx->state_sema); 71 69 spu_fini_csa(&ctx->csa); 70 + if (ctx->gang) 71 + spu_gang_remove_ctx(ctx->gang, ctx); 72 72 kfree(ctx); 73 73 } 74 74
+260 -100
arch/powerpc/platforms/cell/spufs/file.c
··· 36 36 37 37 #include "spufs.h" 38 38 39 + #define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000) 40 + 39 41 40 42 static int 41 43 spufs_mem_open(struct inode *inode, struct file *file) ··· 90 88 return ret; 91 89 } 92 90 93 - #ifdef CONFIG_SPUFS_MMAP 94 91 static struct page * 95 92 spufs_mem_mmap_nopage(struct vm_area_struct *vma, 96 93 unsigned long address, int *type) ··· 102 101 103 102 spu_acquire(ctx); 104 103 105 - if (ctx->state == SPU_STATE_SAVED) 104 + if (ctx->state == SPU_STATE_SAVED) { 105 + vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 106 + & ~(_PAGE_NO_CACHE | _PAGE_GUARDED)); 106 107 page = vmalloc_to_page(ctx->csa.lscsa->ls + offset); 107 - else 108 + } else { 109 + vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 110 + | _PAGE_NO_CACHE | _PAGE_GUARDED); 108 111 page = pfn_to_page((ctx->spu->local_store_phys + offset) 109 112 >> PAGE_SHIFT); 110 - 113 + } 111 114 spu_release(ctx); 112 115 113 116 if (type) ··· 138 133 vma->vm_ops = &spufs_mem_mmap_vmops; 139 134 return 0; 140 135 } 141 - #endif 142 136 143 137 static struct file_operations spufs_mem_fops = { 144 138 .open = spufs_mem_open, 145 139 .read = spufs_mem_read, 146 140 .write = spufs_mem_write, 147 141 .llseek = generic_file_llseek, 148 - #ifdef CONFIG_SPUFS_MMAP 149 142 .mmap = spufs_mem_mmap, 150 - #endif 151 143 }; 152 144 153 - #ifdef CONFIG_SPUFS_MMAP 154 145 static struct page *spufs_ps_nopage(struct vm_area_struct *vma, 155 146 unsigned long address, 156 - int *type, unsigned long ps_offs) 147 + int *type, unsigned long ps_offs, 148 + unsigned long ps_size) 157 149 { 158 150 struct page *page = NOPAGE_SIGBUS; 159 151 int fault_type = VM_FAULT_SIGBUS; ··· 160 158 int ret; 161 159 162 160 offset += vma->vm_pgoff << PAGE_SHIFT; 163 - if (offset >= 0x4000) 161 + if (offset >= ps_size) 164 162 goto out; 165 163 166 164 ret = spu_acquire_runnable(ctx); ··· 181 179 return page; 182 180 } 183 181 182 + #if SPUFS_MMAP_4K 184 183 static struct page *spufs_cntl_mmap_nopage(struct vm_area_struct *vma, 185 184 unsigned long address, int *type) 186 185 { 187 - return spufs_ps_nopage(vma, address, type, 0x4000); 186 + return spufs_ps_nopage(vma, address, type, 0x4000, 0x1000); 188 187 } 189 188 190 189 static struct vm_operations_struct spufs_cntl_mmap_vmops = { ··· 194 191 195 192 /* 196 193 * mmap support for problem state control area [0x4000 - 0x4fff]. 197 - * Mapping this area requires that the application have CAP_SYS_RAWIO, 198 - * as these registers require special care when read/writing. 199 194 */ 200 195 static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) 201 196 { 202 197 if (!(vma->vm_flags & VM_SHARED)) 203 198 return -EINVAL; 204 - 205 - if (!capable(CAP_SYS_RAWIO)) 206 - return -EPERM; 207 199 208 200 vma->vm_flags |= VM_RESERVED; 209 201 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) ··· 207 209 vma->vm_ops = &spufs_cntl_mmap_vmops; 208 210 return 0; 209 211 } 210 - #endif 212 + #else /* SPUFS_MMAP_4K */ 213 + #define spufs_cntl_mmap NULL 214 + #endif /* !SPUFS_MMAP_4K */ 215 + 216 + static u64 spufs_cntl_get(void *data) 217 + { 218 + struct spu_context *ctx = data; 219 + u64 val; 220 + 221 + spu_acquire(ctx); 222 + val = ctx->ops->status_read(ctx); 223 + spu_release(ctx); 224 + 225 + return val; 226 + } 227 + 228 + static void spufs_cntl_set(void *data, u64 val) 229 + { 230 + struct spu_context *ctx = data; 231 + 232 + spu_acquire(ctx); 233 + ctx->ops->runcntl_write(ctx, val); 234 + spu_release(ctx); 235 + } 211 236 212 237 static int spufs_cntl_open(struct inode *inode, struct file *file) 213 238 { ··· 240 219 file->private_data = ctx; 241 220 file->f_mapping = inode->i_mapping; 242 221 ctx->cntl = inode->i_mapping; 243 - return 0; 244 - } 245 - 246 - static ssize_t 247 - spufs_cntl_read(struct file *file, char __user *buffer, 248 - size_t size, loff_t *pos) 249 - { 250 - /* FIXME: read from spu status */ 251 - return -EINVAL; 252 - } 253 - 254 - static ssize_t 255 - spufs_cntl_write(struct file *file, const char __user *buffer, 256 - size_t size, loff_t *pos) 257 - { 258 - /* FIXME: write to runctl bit */ 259 - return -EINVAL; 222 + return simple_attr_open(inode, file, spufs_cntl_get, 223 + spufs_cntl_set, "0x%08lx"); 260 224 } 261 225 262 226 static struct file_operations spufs_cntl_fops = { 263 227 .open = spufs_cntl_open, 264 - .read = spufs_cntl_read, 265 - .write = spufs_cntl_write, 266 - #ifdef CONFIG_SPUFS_MMAP 228 + .read = simple_attr_read, 229 + .write = simple_attr_write, 267 230 .mmap = spufs_cntl_mmap, 268 - #endif 269 231 }; 270 232 271 233 static int ··· 360 356 return nonseekable_open(inode, file); 361 357 } 362 358 359 + /* 360 + * Read as many bytes from the mailbox as possible, until 361 + * one of the conditions becomes true: 362 + * 363 + * - no more data available in the mailbox 364 + * - end of the user provided buffer 365 + * - end of the mapped area 366 + */ 363 367 static ssize_t spufs_mbox_read(struct file *file, char __user *buf, 364 368 size_t len, loff_t *pos) 365 369 { 366 370 struct spu_context *ctx = file->private_data; 367 - u32 mbox_data; 368 - int ret; 371 + u32 mbox_data, __user *udata; 372 + ssize_t count; 369 373 370 374 if (len < 4) 371 375 return -EINVAL; 372 376 373 - spu_acquire(ctx); 374 - ret = ctx->ops->mbox_read(ctx, &mbox_data); 375 - spu_release(ctx); 376 - 377 - if (!ret) 378 - return -EAGAIN; 379 - 380 - if (copy_to_user(buf, &mbox_data, sizeof mbox_data)) 377 + if (!access_ok(VERIFY_WRITE, buf, len)) 381 378 return -EFAULT; 382 379 383 - return 4; 380 + udata = (void __user *)buf; 381 + 382 + spu_acquire(ctx); 383 + for (count = 0; count <= len; count += 4, udata++) { 384 + int ret; 385 + ret = ctx->ops->mbox_read(ctx, &mbox_data); 386 + if (ret == 0) 387 + break; 388 + 389 + /* 390 + * at the end of the mapped area, we can fault 391 + * but still need to return the data we have 392 + * read successfully so far. 393 + */ 394 + ret = __put_user(mbox_data, udata); 395 + if (ret) { 396 + if (!count) 397 + count = -EFAULT; 398 + break; 399 + } 400 + } 401 + spu_release(ctx); 402 + 403 + if (!count) 404 + count = -EAGAIN; 405 + 406 + return count; 384 407 } 385 408 386 409 static struct file_operations spufs_mbox_fops = { ··· 463 432 kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN); 464 433 } 465 434 435 + /* 436 + * Read as many bytes from the interrupt mailbox as possible, until 437 + * one of the conditions becomes true: 438 + * 439 + * - no more data available in the mailbox 440 + * - end of the user provided buffer 441 + * - end of the mapped area 442 + * 443 + * If the file is opened without O_NONBLOCK, we wait here until 444 + * any data is available, but return when we have been able to 445 + * read something. 446 + */ 466 447 static ssize_t spufs_ibox_read(struct file *file, char __user *buf, 467 448 size_t len, loff_t *pos) 468 449 { 469 450 struct spu_context *ctx = file->private_data; 470 - u32 ibox_data; 471 - ssize_t ret; 451 + u32 ibox_data, __user *udata; 452 + ssize_t count; 472 453 473 454 if (len < 4) 474 455 return -EINVAL; 475 456 457 + if (!access_ok(VERIFY_WRITE, buf, len)) 458 + return -EFAULT; 459 + 460 + udata = (void __user *)buf; 461 + 476 462 spu_acquire(ctx); 477 463 478 - ret = 0; 464 + /* wait only for the first element */ 465 + count = 0; 479 466 if (file->f_flags & O_NONBLOCK) { 480 467 if (!spu_ibox_read(ctx, &ibox_data)) 481 - ret = -EAGAIN; 468 + count = -EAGAIN; 482 469 } else { 483 - ret = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data)); 470 + count = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data)); 471 + } 472 + if (count) 473 + goto out; 474 + 475 + /* if we can't write at all, return -EFAULT */ 476 + count = __put_user(ibox_data, udata); 477 + if (count) 478 + goto out; 479 + 480 + for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) { 481 + int ret; 482 + ret = ctx->ops->ibox_read(ctx, &ibox_data); 483 + if (ret == 0) 484 + break; 485 + /* 486 + * at the end of the mapped area, we can fault 487 + * but still need to return the data we have 488 + * read successfully so far. 489 + */ 490 + ret = __put_user(ibox_data, udata); 491 + if (ret) 492 + break; 484 493 } 485 494 495 + out: 486 496 spu_release(ctx); 487 497 488 - if (ret) 489 - return ret; 490 - 491 - ret = 4; 492 - if (copy_to_user(buf, &ibox_data, sizeof ibox_data)) 493 - ret = -EFAULT; 494 - 495 - return ret; 498 + return count; 496 499 } 497 500 498 501 static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait) ··· 599 534 kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT); 600 535 } 601 536 537 + /* 538 + * Write as many bytes to the interrupt mailbox as possible, until 539 + * one of the conditions becomes true: 540 + * 541 + * - the mailbox is full 542 + * - end of the user provided buffer 543 + * - end of the mapped area 544 + * 545 + * If the file is opened without O_NONBLOCK, we wait here until 546 + * space is availabyl, but return when we have been able to 547 + * write something. 548 + */ 602 549 static ssize_t spufs_wbox_write(struct file *file, const char __user *buf, 603 550 size_t len, loff_t *pos) 604 551 { 605 552 struct spu_context *ctx = file->private_data; 606 - u32 wbox_data; 607 - int ret; 553 + u32 wbox_data, __user *udata; 554 + ssize_t count; 608 555 609 556 if (len < 4) 610 557 return -EINVAL; 611 558 612 - if (copy_from_user(&wbox_data, buf, sizeof wbox_data)) 559 + udata = (void __user *)buf; 560 + if (!access_ok(VERIFY_READ, buf, len)) 561 + return -EFAULT; 562 + 563 + if (__get_user(wbox_data, udata)) 613 564 return -EFAULT; 614 565 615 566 spu_acquire(ctx); 616 567 617 - ret = 0; 568 + /* 569 + * make sure we can at least write one element, by waiting 570 + * in case of !O_NONBLOCK 571 + */ 572 + count = 0; 618 573 if (file->f_flags & O_NONBLOCK) { 619 574 if (!spu_wbox_write(ctx, wbox_data)) 620 - ret = -EAGAIN; 575 + count = -EAGAIN; 621 576 } else { 622 - ret = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data)); 577 + count = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data)); 623 578 } 624 579 625 - spu_release(ctx); 580 + if (count) 581 + goto out; 626 582 627 - return ret ? ret : sizeof wbox_data; 583 + /* write aѕ much as possible */ 584 + for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) { 585 + int ret; 586 + ret = __get_user(wbox_data, udata); 587 + if (ret) 588 + break; 589 + 590 + ret = spu_wbox_write(ctx, wbox_data); 591 + if (ret == 0) 592 + break; 593 + } 594 + 595 + out: 596 + spu_release(ctx); 597 + return count; 628 598 } 629 599 630 600 static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait) ··· 757 657 return 4; 758 658 } 759 659 760 - #ifdef CONFIG_SPUFS_MMAP 761 660 static struct page *spufs_signal1_mmap_nopage(struct vm_area_struct *vma, 762 661 unsigned long address, int *type) 763 662 { 764 - return spufs_ps_nopage(vma, address, type, 0x14000); 663 + #if PAGE_SIZE == 0x1000 664 + return spufs_ps_nopage(vma, address, type, 0x14000, 0x1000); 665 + #elif PAGE_SIZE == 0x10000 666 + /* For 64k pages, both signal1 and signal2 can be used to mmap the whole 667 + * signal 1 and 2 area 668 + */ 669 + return spufs_ps_nopage(vma, address, type, 0x10000, 0x10000); 670 + #else 671 + #error unsupported page size 672 + #endif 765 673 } 766 674 767 675 static struct vm_operations_struct spufs_signal1_mmap_vmops = { ··· 788 680 vma->vm_ops = &spufs_signal1_mmap_vmops; 789 681 return 0; 790 682 } 791 - #endif 792 683 793 684 static struct file_operations spufs_signal1_fops = { 794 685 .open = spufs_signal1_open, 795 686 .read = spufs_signal1_read, 796 687 .write = spufs_signal1_write, 797 - #ifdef CONFIG_SPUFS_MMAP 798 688 .mmap = spufs_signal1_mmap, 799 - #endif 800 689 }; 801 690 802 691 static int spufs_signal2_open(struct inode *inode, struct file *file) ··· 848 743 return 4; 849 744 } 850 745 851 - #ifdef CONFIG_SPUFS_MMAP 746 + #if SPUFS_MMAP_4K 852 747 static struct page *spufs_signal2_mmap_nopage(struct vm_area_struct *vma, 853 748 unsigned long address, int *type) 854 749 { 855 - return spufs_ps_nopage(vma, address, type, 0x1c000); 750 + #if PAGE_SIZE == 0x1000 751 + return spufs_ps_nopage(vma, address, type, 0x1c000, 0x1000); 752 + #elif PAGE_SIZE == 0x10000 753 + /* For 64k pages, both signal1 and signal2 can be used to mmap the whole 754 + * signal 1 and 2 area 755 + */ 756 + return spufs_ps_nopage(vma, address, type, 0x10000, 0x10000); 757 + #else 758 + #error unsupported page size 759 + #endif 856 760 } 857 761 858 762 static struct vm_operations_struct spufs_signal2_mmap_vmops = { ··· 881 767 vma->vm_ops = &spufs_signal2_mmap_vmops; 882 768 return 0; 883 769 } 884 - #endif 770 + #else /* SPUFS_MMAP_4K */ 771 + #define spufs_signal2_mmap NULL 772 + #endif /* !SPUFS_MMAP_4K */ 885 773 886 774 static struct file_operations spufs_signal2_fops = { 887 775 .open = spufs_signal2_open, 888 776 .read = spufs_signal2_read, 889 777 .write = spufs_signal2_write, 890 - #ifdef CONFIG_SPUFS_MMAP 891 778 .mmap = spufs_signal2_mmap, 892 - #endif 893 779 }; 894 780 895 781 static void spufs_signal1_type_set(void *data, u64 val) ··· 938 824 DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, 939 825 spufs_signal2_type_set, "%llu"); 940 826 941 - #ifdef CONFIG_SPUFS_MMAP 827 + #if SPUFS_MMAP_4K 942 828 static struct page *spufs_mss_mmap_nopage(struct vm_area_struct *vma, 943 829 unsigned long address, int *type) 944 830 { 945 - return spufs_ps_nopage(vma, address, type, 0x0000); 831 + return spufs_ps_nopage(vma, address, type, 0x0000, 0x1000); 946 832 } 947 833 948 834 static struct vm_operations_struct spufs_mss_mmap_vmops = { ··· 951 837 952 838 /* 953 839 * mmap support for problem state MFC DMA area [0x0000 - 0x0fff]. 954 - * Mapping this area requires that the application have CAP_SYS_RAWIO, 955 - * as these registers require special care when read/writing. 956 840 */ 957 841 static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma) 958 842 { 959 843 if (!(vma->vm_flags & VM_SHARED)) 960 844 return -EINVAL; 961 - 962 - if (!capable(CAP_SYS_RAWIO)) 963 - return -EPERM; 964 845 965 846 vma->vm_flags |= VM_RESERVED; 966 847 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) ··· 964 855 vma->vm_ops = &spufs_mss_mmap_vmops; 965 856 return 0; 966 857 } 967 - #endif 858 + #else /* SPUFS_MMAP_4K */ 859 + #define spufs_mss_mmap NULL 860 + #endif /* !SPUFS_MMAP_4K */ 968 861 969 862 static int spufs_mss_open(struct inode *inode, struct file *file) 970 863 { ··· 978 867 979 868 static struct file_operations spufs_mss_fops = { 980 869 .open = spufs_mss_open, 981 - #ifdef CONFIG_SPUFS_MMAP 982 870 .mmap = spufs_mss_mmap, 983 - #endif 871 + }; 872 + 873 + static struct page *spufs_psmap_mmap_nopage(struct vm_area_struct *vma, 874 + unsigned long address, int *type) 875 + { 876 + return spufs_ps_nopage(vma, address, type, 0x0000, 0x20000); 877 + } 878 + 879 + static struct vm_operations_struct spufs_psmap_mmap_vmops = { 880 + .nopage = spufs_psmap_mmap_nopage, 881 + }; 882 + 883 + /* 884 + * mmap support for full problem state area [0x00000 - 0x1ffff]. 885 + */ 886 + static int spufs_psmap_mmap(struct file *file, struct vm_area_struct *vma) 887 + { 888 + if (!(vma->vm_flags & VM_SHARED)) 889 + return -EINVAL; 890 + 891 + vma->vm_flags |= VM_RESERVED; 892 + vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 893 + | _PAGE_NO_CACHE | _PAGE_GUARDED); 894 + 895 + vma->vm_ops = &spufs_psmap_mmap_vmops; 896 + return 0; 897 + } 898 + 899 + static int spufs_psmap_open(struct inode *inode, struct file *file) 900 + { 901 + struct spufs_inode_info *i = SPUFS_I(inode); 902 + 903 + file->private_data = i->i_ctx; 904 + return nonseekable_open(inode, file); 905 + } 906 + 907 + static struct file_operations spufs_psmap_fops = { 908 + .open = spufs_psmap_open, 909 + .mmap = spufs_psmap_mmap, 984 910 }; 985 911 986 912 987 - #ifdef CONFIG_SPUFS_MMAP 913 + #if SPUFS_MMAP_4K 988 914 static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma, 989 915 unsigned long address, int *type) 990 916 { 991 - return spufs_ps_nopage(vma, address, type, 0x3000); 917 + return spufs_ps_nopage(vma, address, type, 0x3000, 0x1000); 992 918 } 993 919 994 920 static struct vm_operations_struct spufs_mfc_mmap_vmops = { ··· 1034 886 1035 887 /* 1036 888 * mmap support for problem state MFC DMA area [0x0000 - 0x0fff]. 1037 - * Mapping this area requires that the application have CAP_SYS_RAWIO, 1038 - * as these registers require special care when read/writing. 1039 889 */ 1040 890 static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) 1041 891 { 1042 892 if (!(vma->vm_flags & VM_SHARED)) 1043 893 return -EINVAL; 1044 - 1045 - if (!capable(CAP_SYS_RAWIO)) 1046 - return -EPERM; 1047 894 1048 895 vma->vm_flags |= VM_RESERVED; 1049 896 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) ··· 1047 904 vma->vm_ops = &spufs_mfc_mmap_vmops; 1048 905 return 0; 1049 906 } 1050 - #endif 907 + #else /* SPUFS_MMAP_4K */ 908 + #define spufs_mfc_mmap NULL 909 + #endif /* !SPUFS_MMAP_4K */ 1051 910 1052 911 static int spufs_mfc_open(struct inode *inode, struct file *file) 1053 912 { ··· 1339 1194 .flush = spufs_mfc_flush, 1340 1195 .fsync = spufs_mfc_fsync, 1341 1196 .fasync = spufs_mfc_fasync, 1342 - #ifdef CONFIG_SPUFS_MMAP 1343 1197 .mmap = spufs_mfc_mmap, 1344 - #endif 1345 1198 }; 1346 1199 1347 1200 static void spufs_npc_set(void *data, u64 val) ··· 1487 1344 } 1488 1345 DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n") 1489 1346 1347 + static u64 spufs_object_id_get(void *data) 1348 + { 1349 + struct spu_context *ctx = data; 1350 + return ctx->object_id; 1351 + } 1352 + 1353 + static void spufs_object_id_set(void *data, u64 id) 1354 + { 1355 + struct spu_context *ctx = data; 1356 + ctx->object_id = id; 1357 + } 1358 + 1359 + DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get, 1360 + spufs_object_id_set, "0x%llx\n"); 1361 + 1490 1362 struct tree_descr spufs_dir_contents[] = { 1491 1363 { "mem", &spufs_mem_fops, 0666, }, 1492 1364 { "regs", &spufs_regs_fops, 0666, }, ··· 1525 1367 { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, 1526 1368 { "event_mask", &spufs_event_mask_ops, 0666, }, 1527 1369 { "srr0", &spufs_srr0_ops, 0666, }, 1370 + { "psmap", &spufs_psmap_fops, 0666, }, 1528 1371 { "phys-id", &spufs_id_ops, 0666, }, 1372 + { "object-id", &spufs_object_id_ops, 0666, }, 1529 1373 {}, 1530 1374 };
+81
arch/powerpc/platforms/cell/spufs/gang.c
··· 1 + /* 2 + * SPU file system 3 + * 4 + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 5 + * 6 + * Author: Arnd Bergmann <arndb@de.ibm.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; either version 2, or (at your option) 11 + * any later version. 12 + * 13 + * This program is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + * 18 + * You should have received a copy of the GNU General Public License 19 + * along with this program; if not, write to the Free Software 20 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 + */ 22 + 23 + #include <linux/list.h> 24 + #include <linux/slab.h> 25 + 26 + #include "spufs.h" 27 + 28 + struct spu_gang *alloc_spu_gang(void) 29 + { 30 + struct spu_gang *gang; 31 + 32 + gang = kzalloc(sizeof *gang, GFP_KERNEL); 33 + if (!gang) 34 + goto out; 35 + 36 + kref_init(&gang->kref); 37 + mutex_init(&gang->mutex); 38 + INIT_LIST_HEAD(&gang->list); 39 + 40 + out: 41 + return gang; 42 + } 43 + 44 + static void destroy_spu_gang(struct kref *kref) 45 + { 46 + struct spu_gang *gang; 47 + gang = container_of(kref, struct spu_gang, kref); 48 + WARN_ON(gang->contexts || !list_empty(&gang->list)); 49 + kfree(gang); 50 + } 51 + 52 + struct spu_gang *get_spu_gang(struct spu_gang *gang) 53 + { 54 + kref_get(&gang->kref); 55 + return gang; 56 + } 57 + 58 + int put_spu_gang(struct spu_gang *gang) 59 + { 60 + return kref_put(&gang->kref, &destroy_spu_gang); 61 + } 62 + 63 + void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx) 64 + { 65 + mutex_lock(&gang->mutex); 66 + ctx->gang = get_spu_gang(gang); 67 + list_add(&ctx->gang_list, &gang->list); 68 + gang->contexts++; 69 + mutex_unlock(&gang->mutex); 70 + } 71 + 72 + void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx) 73 + { 74 + mutex_lock(&gang->mutex); 75 + WARN_ON(ctx->gang != gang); 76 + list_del_init(&ctx->gang_list); 77 + gang->contexts--; 78 + mutex_unlock(&gang->mutex); 79 + 80 + put_spu_gang(gang); 81 + }
+194 -38
arch/powerpc/platforms/cell/spufs/inode.c
··· 50 50 ei = kmem_cache_alloc(spufs_inode_cache, SLAB_KERNEL); 51 51 if (!ei) 52 52 return NULL; 53 + 54 + ei->i_gang = NULL; 55 + ei->i_ctx = NULL; 56 + 53 57 return &ei->vfs_inode; 54 58 } 55 59 ··· 132 128 static void 133 129 spufs_delete_inode(struct inode *inode) 134 130 { 135 - if (SPUFS_I(inode)->i_ctx) 136 - put_spu_context(SPUFS_I(inode)->i_ctx); 131 + struct spufs_inode_info *ei = SPUFS_I(inode); 132 + 133 + if (ei->i_ctx) 134 + put_spu_context(ei->i_ctx); 135 + if (ei->i_gang) 136 + put_spu_gang(ei->i_gang); 137 137 clear_inode(inode); 138 138 } 139 139 140 140 static void spufs_prune_dir(struct dentry *dir) 141 141 { 142 142 struct dentry *dentry, *tmp; 143 + 143 144 mutex_lock(&dir->d_inode->i_mutex); 144 145 list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) { 145 146 spin_lock(&dcache_lock); ··· 165 156 mutex_unlock(&dir->d_inode->i_mutex); 166 157 } 167 158 168 - /* Caller must hold root->i_mutex */ 169 - static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) 159 + /* Caller must hold parent->i_mutex */ 160 + static int spufs_rmdir(struct inode *parent, struct dentry *dir) 170 161 { 171 162 /* remove all entries */ 172 - spufs_prune_dir(dir_dentry); 163 + spufs_prune_dir(dir); 173 164 174 - return simple_rmdir(root, dir_dentry); 165 + return simple_rmdir(parent, dir); 175 166 } 176 167 177 168 static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, ··· 200 191 static int spufs_dir_close(struct inode *inode, struct file *file) 201 192 { 202 193 struct spu_context *ctx; 203 - struct inode *dir; 204 - struct dentry *dentry; 194 + struct inode *parent; 195 + struct dentry *dir; 205 196 int ret; 206 197 207 - dentry = file->f_dentry; 208 - dir = dentry->d_parent->d_inode; 209 - ctx = SPUFS_I(dentry->d_inode)->i_ctx; 198 + dir = file->f_dentry; 199 + parent = dir->d_parent->d_inode; 200 + ctx = SPUFS_I(dir->d_inode)->i_ctx; 210 201 211 - mutex_lock(&dir->i_mutex); 212 - ret = spufs_rmdir(dir, dentry); 213 - mutex_unlock(&dir->i_mutex); 202 + mutex_lock(&parent->i_mutex); 203 + ret = spufs_rmdir(parent, dir); 204 + mutex_unlock(&parent->i_mutex); 214 205 WARN_ON(ret); 215 206 216 207 /* We have to give up the mm_struct */ ··· 233 224 }; 234 225 235 226 static int 236 - spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) 227 + spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, 228 + int mode) 237 229 { 238 230 int ret; 239 231 struct inode *inode; ··· 249 239 inode->i_gid = dir->i_gid; 250 240 inode->i_mode &= S_ISGID; 251 241 } 252 - ctx = alloc_spu_context(); 242 + ctx = alloc_spu_context(SPUFS_I(dir)->i_gang); /* XXX gang */ 253 243 SPUFS_I(inode)->i_ctx = ctx; 254 244 if (!ctx) 255 245 goto out_iput; 246 + 247 + ctx->flags = flags; 256 248 257 249 inode->i_op = &spufs_dir_inode_operations; 258 250 inode->i_fop = &simple_dir_operations; ··· 301 289 return ret; 302 290 } 303 291 292 + static int spufs_create_context(struct inode *inode, 293 + struct dentry *dentry, 294 + struct vfsmount *mnt, int flags, int mode) 295 + { 296 + int ret; 297 + 298 + ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO); 299 + if (ret) 300 + goto out_unlock; 301 + 302 + /* 303 + * get references for dget and mntget, will be released 304 + * in error path of *_open(). 305 + */ 306 + ret = spufs_context_open(dget(dentry), mntget(mnt)); 307 + if (ret < 0) { 308 + WARN_ON(spufs_rmdir(inode, dentry)); 309 + mutex_unlock(&inode->i_mutex); 310 + spu_forget(SPUFS_I(dentry->d_inode)->i_ctx); 311 + goto out; 312 + } 313 + 314 + out_unlock: 315 + mutex_unlock(&inode->i_mutex); 316 + out: 317 + dput(dentry); 318 + return ret; 319 + } 320 + 321 + static int spufs_rmgang(struct inode *root, struct dentry *dir) 322 + { 323 + /* FIXME: this fails if the dir is not empty, 324 + which causes a leak of gangs. */ 325 + return simple_rmdir(root, dir); 326 + } 327 + 328 + static int spufs_gang_close(struct inode *inode, struct file *file) 329 + { 330 + struct inode *parent; 331 + struct dentry *dir; 332 + int ret; 333 + 334 + dir = file->f_dentry; 335 + parent = dir->d_parent->d_inode; 336 + 337 + ret = spufs_rmgang(parent, dir); 338 + WARN_ON(ret); 339 + 340 + return dcache_dir_close(inode, file); 341 + } 342 + 343 + struct file_operations spufs_gang_fops = { 344 + .open = dcache_dir_open, 345 + .release = spufs_gang_close, 346 + .llseek = dcache_dir_lseek, 347 + .read = generic_read_dir, 348 + .readdir = dcache_readdir, 349 + .fsync = simple_sync_file, 350 + }; 351 + 352 + static int 353 + spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode) 354 + { 355 + int ret; 356 + struct inode *inode; 357 + struct spu_gang *gang; 358 + 359 + ret = -ENOSPC; 360 + inode = spufs_new_inode(dir->i_sb, mode | S_IFDIR); 361 + if (!inode) 362 + goto out; 363 + 364 + ret = 0; 365 + if (dir->i_mode & S_ISGID) { 366 + inode->i_gid = dir->i_gid; 367 + inode->i_mode &= S_ISGID; 368 + } 369 + gang = alloc_spu_gang(); 370 + SPUFS_I(inode)->i_ctx = NULL; 371 + SPUFS_I(inode)->i_gang = gang; 372 + if (!gang) 373 + goto out_iput; 374 + 375 + inode->i_op = &spufs_dir_inode_operations; 376 + inode->i_fop = &simple_dir_operations; 377 + 378 + d_instantiate(dentry, inode); 379 + dget(dentry); 380 + dir->i_nlink++; 381 + dentry->d_inode->i_nlink++; 382 + return ret; 383 + 384 + out_iput: 385 + iput(inode); 386 + out: 387 + return ret; 388 + } 389 + 390 + static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt) 391 + { 392 + int ret; 393 + struct file *filp; 394 + 395 + ret = get_unused_fd(); 396 + if (ret < 0) { 397 + dput(dentry); 398 + mntput(mnt); 399 + goto out; 400 + } 401 + 402 + filp = dentry_open(dentry, mnt, O_RDONLY); 403 + if (IS_ERR(filp)) { 404 + put_unused_fd(ret); 405 + ret = PTR_ERR(filp); 406 + goto out; 407 + } 408 + 409 + filp->f_op = &spufs_gang_fops; 410 + fd_install(ret, filp); 411 + out: 412 + return ret; 413 + } 414 + 415 + static int spufs_create_gang(struct inode *inode, 416 + struct dentry *dentry, 417 + struct vfsmount *mnt, int mode) 418 + { 419 + int ret; 420 + 421 + ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO); 422 + if (ret) 423 + goto out; 424 + 425 + /* 426 + * get references for dget and mntget, will be released 427 + * in error path of *_open(). 428 + */ 429 + ret = spufs_gang_open(dget(dentry), mntget(mnt)); 430 + if (ret < 0) 431 + WARN_ON(spufs_rmgang(inode, dentry)); 432 + 433 + out: 434 + mutex_unlock(&inode->i_mutex); 435 + dput(dentry); 436 + return ret; 437 + } 438 + 439 + 304 440 static struct file_system_type spufs_type; 305 441 306 - long spufs_create_thread(struct nameidata *nd, 307 - unsigned int flags, mode_t mode) 442 + long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode) 308 443 { 309 444 struct dentry *dentry; 310 445 int ret; 311 446 312 - /* need to be at the root of spufs */ 313 447 ret = -EINVAL; 314 - if (nd->dentry->d_sb->s_type != &spufs_type || 315 - nd->dentry != nd->dentry->d_sb->s_root) 448 + /* check if we are on spufs */ 449 + if (nd->dentry->d_sb->s_type != &spufs_type) 316 450 goto out; 317 451 318 - /* all flags are reserved */ 319 - if (flags) 452 + /* don't accept undefined flags */ 453 + if (flags & (~SPU_CREATE_FLAG_ALL)) 320 454 goto out; 455 + 456 + /* only threads can be underneath a gang */ 457 + if (nd->dentry != nd->dentry->d_sb->s_root) { 458 + if ((flags & SPU_CREATE_GANG) || 459 + !SPUFS_I(nd->dentry->d_inode)->i_gang) 460 + goto out; 461 + } 321 462 322 463 dentry = lookup_create(nd, 1); 323 464 ret = PTR_ERR(dentry); ··· 482 317 goto out_dput; 483 318 484 319 mode &= ~current->fs->umask; 485 - ret = spufs_mkdir(nd->dentry->d_inode, dentry, mode & S_IRWXUGO); 486 - if (ret) 487 - goto out_dput; 488 320 489 - /* 490 - * get references for dget and mntget, will be released 491 - * in error path of *_open(). 492 - */ 493 - ret = spufs_context_open(dget(dentry), mntget(nd->mnt)); 494 - if (ret < 0) { 495 - WARN_ON(spufs_rmdir(nd->dentry->d_inode, dentry)); 496 - mutex_unlock(&nd->dentry->d_inode->i_mutex); 497 - spu_forget(SPUFS_I(dentry->d_inode)->i_ctx); 498 - dput(dentry); 499 - goto out; 500 - } 321 + if (flags & SPU_CREATE_GANG) 322 + return spufs_create_gang(nd->dentry->d_inode, 323 + dentry, nd->mnt, mode); 324 + else 325 + return spufs_create_context(nd->dentry->d_inode, 326 + dentry, nd->mnt, flags, mode); 501 327 502 328 out_dput: 503 329 dput(dentry);
+35 -13
arch/powerpc/platforms/cell/spufs/run.c
··· 14 14 wake_up_all(&ctx->stop_wq); 15 15 } 16 16 17 + void spufs_dma_callback(struct spu *spu, int type) 18 + { 19 + struct spu_context *ctx = spu->ctx; 20 + 21 + if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) { 22 + ctx->event_return |= type; 23 + wake_up_all(&ctx->stop_wq); 24 + } else { 25 + switch (type) { 26 + case SPE_EVENT_DMA_ALIGNMENT: 27 + case SPE_EVENT_INVALID_DMA: 28 + force_sig(SIGBUS, /* info, */ current); 29 + break; 30 + case SPE_EVENT_SPE_ERROR: 31 + force_sig(SIGILL, /* info */ current); 32 + break; 33 + } 34 + } 35 + } 36 + 17 37 static inline int spu_stopped(struct spu_context *ctx, u32 * stat) 18 38 { 19 39 struct spu *spu; ··· 48 28 return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0; 49 29 } 50 30 51 - static inline int spu_run_init(struct spu_context *ctx, u32 * npc, 52 - u32 * status) 31 + static inline int spu_run_init(struct spu_context *ctx, u32 * npc) 53 32 { 54 33 int ret; 55 34 ··· 91 72 SPU_STATUS_STOPPED_BY_HALT)) { 92 73 return *status; 93 74 } 94 - if ((ret = spu_run_init(ctx, npc, status)) != 0) 75 + if ((ret = spu_run_init(ctx, npc)) != 0) 95 76 return ret; 96 77 return 0; 97 78 } ··· 196 177 } 197 178 198 179 long spufs_run_spu(struct file *file, struct spu_context *ctx, 199 - u32 * npc, u32 * status) 180 + u32 *npc, u32 *event) 200 181 { 201 182 int ret; 183 + u32 status; 202 184 203 185 if (down_interruptible(&ctx->run_sema)) 204 186 return -ERESTARTSYS; 205 187 206 - ret = spu_run_init(ctx, npc, status); 188 + ctx->event_return = 0; 189 + ret = spu_run_init(ctx, npc); 207 190 if (ret) 208 191 goto out; 209 192 210 193 do { 211 - ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status)); 194 + ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, &status)); 212 195 if (unlikely(ret)) 213 196 break; 214 - if ((*status & SPU_STATUS_STOPPED_BY_STOP) && 215 - (*status >> SPU_STOP_STATUS_SHIFT == 0x2104)) { 197 + if ((status & SPU_STATUS_STOPPED_BY_STOP) && 198 + (status >> SPU_STOP_STATUS_SHIFT == 0x2104)) { 216 199 ret = spu_process_callback(ctx); 217 200 if (ret) 218 201 break; 219 - *status &= ~SPU_STATUS_STOPPED_BY_STOP; 202 + status &= ~SPU_STATUS_STOPPED_BY_STOP; 220 203 } 221 204 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { 222 - ret = spu_reacquire_runnable(ctx, npc, status); 205 + ret = spu_reacquire_runnable(ctx, npc, &status); 223 206 if (ret) 224 207 goto out; 225 208 continue; 226 209 } 227 210 ret = spu_process_events(ctx); 228 211 229 - } while (!ret && !(*status & (SPU_STATUS_STOPPED_BY_STOP | 212 + } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP | 230 213 SPU_STATUS_STOPPED_BY_HALT))); 231 214 232 215 ctx->ops->runcntl_stop(ctx); 233 - ret = spu_run_fini(ctx, npc, status); 216 + ret = spu_run_fini(ctx, npc, &status); 234 217 if (!ret) 235 - ret = *status; 218 + ret = status; 236 219 spu_yield(ctx); 237 220 238 221 out: 222 + *event = ctx->event_return; 239 223 up(&ctx->run_sema); 240 224 return ret; 241 225 }
+192 -288
arch/powerpc/platforms/cell/spufs/sched.c
··· 3 3 * Copyright (C) IBM 2005 4 4 * Author: Mark Nutter <mnutter@us.ibm.com> 5 5 * 6 - * SPU scheduler, based on Linux thread priority. For now use 7 - * a simple "cooperative" yield model with no preemption. SPU 8 - * scheduling will eventually be preemptive: When a thread with 9 - * a higher static priority gets ready to run, then an active SPU 10 - * context will be preempted and returned to the waitq. 6 + * 2006-03-31 NUMA domains added. 11 7 * 12 8 * This program is free software; you can redistribute it and/or modify 13 9 * it under the terms of the GNU General Public License as published by ··· 33 37 #include <linux/smp_lock.h> 34 38 #include <linux/stddef.h> 35 39 #include <linux/unistd.h> 40 + #include <linux/numa.h> 41 + #include <linux/mutex.h> 42 + #include <linux/notifier.h> 36 43 37 44 #include <asm/io.h> 38 45 #include <asm/mmu_context.h> ··· 48 49 49 50 #define SPU_BITMAP_SIZE (((MAX_PRIO+BITS_PER_LONG)/BITS_PER_LONG)+1) 50 51 struct spu_prio_array { 51 - atomic_t nr_blocked; 52 52 unsigned long bitmap[SPU_BITMAP_SIZE]; 53 53 wait_queue_head_t waitq[MAX_PRIO]; 54 + struct list_head active_list[MAX_NUMNODES]; 55 + struct mutex active_mutex[MAX_NUMNODES]; 54 56 }; 55 57 56 - /* spu_runqueue - This is the main runqueue data structure for SPUs. */ 57 - struct spu_runqueue { 58 - struct semaphore sem; 59 - unsigned long nr_active; 60 - unsigned long nr_idle; 61 - unsigned long nr_switches; 62 - struct list_head active_list; 63 - struct list_head idle_list; 64 - struct spu_prio_array prio; 65 - }; 58 + static struct spu_prio_array *spu_prio; 66 59 67 - static struct spu_runqueue *spu_runqueues = NULL; 68 - 69 - static inline struct spu_runqueue *spu_rq(void) 60 + static inline int node_allowed(int node) 70 61 { 71 - /* Future: make this a per-NODE array, 72 - * and use cpu_to_node(smp_processor_id()) 73 - */ 74 - return spu_runqueues; 75 - } 62 + cpumask_t mask; 76 63 77 - static inline struct spu *del_idle(struct spu_runqueue *rq) 78 - { 79 - struct spu *spu; 80 - 81 - BUG_ON(rq->nr_idle <= 0); 82 - BUG_ON(list_empty(&rq->idle_list)); 83 - /* Future: Move SPU out of low-power SRI state. */ 84 - spu = list_entry(rq->idle_list.next, struct spu, sched_list); 85 - list_del_init(&spu->sched_list); 86 - rq->nr_idle--; 87 - return spu; 88 - } 89 - 90 - static inline void del_active(struct spu_runqueue *rq, struct spu *spu) 91 - { 92 - BUG_ON(rq->nr_active <= 0); 93 - BUG_ON(list_empty(&rq->active_list)); 94 - list_del_init(&spu->sched_list); 95 - rq->nr_active--; 96 - } 97 - 98 - static inline void add_idle(struct spu_runqueue *rq, struct spu *spu) 99 - { 100 - /* Future: Put SPU into low-power SRI state. */ 101 - list_add_tail(&spu->sched_list, &rq->idle_list); 102 - rq->nr_idle++; 103 - } 104 - 105 - static inline void add_active(struct spu_runqueue *rq, struct spu *spu) 106 - { 107 - rq->nr_active++; 108 - rq->nr_switches++; 109 - list_add_tail(&spu->sched_list, &rq->active_list); 110 - } 111 - 112 - static void prio_wakeup(struct spu_runqueue *rq) 113 - { 114 - if (atomic_read(&rq->prio.nr_blocked) && rq->nr_idle) { 115 - int best = sched_find_first_bit(rq->prio.bitmap); 116 - if (best < MAX_PRIO) { 117 - wait_queue_head_t *wq = &rq->prio.waitq[best]; 118 - wake_up_interruptible_nr(wq, 1); 119 - } 120 - } 121 - } 122 - 123 - static void prio_wait(struct spu_runqueue *rq, struct spu_context *ctx, 124 - u64 flags) 125 - { 126 - int prio = current->prio; 127 - wait_queue_head_t *wq = &rq->prio.waitq[prio]; 128 - DEFINE_WAIT(wait); 129 - 130 - __set_bit(prio, rq->prio.bitmap); 131 - atomic_inc(&rq->prio.nr_blocked); 132 - prepare_to_wait_exclusive(wq, &wait, TASK_INTERRUPTIBLE); 133 - if (!signal_pending(current)) { 134 - up(&rq->sem); 135 - up_write(&ctx->state_sema); 136 - pr_debug("%s: pid=%d prio=%d\n", __FUNCTION__, 137 - current->pid, current->prio); 138 - schedule(); 139 - down_write(&ctx->state_sema); 140 - down(&rq->sem); 141 - } 142 - finish_wait(wq, &wait); 143 - atomic_dec(&rq->prio.nr_blocked); 144 - if (!waitqueue_active(wq)) 145 - __clear_bit(prio, rq->prio.bitmap); 146 - } 147 - 148 - static inline int is_best_prio(struct spu_runqueue *rq) 149 - { 150 - int best_prio; 151 - 152 - best_prio = sched_find_first_bit(rq->prio.bitmap); 153 - return (current->prio < best_prio) ? 1 : 0; 64 + if (!nr_cpus_node(node)) 65 + return 0; 66 + mask = node_to_cpumask(node); 67 + if (!cpus_intersects(mask, current->cpus_allowed)) 68 + return 0; 69 + return 1; 154 70 } 155 71 156 72 static inline void mm_needs_global_tlbie(struct mm_struct *mm) 157 73 { 74 + int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1; 75 + 158 76 /* Global TLBIE broadcast required with SPEs. */ 159 - #if (NR_CPUS > 1) 160 - __cpus_setall(&mm->cpu_vm_mask, NR_CPUS); 161 - #else 162 - __cpus_setall(&mm->cpu_vm_mask, NR_CPUS+1); /* is this ok? */ 163 - #endif 77 + __cpus_setall(&mm->cpu_vm_mask, nr); 164 78 } 79 + 80 + static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier); 81 + 82 + static void spu_switch_notify(struct spu *spu, struct spu_context *ctx) 83 + { 84 + blocking_notifier_call_chain(&spu_switch_notifier, 85 + ctx ? ctx->object_id : 0, spu); 86 + } 87 + 88 + int spu_switch_event_register(struct notifier_block * n) 89 + { 90 + return blocking_notifier_chain_register(&spu_switch_notifier, n); 91 + } 92 + 93 + int spu_switch_event_unregister(struct notifier_block * n) 94 + { 95 + return blocking_notifier_chain_unregister(&spu_switch_notifier, n); 96 + } 97 + 165 98 166 99 static inline void bind_context(struct spu *spu, struct spu_context *ctx) 167 100 { 168 - pr_debug("%s: pid=%d SPU=%d\n", __FUNCTION__, current->pid, 169 - spu->number); 101 + pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid, 102 + spu->number, spu->node); 170 103 spu->ctx = ctx; 171 104 spu->flags = 0; 172 - ctx->flags = 0; 173 105 ctx->spu = spu; 174 106 ctx->ops = &spu_hw_ops; 175 107 spu->pid = current->pid; ··· 111 181 spu->wbox_callback = spufs_wbox_callback; 112 182 spu->stop_callback = spufs_stop_callback; 113 183 spu->mfc_callback = spufs_mfc_callback; 184 + spu->dma_callback = spufs_dma_callback; 114 185 mb(); 115 186 spu_unmap_mappings(ctx); 116 187 spu_restore(&ctx->csa, spu); 117 188 spu->timestamp = jiffies; 189 + spu_cpu_affinity_set(spu, raw_smp_processor_id()); 190 + spu_switch_notify(spu, ctx); 118 191 } 119 192 120 193 static inline void unbind_context(struct spu *spu, struct spu_context *ctx) 121 194 { 122 - pr_debug("%s: unbind pid=%d SPU=%d\n", __FUNCTION__, 123 - spu->pid, spu->number); 195 + pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__, 196 + spu->pid, spu->number, spu->node); 197 + spu_switch_notify(spu, NULL); 124 198 spu_unmap_mappings(ctx); 125 199 spu_save(&ctx->csa, spu); 126 200 spu->timestamp = jiffies; ··· 133 199 spu->wbox_callback = NULL; 134 200 spu->stop_callback = NULL; 135 201 spu->mfc_callback = NULL; 202 + spu->dma_callback = NULL; 136 203 spu->mm = NULL; 137 204 spu->pid = 0; 138 205 spu->prio = MAX_PRIO; 139 206 ctx->ops = &spu_backing_ops; 140 207 ctx->spu = NULL; 141 - ctx->flags = 0; 142 208 spu->flags = 0; 143 209 spu->ctx = NULL; 144 210 } 145 211 146 - static void spu_reaper(void *data) 212 + static inline void spu_add_wq(wait_queue_head_t * wq, wait_queue_t * wait, 213 + int prio) 147 214 { 148 - struct spu_context *ctx = data; 149 - struct spu *spu; 215 + prepare_to_wait_exclusive(wq, wait, TASK_INTERRUPTIBLE); 216 + set_bit(prio, spu_prio->bitmap); 217 + } 150 218 151 - down_write(&ctx->state_sema); 152 - spu = ctx->spu; 153 - if (spu && test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) { 154 - if (atomic_read(&spu->rq->prio.nr_blocked)) { 155 - pr_debug("%s: spu=%d\n", __func__, spu->number); 156 - ctx->ops->runcntl_stop(ctx); 157 - spu_deactivate(ctx); 158 - wake_up_all(&ctx->stop_wq); 159 - } else { 160 - clear_bit(SPU_CONTEXT_PREEMPT, &ctx->flags); 161 - } 219 + static inline void spu_del_wq(wait_queue_head_t * wq, wait_queue_t * wait, 220 + int prio) 221 + { 222 + u64 flags; 223 + 224 + __set_current_state(TASK_RUNNING); 225 + 226 + spin_lock_irqsave(&wq->lock, flags); 227 + 228 + remove_wait_queue_locked(wq, wait); 229 + if (list_empty(&wq->task_list)) 230 + clear_bit(prio, spu_prio->bitmap); 231 + 232 + spin_unlock_irqrestore(&wq->lock, flags); 233 + } 234 + 235 + static void spu_prio_wait(struct spu_context *ctx, u64 flags) 236 + { 237 + int prio = current->prio; 238 + wait_queue_head_t *wq = &spu_prio->waitq[prio]; 239 + DEFINE_WAIT(wait); 240 + 241 + if (ctx->spu) 242 + return; 243 + 244 + spu_add_wq(wq, &wait, prio); 245 + 246 + if (!signal_pending(current)) { 247 + up_write(&ctx->state_sema); 248 + pr_debug("%s: pid=%d prio=%d\n", __FUNCTION__, 249 + current->pid, current->prio); 250 + schedule(); 251 + down_write(&ctx->state_sema); 162 252 } 163 - up_write(&ctx->state_sema); 164 - put_spu_context(ctx); 253 + 254 + spu_del_wq(wq, &wait, prio); 165 255 } 166 256 167 - static void schedule_spu_reaper(struct spu_runqueue *rq, struct spu *spu) 257 + static void spu_prio_wakeup(void) 168 258 { 169 - struct spu_context *ctx = get_spu_context(spu->ctx); 170 - unsigned long now = jiffies; 171 - unsigned long expire = spu->timestamp + SPU_MIN_TIMESLICE; 172 - 173 - set_bit(SPU_CONTEXT_PREEMPT, &ctx->flags); 174 - INIT_WORK(&ctx->reap_work, spu_reaper, ctx); 175 - if (time_after(now, expire)) 176 - schedule_work(&ctx->reap_work); 177 - else 178 - schedule_delayed_work(&ctx->reap_work, expire - now); 179 - } 180 - 181 - static void check_preempt_active(struct spu_runqueue *rq) 182 - { 183 - struct list_head *p; 184 - struct spu *worst = NULL; 185 - 186 - list_for_each(p, &rq->active_list) { 187 - struct spu *spu = list_entry(p, struct spu, sched_list); 188 - struct spu_context *ctx = spu->ctx; 189 - if (!test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) { 190 - if (!worst || (spu->prio > worst->prio)) { 191 - worst = spu; 192 - } 193 - } 259 + int best = sched_find_first_bit(spu_prio->bitmap); 260 + if (best < MAX_PRIO) { 261 + wait_queue_head_t *wq = &spu_prio->waitq[best]; 262 + wake_up_interruptible_nr(wq, 1); 194 263 } 195 - if (worst && (current->prio < worst->prio)) 196 - schedule_spu_reaper(rq, worst); 197 - } 198 - 199 - static struct spu *get_idle_spu(struct spu_context *ctx, u64 flags) 200 - { 201 - struct spu_runqueue *rq; 202 - struct spu *spu = NULL; 203 - 204 - rq = spu_rq(); 205 - down(&rq->sem); 206 - for (;;) { 207 - if (rq->nr_idle > 0) { 208 - if (is_best_prio(rq)) { 209 - /* Fall through. */ 210 - spu = del_idle(rq); 211 - break; 212 - } else { 213 - prio_wakeup(rq); 214 - up(&rq->sem); 215 - yield(); 216 - if (signal_pending(current)) { 217 - return NULL; 218 - } 219 - rq = spu_rq(); 220 - down(&rq->sem); 221 - continue; 222 - } 223 - } else { 224 - check_preempt_active(rq); 225 - prio_wait(rq, ctx, flags); 226 - if (signal_pending(current)) { 227 - prio_wakeup(rq); 228 - spu = NULL; 229 - break; 230 - } 231 - continue; 232 - } 233 - } 234 - up(&rq->sem); 235 - return spu; 236 - } 237 - 238 - static void put_idle_spu(struct spu *spu) 239 - { 240 - struct spu_runqueue *rq = spu->rq; 241 - 242 - down(&rq->sem); 243 - add_idle(rq, spu); 244 - prio_wakeup(rq); 245 - up(&rq->sem); 246 264 } 247 265 248 266 static int get_active_spu(struct spu *spu) 249 267 { 250 - struct spu_runqueue *rq = spu->rq; 251 - struct list_head *p; 268 + int node = spu->node; 252 269 struct spu *tmp; 253 270 int rc = 0; 254 271 255 - down(&rq->sem); 256 - list_for_each(p, &rq->active_list) { 257 - tmp = list_entry(p, struct spu, sched_list); 272 + mutex_lock(&spu_prio->active_mutex[node]); 273 + list_for_each_entry(tmp, &spu_prio->active_list[node], list) { 258 274 if (tmp == spu) { 259 - del_active(rq, spu); 275 + list_del_init(&spu->list); 260 276 rc = 1; 261 277 break; 262 278 } 263 279 } 264 - up(&rq->sem); 280 + mutex_unlock(&spu_prio->active_mutex[node]); 265 281 return rc; 266 282 } 267 283 268 284 static void put_active_spu(struct spu *spu) 269 285 { 270 - struct spu_runqueue *rq = spu->rq; 286 + int node = spu->node; 271 287 272 - down(&rq->sem); 273 - add_active(rq, spu); 274 - up(&rq->sem); 288 + mutex_lock(&spu_prio->active_mutex[node]); 289 + list_add_tail(&spu->list, &spu_prio->active_list[node]); 290 + mutex_unlock(&spu_prio->active_mutex[node]); 275 291 } 276 292 277 - /* Lock order: 278 - * spu_activate() & spu_deactivate() require the 279 - * caller to have down_write(&ctx->state_sema). 293 + static struct spu *spu_get_idle(struct spu_context *ctx, u64 flags) 294 + { 295 + struct spu *spu = NULL; 296 + int node = cpu_to_node(raw_smp_processor_id()); 297 + int n; 298 + 299 + for (n = 0; n < MAX_NUMNODES; n++, node++) { 300 + node = (node < MAX_NUMNODES) ? node : 0; 301 + if (!node_allowed(node)) 302 + continue; 303 + spu = spu_alloc_node(node); 304 + if (spu) 305 + break; 306 + } 307 + return spu; 308 + } 309 + 310 + static inline struct spu *spu_get(struct spu_context *ctx, u64 flags) 311 + { 312 + /* Future: spu_get_idle() if possible, 313 + * otherwise try to preempt an active 314 + * context. 315 + */ 316 + return spu_get_idle(ctx, flags); 317 + } 318 + 319 + /* The three externally callable interfaces 320 + * for the scheduler begin here. 280 321 * 281 - * The rq->sem is breifly held (inside or outside a 282 - * given ctx lock) for list management, but is never 283 - * held during save/restore. 322 + * spu_activate - bind a context to SPU, waiting as needed. 323 + * spu_deactivate - unbind a context from its SPU. 324 + * spu_yield - yield an SPU if others are waiting. 284 325 */ 285 326 286 327 int spu_activate(struct spu_context *ctx, u64 flags) 287 328 { 288 329 struct spu *spu; 330 + int ret = 0; 289 331 290 - if (ctx->spu) 291 - return 0; 292 - spu = get_idle_spu(ctx, flags); 293 - if (!spu) 294 - return (signal_pending(current)) ? -ERESTARTSYS : -EAGAIN; 295 - bind_context(spu, ctx); 296 - /* 297 - * We're likely to wait for interrupts on the same 298 - * CPU that we are now on, so send them here. 299 - */ 300 - spu_cpu_affinity_set(spu, raw_smp_processor_id()); 301 - put_active_spu(spu); 302 - return 0; 332 + for (;;) { 333 + if (ctx->spu) 334 + return 0; 335 + spu = spu_get(ctx, flags); 336 + if (spu != NULL) { 337 + if (ctx->spu != NULL) { 338 + spu_free(spu); 339 + spu_prio_wakeup(); 340 + break; 341 + } 342 + bind_context(spu, ctx); 343 + put_active_spu(spu); 344 + break; 345 + } 346 + spu_prio_wait(ctx, flags); 347 + if (signal_pending(current)) { 348 + ret = -ERESTARTSYS; 349 + spu_prio_wakeup(); 350 + break; 351 + } 352 + } 353 + return ret; 303 354 } 304 355 305 356 void spu_deactivate(struct spu_context *ctx) ··· 297 378 return; 298 379 needs_idle = get_active_spu(spu); 299 380 unbind_context(spu, ctx); 300 - if (needs_idle) 301 - put_idle_spu(spu); 381 + if (needs_idle) { 382 + spu_free(spu); 383 + spu_prio_wakeup(); 384 + } 302 385 } 303 386 304 387 void spu_yield(struct spu_context *ctx) ··· 308 387 struct spu *spu; 309 388 int need_yield = 0; 310 389 311 - down_write(&ctx->state_sema); 312 - spu = ctx->spu; 313 - if (spu && (sched_find_first_bit(spu->rq->prio.bitmap) < MAX_PRIO)) { 314 - pr_debug("%s: yielding SPU %d\n", __FUNCTION__, spu->number); 315 - spu_deactivate(ctx); 316 - ctx->state = SPU_STATE_SAVED; 317 - need_yield = 1; 318 - } else if (spu) { 319 - spu->prio = MAX_PRIO; 390 + if (down_write_trylock(&ctx->state_sema)) { 391 + if ((spu = ctx->spu) != NULL) { 392 + int best = sched_find_first_bit(spu_prio->bitmap); 393 + if (best < MAX_PRIO) { 394 + pr_debug("%s: yielding SPU %d NODE %d\n", 395 + __FUNCTION__, spu->number, spu->node); 396 + spu_deactivate(ctx); 397 + ctx->state = SPU_STATE_SAVED; 398 + need_yield = 1; 399 + } else { 400 + spu->prio = MAX_PRIO; 401 + } 402 + } 403 + up_write(&ctx->state_sema); 320 404 } 321 - up_write(&ctx->state_sema); 322 405 if (unlikely(need_yield)) 323 406 yield(); 324 407 } 325 408 326 409 int __init spu_sched_init(void) 327 410 { 328 - struct spu_runqueue *rq; 329 - struct spu *spu; 330 411 int i; 331 412 332 - rq = spu_runqueues = kmalloc(sizeof(struct spu_runqueue), GFP_KERNEL); 333 - if (!rq) { 334 - printk(KERN_WARNING "%s: Unable to allocate runqueues.\n", 413 + spu_prio = kzalloc(sizeof(struct spu_prio_array), GFP_KERNEL); 414 + if (!spu_prio) { 415 + printk(KERN_WARNING "%s: Unable to allocate priority queue.\n", 335 416 __FUNCTION__); 336 417 return 1; 337 418 } 338 - memset(rq, 0, sizeof(struct spu_runqueue)); 339 - init_MUTEX(&rq->sem); 340 - INIT_LIST_HEAD(&rq->active_list); 341 - INIT_LIST_HEAD(&rq->idle_list); 342 - rq->nr_active = 0; 343 - rq->nr_idle = 0; 344 - rq->nr_switches = 0; 345 - atomic_set(&rq->prio.nr_blocked, 0); 346 419 for (i = 0; i < MAX_PRIO; i++) { 347 - init_waitqueue_head(&rq->prio.waitq[i]); 348 - __clear_bit(i, rq->prio.bitmap); 420 + init_waitqueue_head(&spu_prio->waitq[i]); 421 + __clear_bit(i, spu_prio->bitmap); 349 422 } 350 - __set_bit(MAX_PRIO, rq->prio.bitmap); 351 - for (;;) { 352 - spu = spu_alloc(); 353 - if (!spu) 354 - break; 355 - pr_debug("%s: adding SPU[%d]\n", __FUNCTION__, spu->number); 356 - add_idle(rq, spu); 357 - spu->rq = rq; 358 - spu->timestamp = jiffies; 359 - } 360 - if (!rq->nr_idle) { 361 - printk(KERN_WARNING "%s: No available SPUs.\n", __FUNCTION__); 362 - kfree(rq); 363 - return 1; 423 + __set_bit(MAX_PRIO, spu_prio->bitmap); 424 + for (i = 0; i < MAX_NUMNODES; i++) { 425 + mutex_init(&spu_prio->active_mutex[i]); 426 + INIT_LIST_HEAD(&spu_prio->active_list[i]); 364 427 } 365 428 return 0; 366 429 } 367 430 368 431 void __exit spu_sched_exit(void) 369 432 { 370 - struct spu_runqueue *rq = spu_rq(); 371 - struct spu *spu; 433 + struct spu *spu, *tmp; 434 + int node; 372 435 373 - if (!rq) { 374 - printk(KERN_WARNING "%s: no runqueues!\n", __FUNCTION__); 375 - return; 436 + for (node = 0; node < MAX_NUMNODES; node++) { 437 + mutex_lock(&spu_prio->active_mutex[node]); 438 + list_for_each_entry_safe(spu, tmp, &spu_prio->active_list[node], 439 + list) { 440 + list_del_init(&spu->list); 441 + spu_free(spu); 442 + } 443 + mutex_unlock(&spu_prio->active_mutex[node]); 376 444 } 377 - while (rq->nr_idle > 0) { 378 - spu = del_idle(rq); 379 - if (!spu) 380 - break; 381 - spu_free(spu); 382 - } 383 - kfree(rq); 445 + kfree(spu_prio); 384 446 }
+26 -3
arch/powerpc/platforms/cell/spufs/spufs.h
··· 39 39 40 40 #define SPU_CONTEXT_PREEMPT 0UL 41 41 42 + struct spu_gang; 43 + 42 44 struct spu_context { 43 45 struct spu *spu; /* pointer to a physical SPU */ 44 46 struct spu_state csa; /* SPU context save area. */ ··· 50 48 struct address_space *cntl; /* 'control' area mappings. */ 51 49 struct address_space *signal1; /* 'signal1' area mappings. */ 52 50 struct address_space *signal2; /* 'signal2' area mappings. */ 51 + u64 object_id; /* user space pointer for oprofile */ 53 52 54 53 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; 55 54 struct rw_semaphore state_sema; ··· 69 66 u32 tagwait; 70 67 struct spu_context_ops *ops; 71 68 struct work_struct reap_work; 72 - u64 flags; 69 + unsigned long flags; 70 + unsigned long event_return; 71 + 72 + struct list_head gang_list; 73 + struct spu_gang *gang; 74 + }; 75 + 76 + struct spu_gang { 77 + struct list_head list; 78 + struct mutex mutex; 79 + struct kref kref; 80 + int contexts; 73 81 }; 74 82 75 83 struct mfc_dma_command { ··· 128 114 129 115 struct spufs_inode_info { 130 116 struct spu_context *i_ctx; 117 + struct spu_gang *i_gang; 131 118 struct inode vfs_inode; 132 119 }; 133 120 #define SPUFS_I(inode) \ ··· 139 124 /* system call implementation */ 140 125 long spufs_run_spu(struct file *file, 141 126 struct spu_context *ctx, u32 *npc, u32 *status); 142 - long spufs_create_thread(struct nameidata *nd, 127 + long spufs_create(struct nameidata *nd, 143 128 unsigned int flags, mode_t mode); 144 129 extern struct file_operations spufs_context_fops; 145 130 131 + /* gang management */ 132 + struct spu_gang *alloc_spu_gang(void); 133 + struct spu_gang *get_spu_gang(struct spu_gang *gang); 134 + int put_spu_gang(struct spu_gang *gang); 135 + void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx); 136 + void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx); 137 + 146 138 /* context management */ 147 - struct spu_context * alloc_spu_context(void); 139 + struct spu_context * alloc_spu_context(struct spu_gang *gang); 148 140 void destroy_spu_context(struct kref *kref); 149 141 struct spu_context * get_spu_context(struct spu_context *ctx); 150 142 int put_spu_context(struct spu_context *ctx); ··· 205 183 void spufs_wbox_callback(struct spu *spu); 206 184 void spufs_stop_callback(struct spu *spu); 207 185 void spufs_mfc_callback(struct spu *spu); 186 + void spufs_dma_callback(struct spu *spu, int type); 208 187 209 188 #endif
+9
arch/powerpc/platforms/cell/spufs/switch.c
··· 1779 1779 */ 1780 1780 out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW); 1781 1781 eieio(); 1782 + /* 1783 + * FIXME: this is to restart a DMA that we were processing 1784 + * before the save. better remember the fault information 1785 + * in the csa instead. 1786 + */ 1787 + if ((csa->priv2.mfc_control_RW & MFC_CNTL_SUSPEND_DMA_QUEUE_MASK)) { 1788 + out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); 1789 + eieio(); 1790 + } 1782 1791 } 1783 1792 1784 1793 static inline void enable_user_access(struct spu_state *csa, struct spu *spu)
+6 -3
arch/powerpc/platforms/cell/spufs/syscalls.c
··· 38 38 u32 npc, status; 39 39 40 40 ret = -EFAULT; 41 - if (get_user(npc, unpc) || get_user(status, ustatus)) 41 + if (get_user(npc, unpc)) 42 42 goto out; 43 43 44 44 /* check if this file was created by spu_create */ ··· 49 49 i = SPUFS_I(filp->f_dentry->d_inode); 50 50 ret = spufs_run_spu(filp, i->i_ctx, &npc, &status); 51 51 52 - if (put_user(npc, unpc) || put_user(status, ustatus)) 52 + if (put_user(npc, unpc)) 53 + ret = -EFAULT; 54 + 55 + if (ustatus && put_user(status, ustatus)) 53 56 ret = -EFAULT; 54 57 out: 55 58 return ret; ··· 90 87 ret = path_lookup(tmp, LOOKUP_PARENT| 91 88 LOOKUP_OPEN|LOOKUP_CREATE, &nd); 92 89 if (!ret) { 93 - ret = spufs_create_thread(&nd, flags, mode); 90 + ret = spufs_create(&nd, flags, mode); 94 91 path_release(&nd); 95 92 } 96 93 putname(tmp);
+36
include/asm-powerpc/spu.h
··· 138 138 void (* ibox_callback)(struct spu *spu); 139 139 void (* stop_callback)(struct spu *spu); 140 140 void (* mfc_callback)(struct spu *spu); 141 + void (* dma_callback)(struct spu *spu, int type); 141 142 142 143 char irq_c0[8]; 143 144 char irq_c1[8]; ··· 148 147 }; 149 148 150 149 struct spu *spu_alloc(void); 150 + struct spu *spu_alloc_node(int node); 151 151 void spu_free(struct spu *spu); 152 152 int spu_irq_class_0_bottom(struct spu *spu); 153 153 int spu_irq_class_1_bottom(struct spu *spu); ··· 170 168 struct module *owner; 171 169 } spufs_calls; 172 170 171 + /* return status from spu_run, same as in libspe */ 172 + #define SPE_EVENT_DMA_ALIGNMENT 0x0008 /*A DMA alignment error */ 173 + #define SPE_EVENT_SPE_ERROR 0x0010 /*An illegal instruction error*/ 174 + #define SPE_EVENT_SPE_DATA_SEGMENT 0x0020 /*A DMA segmentation error */ 175 + #define SPE_EVENT_SPE_DATA_STORAGE 0x0040 /*A DMA storage error */ 176 + #define SPE_EVENT_INVALID_DMA 0x0800 /* Invalid MFC DMA */ 177 + 178 + /* 179 + * Flags for sys_spu_create. 180 + */ 181 + #define SPU_CREATE_EVENTS_ENABLED 0x0001 182 + #define SPU_CREATE_GANG 0x0002 183 + 184 + #define SPU_CREATE_FLAG_ALL 0x0003 /* mask of all valid flags */ 185 + 186 + 173 187 #ifdef CONFIG_SPU_FS_MODULE 174 188 int register_spu_syscalls(struct spufs_calls *calls); 175 189 void unregister_spu_syscalls(struct spufs_calls *calls); ··· 199 181 } 200 182 #endif /* MODULE */ 201 183 184 + 185 + /* 186 + * Notifier blocks: 187 + * 188 + * oprofile can get notified when a context switch is performed 189 + * on an spe. The notifer function that gets called is passed 190 + * a pointer to the SPU structure as well as the object-id that 191 + * identifies the binary running on that SPU now. 192 + * 193 + * For a context save, the object-id that is passed is zero, 194 + * identifying that the kernel will run from that moment on. 195 + * 196 + * For a context restore, the object-id is the value written 197 + * to object-id spufs file from user space and the notifer 198 + * function can assume that spu->ctx is valid. 199 + */ 200 + int spu_switch_event_register(struct notifier_block * n); 201 + int spu_switch_event_unregister(struct notifier_block * n); 202 202 203 203 /* 204 204 * This defines the Local Store, Problem Area and Privlege Area of an SPU.