aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2007-07-20 21:39:44 +0200
committerArnd Bergmann <arnd@klappe.arndb.de>2007-07-20 21:42:11 +0200
commitaa6d5b20254a21b69092dd839b70ee148303ef25 (patch)
tree0519330e2e4eb6360866dbf2104ed987e4bdd2c0 /arch
parent[CELL] spufs: use find_first_bit() instead of sched_find_first_bit() (diff)
downloadlinux-dev-aa6d5b20254a21b69092dd839b70ee148303ef25.tar.xz
linux-dev-aa6d5b20254a21b69092dd839b70ee148303ef25.zip
[CELL] cell: add per BE structure with info about its SPUs
Addition of a spufs-global "cbe_info" array. Each entry contains information about one Cell/B.E. node, namelly: * list of spus (both free and busy spus are in this list); * list of free spus (replacing the static spu_list from spu_base.c) * number of spus; * number of reserved (non scheduleable) spus. SPE affinity implementation actually requires only access to one spu per BE node (since it implements its own pointer to walk through the other spus of the ring) and the number of scheduleable spus (n_spus - non_sched_spus) However having this more general structure can be useful for other functionalities, concentrating per-cbe statistics / data. Signed-off-by: Andre Detsch <adetsch@br.ibm.com> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c21
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c5
2 files changed, 19 insertions, 7 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index caaf2bf78cad..dd632e5feff3 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -41,7 +41,6 @@ EXPORT_SYMBOL_GPL(spu_management_ops);
const struct spu_priv1_ops *spu_priv1_ops;
-static struct list_head spu_list[MAX_NUMNODES];
static LIST_HEAD(spu_full_list);
static DEFINE_MUTEX(spu_mutex);
static DEFINE_SPINLOCK(spu_list_lock);
@@ -429,8 +428,9 @@ struct spu *spu_alloc_node(int node)
struct spu *spu = NULL;
mutex_lock(&spu_mutex);
- if (!list_empty(&spu_list[node])) {
- spu = list_entry(spu_list[node].next, struct spu, list);
+ if (!list_empty(&cbe_spu_info[node].free_spus)) {
+ spu = list_entry(cbe_spu_info[node].free_spus.next, struct spu,
+ list);
list_del_init(&spu->list);
pr_debug("Got SPU %d %d\n", spu->number, spu->node);
}
@@ -459,7 +459,7 @@ struct spu *spu_alloc(void)
void spu_free(struct spu *spu)
{
mutex_lock(&spu_mutex);
- list_add_tail(&spu->list, &spu_list[spu->node]);
+ list_add_tail(&spu->list, &cbe_spu_info[spu->node].free_spus);
mutex_unlock(&spu_mutex);
}
EXPORT_SYMBOL_GPL(spu_free);
@@ -582,7 +582,9 @@ static int __init create_spu(void *data)
mutex_lock(&spu_mutex);
spin_lock_irqsave(&spu_list_lock, flags);
- list_add(&spu->list, &spu_list[spu->node]);
+ list_add(&spu->list, &cbe_spu_info[spu->node].free_spus);
+ list_add(&spu->cbe_list, &cbe_spu_info[spu->node].spus);
+ cbe_spu_info[spu->node].n_spus++;
list_add(&spu->full_list, &spu_full_list);
spin_unlock_irqrestore(&spu_list_lock, flags);
mutex_unlock(&spu_mutex);
@@ -650,12 +652,17 @@ static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf)
static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL);
+struct cbe_spu_info cbe_spu_info[MAX_NUMNODES];
+EXPORT_SYMBOL_GPL(cbe_spu_info);
+
static int __init init_spu_base(void)
{
int i, ret = 0;
- for (i = 0; i < MAX_NUMNODES; i++)
- INIT_LIST_HEAD(&spu_list[i]);
+ for (i = 0; i < MAX_NUMNODES; i++) {
+ INIT_LIST_HEAD(&cbe_spu_info[i].spus);
+ INIT_LIST_HEAD(&cbe_spu_info[i].free_spus);
+ }
if (!spu_management_ops)
goto out;
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 12c09665404d..6d0ab72cc70e 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -231,6 +231,9 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
spu->number, spu->node);
spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
+ if (ctx->flags & SPU_CREATE_NOSCHED)
+ atomic_inc(&cbe_spu_info[spu->node].reserved_spus);
+
ctx->stats.slb_flt_base = spu->stats.slb_flt;
ctx->stats.class2_intr_base = spu->stats.class2_intr;
@@ -267,6 +270,8 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
spu->pid, spu->number, spu->node);
spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
+ if (spu->ctx->flags & SPU_CREATE_NOSCHED)
+ atomic_dec(&cbe_spu_info[spu->node].reserved_spus);
spu_switch_notify(spu, NULL);
spu_unmap_mappings(ctx);
spu_save(&ctx->csa, spu);