[Cbe-oss-dev] [PATCH 1/6] cell: add per BE structure with info about its SPUs

Andre Detsch adetsch at br.ibm.com
Mon Feb 12 12:10:42 EST 2007


From: Andre Detsch <adetsch at br.ibm.com>
Subject: cell: add per BE structure with info about its SPUs

Addition of a spufs-global "be_info" array. Each entry contains information
about one BE node, namelly:
* list of available spus (both free and busy spus are in this list);
* list of free spus (substituting the static spu_list from spu_base.c)
* number of spus;
* number of isolated 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 non-isolated spus (n_spus - isolated_spus).
However having this more general structure can be useful for other 
functionalities, concentrating per-be statistics / data.

Decrementation of isolated SPUs number is still missing.

Signed-off-by: Andre Detsch <adetsch at br.ibm.com>

Index: linux-2.6.20/arch/powerpc/platforms/cell/spu_base.c
===================================================================
--- linux-2.6.20.orig/arch/powerpc/platforms/cell/spu_base.c
+++ linux-2.6.20/arch/powerpc/platforms/cell/spu_base.c
@@ -327,7 +327,6 @@ static void spu_free_irqs(struct spu *sp
 		free_irq(spu->irqs[2], spu);
 }
 
-static struct list_head spu_list[MAX_NUMNODES];
 static LIST_HEAD(spu_full_list);
 static DEFINE_MUTEX(spu_mutex);
 
@@ -370,8 +369,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(&be_spu_info[node].free_spus)) {
+		spu = list_entry(be_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);
 		spu_init_channels(spu);
@@ -399,7 +399,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, &be_spu_info[spu->node].free_spus);
 	mutex_unlock(&spu_mutex);
 }
 EXPORT_SYMBOL_GPL(spu_free);
@@ -617,7 +617,9 @@ static int __init create_spu(void *data)
 		goto out_free_irqs;
 
 	mutex_lock(&spu_mutex);
-	list_add(&spu->list, &spu_list[spu->node]);
+	list_add(&spu->list, &be_spu_info[spu->node].free_spus);
+	list_add(&spu->available_list, &be_spu_info[spu->node].available_spus);
+	be_spu_info[spu->node].n_spus++;
 	list_add(&spu->full_list, &spu_full_list);
 	mutex_unlock(&spu_mutex);
 
@@ -636,6 +638,7 @@ out:
 static void destroy_spu(struct spu *spu)
 {
 	list_del_init(&spu->list);
+	list_del_init(&spu->available_list);
 	list_del_init(&spu->full_list);
 
 	spu_destroy_sysdev(spu);
@@ -651,7 +654,8 @@ static void cleanup_spu_base(void)
 
 	mutex_lock(&spu_mutex);
 	for (node = 0; node < MAX_NUMNODES; node++) {
-		list_for_each_entry_safe(spu, tmp, &spu_list[node], list)
+		list_for_each_entry_safe(spu, tmp, &be_spu_info[node].free_spus,
+					 				list)
 			destroy_spu(spu);
 	}
 	mutex_unlock(&spu_mutex);
@@ -659,6 +663,9 @@ static void cleanup_spu_base(void)
 }
 module_exit(cleanup_spu_base);
 
+struct be_spu_info be_spu_info[MAX_NUMNODES];
+EXPORT_SYMBOL_GPL(be_spu_info);
+
 static int __init init_spu_base(void)
 {
 	int i, ret;
@@ -671,11 +678,12 @@ static int __init init_spu_base(void)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < MAX_NUMNODES; i++)
-		INIT_LIST_HEAD(&spu_list[i]);
+	for (i = 0; i < MAX_NUMNODES; i++) {
+		INIT_LIST_HEAD(&be_spu_info[i].available_spus);
+		INIT_LIST_HEAD(&be_spu_info[i].free_spus);
+	}
 
 	ret = spu_enumerate_spus(create_spu);
-
 	if (ret) {
 		printk(KERN_WARNING "%s: Error initializing spus\n",
 			__FUNCTION__);
Index: linux-2.6.20/include/asm-powerpc/spu.h
===================================================================
--- linux-2.6.20.orig/include/asm-powerpc/spu.h
+++ linux-2.6.20/include/asm-powerpc/spu.h
@@ -113,6 +113,7 @@ struct spu {
 	struct spu_problem __iomem *problem;
 	struct spu_priv2 __iomem *priv2;
 	struct list_head list;
+	struct list_head available_list;
 	struct list_head sched_list;
 	struct list_head full_list;
 	int number;
@@ -145,6 +146,15 @@ struct spu {
 	struct sys_device sysdev;
 };
 
+struct be_spu_info {
+	struct list_head available_spus;
+	struct list_head free_spus;
+	int n_spus;
+	atomic_t isolated_spus;
+};
+
+extern struct be_spu_info be_spu_info[];
+
 struct spu *spu_alloc(void);
 struct spu *spu_alloc_node(int node);
 void spu_free(struct spu *spu);
Index: linux-2.6.20/arch/powerpc/platforms/cell/spufs/context.c
===================================================================
--- linux-2.6.20.orig/arch/powerpc/platforms/cell/spufs/context.c
+++ linux-2.6.20/arch/powerpc/platforms/cell/spufs/context.c
@@ -143,6 +143,8 @@ int spu_acquire_exclusive(struct spu_con
 		 */
 		spu_unmap_mappings(ctx);
 	}
+	BUG_ON(!ctx->spu);
+	atomic_inc(&be_spu_info[ctx->spu->node].isolated_spus);
 
 	return 0;
 

--
Andre Detsch



More information about the cbe-oss-dev mailing list