aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spu_base.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2007-07-20 15:39:54 -0400
committerArnd Bergmann <arnd@klappe.arndb.de>2007-07-20 15:42:28 -0400
commit486acd4850dde6d2f8c7f431432f3914c4bfb5f5 (patch)
tree610d93bad54ca3626a55ae78c9cde4a302aecc45 /arch/powerpc/platforms/cell/spu_base.c
parent1474855d0878cced6f39f51f3c2bd7428b44cb1e (diff)
[CELL] spufs: rework list management and associated locking
This sorts out the various lists and related locks in the spu code. In detail: - the per-node free_spus and active_list are gone. Instead struct spu gained an alloc_state member telling whether the spu is free or not - the per-node spus array is now locked by a per-node mutex, which takes over from the global spu_lock and the per-node active_mutex - the spu_alloc* and spu_free function are gone as the state change is now done inline in the spufs code. This allows some more sharing of code for the affinity vs normal case and more efficient locking - some little refactoring in the affinity code for this locking scheme Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Diffstat (limited to 'arch/powerpc/platforms/cell/spu_base.c')
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c72
1 files changed, 7 insertions, 65 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 8617b507af4..90124228b8f 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -409,7 +409,7 @@ static void spu_free_irqs(struct spu *spu)
409 free_irq(spu->irqs[2], spu); 409 free_irq(spu->irqs[2], spu);
410} 410}
411 411
412static void spu_init_channels(struct spu *spu) 412void spu_init_channels(struct spu *spu)
413{ 413{
414 static const struct { 414 static const struct {
415 unsigned channel; 415 unsigned channel;
@@ -442,66 +442,7 @@ static void spu_init_channels(struct spu *spu)
442 out_be64(&priv2->spu_chnlcnt_RW, count_list[i].count); 442 out_be64(&priv2->spu_chnlcnt_RW, count_list[i].count);
443 } 443 }
444} 444}
445 445EXPORT_SYMBOL_GPL(spu_init_channels);
446struct spu *spu_alloc_spu(struct spu *req_spu)
447{
448 struct spu *spu, *ret = NULL;
449
450 spin_lock(&spu_lock);
451 list_for_each_entry(spu, &cbe_spu_info[req_spu->node].free_spus, list) {
452 if (spu == req_spu) {
453 list_del_init(&spu->list);
454 pr_debug("Got SPU %d %d\n", spu->number, spu->node);
455 spu_init_channels(spu);
456 ret = spu;
457 break;
458 }
459 }
460 spin_unlock(&spu_lock);
461 return ret;
462}
463EXPORT_SYMBOL_GPL(spu_alloc_spu);
464
465struct spu *spu_alloc_node(int node)
466{
467 struct spu *spu = NULL;
468
469 spin_lock(&spu_lock);
470 if (!list_empty(&cbe_spu_info[node].free_spus)) {
471 spu = list_entry(cbe_spu_info[node].free_spus.next, struct spu,
472 list);
473 list_del_init(&spu->list);
474 pr_debug("Got SPU %d %d\n", spu->number, spu->node);
475 }
476 spin_unlock(&spu_lock);
477
478 if (spu)
479 spu_init_channels(spu);
480 return spu;
481}
482EXPORT_SYMBOL_GPL(spu_alloc_node);
483
484struct spu *spu_alloc(void)
485{
486 struct spu *spu = NULL;
487 int node;
488
489 for (node = 0; node < MAX_NUMNODES; node++) {
490 spu = spu_alloc_node(node);
491 if (spu)
492 break;
493 }
494
495 return spu;
496}
497
498void spu_free(struct spu *spu)
499{
500 spin_lock(&spu_lock);
501 list_add_tail(&spu->list, &cbe_spu_info[spu->node].free_spus);
502 spin_unlock(&spu_lock);
503}
504EXPORT_SYMBOL_GPL(spu_free);
505 446
506static int spu_shutdown(struct sys_device *sysdev) 447static int spu_shutdown(struct sys_device *sysdev)
507{ 448{
@@ -597,6 +538,8 @@ static int __init create_spu(void *data)
597 if (!spu) 538 if (!spu)
598 goto out; 539 goto out;
599 540
541 spu->alloc_state = SPU_FREE;
542
600 spin_lock_init(&spu->register_lock); 543 spin_lock_init(&spu->register_lock);
601 spin_lock(&spu_lock); 544 spin_lock(&spu_lock);
602 spu->number = number++; 545 spu->number = number++;
@@ -617,11 +560,10 @@ static int __init create_spu(void *data)
617 if (ret) 560 if (ret)
618 goto out_free_irqs; 561 goto out_free_irqs;
619 562
620 spin_lock(&spu_lock); 563 mutex_lock(&cbe_spu_info[spu->node].list_mutex);
621 list_add(&spu->list, &cbe_spu_info[spu->node].free_spus);
622 list_add(&spu->cbe_list, &cbe_spu_info[spu->node].spus); 564 list_add(&spu->cbe_list, &cbe_spu_info[spu->node].spus);
623 cbe_spu_info[spu->node].n_spus++; 565 cbe_spu_info[spu->node].n_spus++;
624 spin_unlock(&spu_lock); 566 mutex_unlock(&cbe_spu_info[spu->node].list_mutex);
625 567
626 mutex_lock(&spu_full_list_mutex); 568 mutex_lock(&spu_full_list_mutex);
627 spin_lock_irqsave(&spu_full_list_lock, flags); 569 spin_lock_irqsave(&spu_full_list_lock, flags);
@@ -831,8 +773,8 @@ static int __init init_spu_base(void)
831 int i, ret = 0; 773 int i, ret = 0;
832 774
833 for (i = 0; i < MAX_NUMNODES; i++) { 775 for (i = 0; i < MAX_NUMNODES; i++) {
776 mutex_init(&cbe_spu_info[i].list_mutex);
834 INIT_LIST_HEAD(&cbe_spu_info[i].spus); 777 INIT_LIST_HEAD(&cbe_spu_info[i].spus);
835 INIT_LIST_HEAD(&cbe_spu_info[i].free_spus);
836 } 778 }
837 779
838 if (!spu_management_ops) 780 if (!spu_management_ops)