linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch 00/12] GRU - GRU Driver Updates
@ 2009-06-08 17:16 steiner
  2009-06-08 17:16 ` [Patch 01/12] GRU - fix cache coherency issues with instruction retry steiner
                   ` (11 more replies)
  0 siblings, 12 replies; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel


This patchset is a collection of patches to the GRU driver.
All changes are internal to the driver and have no effect
on the core kernel or interfaces to/from the core kernel.

Thiese patches must be applied on TOP of the patches that
already exist in the -mm tree.

Patches were built against linux-next of 6/8/2009.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 01/12] GRU - fix cache coherency issues with instruction retry
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
@ 2009-06-08 17:16 ` steiner
  2009-06-08 17:16 ` [Patch 02/12] GRU - add user request to explicitly unload a gru context steiner
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_flush_cbe_at_exception --]
[-- Type: text/plain, Size: 4164 bytes --]

From: Jack Steiner <steiner@sgi.com>

Fix 2 problems related to GRU instruction failures. Cache coherency
is not maintained for CBEs except when loading or unloading contexts.
When reading a CBE to extract error information, the CBE must first be flushed
from the cache.

The function that reads kerrnel CBEs was reading the wrong CBE.


Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/grufault.c     |    3 ++-
 drivers/misc/sgi-gru/grufile.c      |    2 +-
 drivers/misc/sgi-gru/grukservices.c |   12 ++++++++++--
 drivers/misc/sgi-gru/grutables.h    |    1 +
 4 files changed, 14 insertions(+), 4 deletions(-)

Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2009-04-29 13:40:17.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2009-04-29 13:40:36.000000000 -0500
@@ -618,7 +618,7 @@ int gru_get_exception_detail(unsigned lo
 	} else if (gts->ts_gru) {
 		cbrnum = thread_cbr_number(gts, ucbnum);
 		cbe = get_cbe_by_index(gts->ts_gru, cbrnum);
-		prefetchw(cbe);/* Harmless on hardware, required for emulator */
+		gru_flush_cache(cbe);	/* CBE not coherent */
 		excdet.opc = cbe->opccpy;
 		excdet.exopc = cbe->exopccpy;
 		excdet.ecause = cbe->ecause;
@@ -626,6 +626,7 @@ int gru_get_exception_detail(unsigned lo
 		excdet.exceptdet1 = cbe->idef3upd;
 		excdet.cbrstate = cbe->cbrstate;
 		excdet.cbrexecstatus = cbe->cbrexecstatus;
+		gru_flush_cache(cbe);
 		ret = 0;
 	} else {
 		ret = -EAGAIN;
Index: linux/drivers/misc/sgi-gru/grufile.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufile.c	2009-04-29 13:40:16.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grufile.c	2009-04-29 13:41:09.000000000 -0500
@@ -46,6 +46,7 @@
 
 struct gru_blade_state *gru_base[GRU_MAX_BLADES] __read_mostly;
 unsigned long gru_start_paddr __read_mostly;
+void *gru_start_vaddr __read_mostly;
 unsigned long gru_end_paddr __read_mostly;
 unsigned int gru_max_gids __read_mostly;
 struct gru_stats_s gru_stats;
@@ -376,7 +377,6 @@ static int __init gru_init(void)
 {
 	int ret, irq, chip;
 	char id[10];
-	void *gru_start_vaddr;
 
 	if (!is_uv_system())
 		return 0;
Index: linux/drivers/misc/sgi-gru/grukservices.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grukservices.c	2009-04-29 13:40:17.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grukservices.c	2009-04-29 13:40:36.000000000 -0500
@@ -98,6 +98,9 @@
 #define ASYNC_HAN_TO_BID(h)	((h) - 1)
 #define ASYNC_BID_TO_HAN(b)	((b) + 1)
 #define ASYNC_HAN_TO_BS(h)	gru_base[ASYNC_HAN_TO_BID(h)]
+#define KCB_TO_GID(cb)		((cb - gru_start_vaddr) /		\
+					(GRU_SIZE * GRU_CHIPLETS_PER_BLADE))
+#define KCB_TO_BS(cb)		gru_base[KCB_TO_GID(cb)]
 
 #define GRU_NUM_KERNEL_CBR	1
 #define GRU_NUM_KERNEL_DSR_BYTES 256
@@ -354,14 +357,19 @@ int gru_get_cb_exception_detail(void *cb
 		struct control_block_extended_exc_detail *excdet)
 {
 	struct gru_control_block_extended *cbe;
+	struct gru_blade_state *bs;
+	int cbrnum;
 
-	cbe = get_cbe(GRUBASE(cb), get_cb_number(cb));
-	prefetchw(cbe);	/* Harmless on hardware, required for emulator */
+	bs = KCB_TO_BS(cb);
+	cbrnum = thread_cbr_number(bs->bs_kgts, get_cb_number(cb));
+	cbe = get_cbe(GRUBASE(cb), cbrnum);
+	gru_flush_cache(cbe);	/* CBE not coherent */
 	excdet->opc = cbe->opccpy;
 	excdet->exopc = cbe->exopccpy;
 	excdet->ecause = cbe->ecause;
 	excdet->exceptdet0 = cbe->idef1upd;
 	excdet->exceptdet1 = cbe->idef3upd;
+	gru_flush_cache(cbe);
 	return 0;
 }
 
Index: linux/drivers/misc/sgi-gru/grutables.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grutables.h	2009-04-29 13:40:17.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grutables.h	2009-04-29 13:40:36.000000000 -0500
@@ -153,6 +153,7 @@
 extern struct gru_stats_s gru_stats;
 extern struct gru_blade_state *gru_base[];
 extern unsigned long gru_start_paddr, gru_end_paddr;
+extern void *gru_start_vaddr;
 extern unsigned int gru_max_gids;
 
 #define GRU_MAX_BLADES		MAX_NUMNODES


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 02/12] GRU - add user request to explicitly unload a gru context
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
  2009-06-08 17:16 ` [Patch 01/12] GRU - fix cache coherency issues with instruction retry steiner
@ 2009-06-08 17:16 ` steiner
  2009-06-08 23:05   ` Andrew Morton
  2009-06-08 17:16 ` [Patch 03/12] GRU - fix automatic retry of gru instruction failures steiner
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_free_kernel_gts --]
[-- Type: text/plain, Size: 4973 bytes --]

From: Jack Steiner <steiner@sgi.com>

Add user function to explicitly unload GRU kernel contexts from the
GRU. Only contexts that are not in-use will be unloaded.

This function is primarily for testing. It is not expected that this will
be used in normal production systems.


Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/grufile.c      |   10 ++----
 drivers/misc/sgi-gru/grukservices.c |   55 ++++++++++++++++++++++--------------
 drivers/misc/sgi-gru/grutables.h    |    4 +-
 3 files changed, 41 insertions(+), 28 deletions(-)

Index: linux/drivers/misc/sgi-gru/grufile.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufile.c	2009-04-29 13:41:09.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grufile.c	2009-04-29 13:42:22.000000000 -0500
@@ -287,7 +287,6 @@ static void gru_init_chiplet(struct gru_
 	gru_dbg(grudev, "bid %d, nid %d, gid %d, vaddr %p (0x%lx)\n",
 		bid, nid, gru->gs_gid, gru->gs_gru_base_vaddr,
 		gru->gs_gru_base_paddr);
-	gru_kservices_init(gru);
 }
 
 static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr)
@@ -314,6 +313,7 @@ static int gru_init_tables(unsigned long
 		memset(gru_base[bid], 0, sizeof(struct gru_blade_state));
 		gru_base[bid]->bs_lru_gru = &gru_base[bid]->bs_grus[0];
 		spin_lock_init(&gru_base[bid]->bs_lock);
+		init_rwsem(&gru_base[bid]->bs_kgts_sema);
 
 		dsrbytes = 0;
 		cbrs = 0;
@@ -426,6 +426,7 @@ static int __init gru_init(void)
 		printk(KERN_ERR "%s: init tables failed\n", GRU_DRIVER_ID_STR);
 		goto exit3;
 	}
+	gru_kservices_init();
 
 	printk(KERN_INFO "%s: v%s\n", GRU_DRIVER_ID_STR,
 	       GRU_DRIVER_VERSION_STR);
@@ -444,7 +445,7 @@ exit1:
 
 static void __exit gru_exit(void)
 {
-	int i, bid, gid;
+	int i, bid;
 	int order = get_order(sizeof(struct gru_state) *
 			      GRU_CHIPLETS_PER_BLADE);
 
@@ -453,10 +454,7 @@ static void __exit gru_exit(void)
 
 	for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++)
 		free_irq(IRQ_GRU + i, NULL);
-
-	foreach_gid(gid)
-		gru_kservices_exit(GID_TO_GRU(gid));
-
+	gru_kservices_exit();
 	for (bid = 0; bid < GRU_MAX_BLADES; bid++)
 		free_pages((unsigned long)gru_base[bid], order);
 
Index: linux/drivers/misc/sgi-gru/grukservices.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grukservices.c	2009-04-29 13:40:36.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grukservices.c	2009-04-29 13:41:24.000000000 -0500
@@ -188,6 +188,34 @@ static void gru_load_kernel_context(stru
 }
 
 /*
+ * Free all kernel contexts that are not currently in use.
+ *   Returns 0 if all freed, else number of inuse context.
+ */
+static int gru_free_kernel_contexts(void)
+{
+	struct gru_blade_state *bs;
+	struct gru_thread_state *kgts;
+	int bid, ret = 0;
+
+	for (bid = 0; bid < GRU_MAX_BLADES; bid++) {
+		bs = gru_base[bid];
+		if (!bs)
+			continue;
+		if (down_write_trylock(&bs->bs_kgts_sema)) {
+			kgts = bs->bs_kgts;
+			if (kgts && kgts->ts_gru)
+				gru_unload_context(kgts, 0);
+			kfree(kgts);
+			bs->bs_kgts = NULL;
+			up_write(&bs->bs_kgts_sema);
+		} else {
+			ret++;
+		}
+	}
+	return ret;
+}
+
+/*
  * Lock & load the kernel context for the specified blade.
  */
 static struct gru_blade_state *gru_lock_kernel_context(int blade_id)
@@ -1009,35 +1037,22 @@ int gru_ktest(unsigned long arg)
 	case 2:
 		ret = quicktest2(arg);
 		break;
+	case 99:
+		ret = gru_free_kernel_contexts();
+		break;
 	}
 	return ret;
 
 }
 
-int gru_kservices_init(struct gru_state *gru)
+int gru_kservices_init(void)
 {
-	struct gru_blade_state *bs;
-
-	bs = gru->gs_blade;
-	if (gru != &bs->bs_grus[0])
-		return 0;
-
-	init_rwsem(&bs->bs_kgts_sema);
 	return 0;
 }
 
-void gru_kservices_exit(struct gru_state *gru)
+void gru_kservices_exit(void)
 {
-	struct gru_blade_state *bs;
-	struct gru_thread_state *kgts;
-
-	bs = gru->gs_blade;
-	if (gru != &bs->bs_grus[0])
-		return;
-
-	kgts = bs->bs_kgts;
-	if (kgts && kgts->ts_gru)
-		gru_unload_context(kgts, 0);
-	kfree(kgts);
+	if (gru_free_kernel_contexts())
+		BUG();
 }
 
Index: linux/drivers/misc/sgi-gru/grutables.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grutables.h	2009-04-29 13:40:36.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grutables.h	2009-04-29 13:43:22.000000000 -0500
@@ -638,8 +638,8 @@ extern void gru_unload_context(struct gr
 extern int gru_update_cch(struct gru_thread_state *gts, int force_unload);
 extern void gts_drop(struct gru_thread_state *gts);
 extern void gru_tgh_flush_init(struct gru_state *gru);
-extern int gru_kservices_init(struct gru_state *gru);
-extern void gru_kservices_exit(struct gru_state *gru);
+extern int gru_kservices_init(void);
+extern void gru_kservices_exit(void);
 extern int gru_dump_chiplet_request(unsigned long arg);
 extern irqreturn_t gru_intr(int irq, void *dev_id);
 extern int gru_handle_user_call_os(unsigned long address);


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 03/12] GRU - fix automatic retry of gru instruction failures
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
  2009-06-08 17:16 ` [Patch 01/12] GRU - fix cache coherency issues with instruction retry steiner
  2009-06-08 17:16 ` [Patch 02/12] GRU - add user request to explicitly unload a gru context steiner
@ 2009-06-08 17:16 ` steiner
  2009-06-08 17:16 ` [Patch 04/12] GRU - collect per-context user statistics steiner
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_exception_retry --]
[-- Type: text/plain, Size: 1070 bytes --]

From: Jack Steiner <steiner@sgi.com>

Fix bug in automatic retry of GRU instruction failures.
CBR substatus (message queue failure) was being checked
incorrectly.


Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/grukservices.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

Index: linux/drivers/misc/sgi-gru/grukservices.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grukservices.c	2009-04-29 13:41:24.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grukservices.c	2009-04-29 13:43:32.000000000 -0500
@@ -436,11 +436,10 @@ static int gru_retry_exception(void *cb)
 	int retry = EXCEPTION_RETRY_LIMIT;
 
 	while (1)  {
-		if (gru_get_cb_message_queue_substatus(cb))
-			break;
 		if (gru_wait_idle_or_exception(gen) == CBS_IDLE)
 			return CBS_IDLE;
-
+		if (gru_get_cb_message_queue_substatus(cb))
+			return CBS_EXCEPTION;
 		gru_get_cb_exception_detail(cb, &excdet);
 		if ((excdet.ecause & ~EXCEPTION_RETRY_BITS) ||
 				(excdet.cbrexecstatus & CBR_EXS_ABORT_OCC))


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 04/12] GRU - collect per-context user statistics
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
                   ` (2 preceding siblings ...)
  2009-06-08 17:16 ` [Patch 03/12] GRU - fix automatic retry of gru instruction failures steiner
@ 2009-06-08 17:16 ` steiner
  2009-06-08 23:07   ` Andrew Morton
  2009-06-08 17:16 ` [Patch 05/12] GRU - delete user request for fetching chiplet status steiner
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_statistics --]
[-- Type: text/plain, Size: 5498 bytes --]

From: Jack Steiner <steiner@sgi.com>

Collect GRU statistics for each user GRU context. Statistics are
kept for TLB misses & content resource contention. Add user
request for retrieving the statistics.

Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/grufault.c  |   27 +++++++++++++++++++++++++++
 drivers/misc/sgi-gru/grufile.c   |    3 +++
 drivers/misc/sgi-gru/grulib.h    |   18 ++++++++++++++++++
 drivers/misc/sgi-gru/grumain.c   |    1 +
 drivers/misc/sgi-gru/grutables.h |    3 +++
 5 files changed, 52 insertions(+)

Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2009-04-29 13:40:36.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2009-04-29 13:43:42.000000000 -0500
@@ -502,6 +502,7 @@ irqreturn_t gru_intr(int irq, void *dev_
 		 */
 		if (!gts->ts_force_cch_reload &&
 					down_read_trylock(&gts->ts_mm->mmap_sem)) {
+			gts->ustats.fmm_tlbdropin++;
 			gru_try_dropin(gts, tfh, NULL);
 			up_read(&gts->ts_mm->mmap_sem);
 		} else {
@@ -520,6 +521,7 @@ static int gru_user_dropin(struct gru_th
 	struct gru_mm_struct *gms = gts->ts_gms;
 	int ret;
 
+	gts->ustats.upm_tlbdropin++;
 	while (1) {
 		wait_event(gms->ms_wait_queue,
 			   atomic_read(&gms->ms_range_active) == 0);
@@ -723,6 +725,31 @@ int gru_user_flush_tlb(unsigned long arg
 }
 
 /*
+ * Fetch GSEG statisticss
+ */
+long gru_get_gseg_statistics(unsigned long arg)
+{
+	struct gru_thread_state *gts;
+	struct gru_get_gseg_statistics_req req;
+
+	if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
+		return -EFAULT;
+
+	gts = gru_find_lock_gts(req.gseg);
+	if (gts) {
+		memcpy(&req.stats, &gts->ustats, sizeof(gts->ustats));
+		gru_unlock_gts(gts);
+	} else {
+		memset(&req.stats, 0, sizeof(gts->ustats));
+	}
+
+	if (copy_to_user((void __user *)arg, &req, sizeof(req)))
+		return -EFAULT;
+
+	return 0;
+}
+
+/*
  * Register the current task as the user of the GSEG slice.
  * Needed for TLB fault interrupt targeting.
  */
Index: linux/drivers/misc/sgi-gru/grufile.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufile.c	2009-04-29 13:42:22.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grufile.c	2009-04-29 13:43:42.000000000 -0500
@@ -251,6 +251,9 @@ static long gru_file_unlocked_ioctl(stru
 	case GRU_USER_CALL_OS:
 		err = gru_handle_user_call_os(arg);
 		break;
+	case GRU_GET_GSEG_STATISTICS:
+		err = gru_get_gseg_statistics(arg);
+		break;
 	case GRU_KTEST:
 		err = gru_ktest(arg);
 		break;
Index: linux/drivers/misc/sgi-gru/grulib.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grulib.h	2009-04-29 13:40:16.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grulib.h	2009-04-29 13:43:42.000000000 -0500
@@ -50,6 +50,9 @@
 /* For dumpping GRU chiplet state */
 #define GRU_DUMP_CHIPLET_STATE		_IOWR(GRU_IOCTL_NUM, 11, void *)
 
+/* For getting gseg statistics */
+#define GRU_GET_GSEG_STATISTICS		_IOWR(GRU_IOCTL_NUM, 12, void *)
+
 /* For user TLB flushing (primarily for tests) */
 #define GRU_USER_FLUSH_TLB		_IOWR(GRU_IOCTL_NUM, 50, void *)
 
@@ -61,6 +64,21 @@
 
 #define CONTEXT_WINDOW_BYTES(th)        (GRU_GSEG_PAGESIZE * (th))
 #define THREAD_POINTER(p, th)		(p + GRU_GSEG_PAGESIZE * (th))
+#define GSEG_START(cb)			((void *)((unsigned long)(cb) & ~(GRU_GSEG_PAGESIZE - 1)))
+
+/*
+ * Statictics kept on a per-GTS basis.
+ */
+struct gts_statistics {
+	unsigned long	fmm_tlbdropin;
+	unsigned long	upm_tlbdropin;
+	unsigned long	context_stolen;
+};
+
+struct gru_get_gseg_statistics_req {
+	unsigned long		gseg;
+	struct gts_statistics	stats;
+};
 
 /*
  * Structure used to pass TLB flush parameters to the driver
Index: linux/drivers/misc/sgi-gru/grumain.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grumain.c	2009-04-29 13:40:15.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grumain.c	2009-04-29 13:43:42.000000000 -0500
@@ -744,6 +744,7 @@ void gru_steal_context(struct gru_thread
 	spin_unlock(&blade->bs_lock);
 
 	if (ngts) {
+		gts->ustats.context_stolen++;
 		ngts->ts_steal_jiffies = jiffies;
 		gru_unload_context(ngts, is_kernel_context(ngts) ? 0 : 1);
 		gts_stolen(ngts, blade);
Index: linux/drivers/misc/sgi-gru/grutables.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grutables.h	2009-04-29 13:43:22.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grutables.h	2009-04-29 13:44:08.000000000 -0500
@@ -148,6 +148,7 @@
 #include <linux/wait.h>
 #include <linux/mmu_notifier.h>
 #include "gru.h"
+#include "grulib.h"
 #include "gruhandles.h"
 
 extern struct gru_stats_s gru_stats;
@@ -388,6 +389,7 @@ struct gru_thread_state {
 							  allocated CB */
 	int			ts_data_valid;	/* Indicates if ts_gdata has
 						   valid data */
+	struct gts_statistics	ustats;		/* User statistics */
 	unsigned long		ts_gdata[0];	/* save area for GRU data (CB,
 						   DS, CBE) */
 };
@@ -641,6 +643,7 @@ extern void gru_tgh_flush_init(struct gr
 extern int gru_kservices_init(void);
 extern void gru_kservices_exit(void);
 extern int gru_dump_chiplet_request(unsigned long arg);
+extern long gru_get_gseg_statistics(unsigned long arg);
 extern irqreturn_t gru_intr(int irq, void *dev_id);
 extern int gru_handle_user_call_os(unsigned long address);
 extern int gru_user_flush_tlb(unsigned long arg);


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 05/12] GRU - delete user request for fetching chiplet status
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
                   ` (3 preceding siblings ...)
  2009-06-08 17:16 ` [Patch 04/12] GRU - collect per-context user statistics steiner
@ 2009-06-08 17:16 ` steiner
  2009-06-08 17:16 ` [Patch 06/12] GRU - cleanup gru inline functions steiner
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_delete_chiplet_status --]
[-- Type: text/plain, Size: 2774 bytes --]

From: Jack Steiner <steiner@sgi.com>

Delete the user request for fetching the status of a GRU chiplet.
This request has been made obsolete by other changes. Note: this
is not a change to a user API - there are no compatibility
issues with this change.

Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/grufile.c |   38 --------------------------------------
 drivers/misc/sgi-gru/grulib.h  |    3 ---
 2 files changed, 41 deletions(-)

Index: linux/drivers/misc/sgi-gru/grufile.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufile.c	2009-04-29 13:43:42.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grufile.c	2009-04-29 13:44:16.000000000 -0500
@@ -183,41 +183,6 @@ static long gru_get_config_info(unsigned
 }
 
 /*
- * Get GRU chiplet status
- */
-static long gru_get_chiplet_status(unsigned long arg)
-{
-	struct gru_state *gru;
-	struct gru_chiplet_info info;
-
-	if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
-		return -EFAULT;
-
-	if (info.node == -1)
-		info.node = numa_node_id();
-	if (info.node >= num_possible_nodes() ||
-			info.chiplet >= GRU_CHIPLETS_PER_HUB ||
-			info.node < 0 || info.chiplet < 0)
-		return -EINVAL;
-
-	info.blade = uv_node_to_blade_id(info.node);
-	gru = get_gru(info.blade, info.chiplet);
-
-	info.total_dsr_bytes = GRU_NUM_DSR_BYTES;
-	info.total_cbr = GRU_NUM_CB;
-	info.total_user_dsr_bytes = GRU_NUM_DSR_BYTES -
-		gru->gs_reserved_dsr_bytes;
-	info.total_user_cbr = GRU_NUM_CB - gru->gs_reserved_cbrs;
-	info.free_user_dsr_bytes = hweight64(gru->gs_dsr_map) *
-			GRU_DSR_AU_BYTES;
-	info.free_user_cbr = hweight64(gru->gs_cbr_map) * GRU_CBR_AU_SIZE;
-
-	if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-		return -EFAULT;
-	return 0;
-}
-
-/*
  * gru_file_unlocked_ioctl
  *
  * Called to update file attributes via IOCTL calls.
@@ -242,9 +207,6 @@ static long gru_file_unlocked_ioctl(stru
 	case GRU_USER_UNLOAD_CONTEXT:
 		err = gru_user_unload_context(arg);
 		break;
-	case GRU_GET_CHIPLET_STATUS:
-		err = gru_get_chiplet_status(arg);
-		break;
 	case GRU_USER_FLUSH_TLB:
 		err = gru_user_flush_tlb(arg);
 		break;
Index: linux/drivers/misc/sgi-gru/grulib.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grulib.h	2009-04-29 13:43:42.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grulib.h	2009-04-29 13:44:16.000000000 -0500
@@ -44,9 +44,6 @@
 /* For user unload context */
 #define GRU_USER_UNLOAD_CONTEXT		_IOWR(GRU_IOCTL_NUM, 9, void *)
 
-/* For fetching GRU chiplet status */
-#define GRU_GET_CHIPLET_STATUS		_IOWR(GRU_IOCTL_NUM, 10, void *)
-
 /* For dumpping GRU chiplet state */
 #define GRU_DUMP_CHIPLET_STATE		_IOWR(GRU_IOCTL_NUM, 11, void *)
 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 06/12] GRU - cleanup gru inline functions
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
                   ` (4 preceding siblings ...)
  2009-06-08 17:16 ` [Patch 05/12] GRU - delete user request for fetching chiplet status steiner
@ 2009-06-08 17:16 ` steiner
  2009-06-08 17:16 ` [Patch 07/12] GRU - generic infrastructure for context options steiner
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_instruction_wait --]
[-- Type: text/plain, Size: 2359 bytes --]

From: Jack Steiner <steiner@sgi.com>

Cleanup of GRU inline functions to eliminate unnecessary
inline code. Update function descriptions.

Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/gru_instructions.h |   33 +++++++++++++++-----------------
 1 file changed, 16 insertions(+), 17 deletions(-)

Index: linux/drivers/misc/sgi-gru/gru_instructions.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gru_instructions.h	2009-04-29 13:40:17.000000000 -0500
+++ linux/drivers/misc/sgi-gru/gru_instructions.h	2009-04-29 13:44:25.000000000 -0500
@@ -623,9 +623,11 @@ static inline int gru_get_cb_substatus(v
 	return cbs->isubstatus;
 }
 
-/* Check the status of a CB. If the CB is in UPM mode, call the
- * OS to handle the UPM status.
- * Returns the CB status field value (0 for normal completion)
+/*
+ * User interface to check an instruction status. UPM and exceptions
+ * are handled automatically. However, this function does NOT wait
+ * for an active instruction to complete.
+ *
  */
 static inline int gru_check_status(void *cb)
 {
@@ -633,34 +635,31 @@ static inline int gru_check_status(void 
 	int ret;
 
 	ret = cbs->istatus;
-	if (ret == CBS_CALL_OS)
+	if (ret != CBS_ACTIVE)
 		ret = gru_check_status_proc(cb);
 	return ret;
 }
 
-/* Wait for CB to complete.
- * Returns the CB status field value (0 for normal completion)
+/*
+ * User interface (via inline function) to wait for an instruction
+ * to complete. Completion status (IDLE or EXCEPTION is returned
+ * to the user. Exception due to hardware errors are automatically
+ * retried before returning an exception.
+ *
  */
 static inline int gru_wait(void *cb)
 {
-	struct gru_control_block_status *cbs = (void *)cb;
-	int ret = cbs->istatus;
-
-	if (ret != CBS_IDLE)
-		ret = gru_wait_proc(cb);
-	return ret;
+	return gru_wait_proc(cb);
 }
 
-/* Wait for CB to complete. Aborts program if error. (Note: error does NOT
+/*
+ * Wait for CB to complete. Aborts program if error. (Note: error does NOT
  * mean TLB mis - only fatal errors such as memory parity error or user
  * bugs will cause termination.
  */
 static inline void gru_wait_abort(void *cb)
 {
-	struct gru_control_block_status *cbs = (void *)cb;
-
-	if (cbs->istatus != CBS_IDLE)
-		gru_wait_abort_proc(cb);
+	gru_wait_abort_proc(cb);
 }
 
 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 07/12] GRU - generic infrastructure for context options
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
                   ` (5 preceding siblings ...)
  2009-06-08 17:16 ` [Patch 06/12] GRU - cleanup gru inline functions steiner
@ 2009-06-08 17:16 ` steiner
  2009-06-08 17:16 ` [Patch 08/12] GRU - add user request to specify gru slice steiner
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_context_options --]
[-- Type: text/plain, Size: 5215 bytes --]

From: Jack Steiner <steiner@sgi.com>

Change the user GRU request for specifying the "task_slice"
option to use a generic infrastructure that can be expanded in the
future to include additional context options. No new capabilities
are added with this patch.


Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/grufault.c  |   24 ++++++++++++++++++------
 drivers/misc/sgi-gru/grufile.c   |    4 ++--
 drivers/misc/sgi-gru/grulib.h    |   14 ++++++++++++--
 drivers/misc/sgi-gru/gruprocfs.c |    2 +-
 drivers/misc/sgi-gru/grutables.h |    4 ++--
 5 files changed, 35 insertions(+), 13 deletions(-)

Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2009-05-12 16:43:19.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2009-05-12 16:43:36.000000000 -0500
@@ -753,18 +753,30 @@ long gru_get_gseg_statistics(unsigned lo
  * Register the current task as the user of the GSEG slice.
  * Needed for TLB fault interrupt targeting.
  */
-int gru_set_task_slice(long address)
+int gru_set_context_option(unsigned long arg)
 {
 	struct gru_thread_state *gts;
+	struct gru_set_context_option_req req;
+	int ret = 0;
 
-	STAT(set_task_slice);
-	gru_dbg(grudev, "address 0x%lx\n", address);
-	gts = gru_alloc_locked_gts(address);
+	STAT(set_context_option);
+	if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
+		return -EFAULT;
+	gru_dbg(grudev, "op %d, gseg 0x%lx, value1 0x%lx\n", req.op, req.gseg, req.val1);
+
+	gts = gru_alloc_locked_gts(req.gseg);
 	if (!gts)
 		return -EINVAL;
 
-	gts->ts_tgid_owner = current->tgid;
+	switch (req.op) {
+	case sco_gseg_owner:
+ 		/* Register the current task as the GSEG owner */
+		gts->ts_tgid_owner = current->tgid;
+		break;
+	default:
+		ret = -EINVAL;
+	}
 	gru_unlock_gts(gts);
 
-	return 0;
+	return ret;
 }
Index: linux/drivers/misc/sgi-gru/grufile.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufile.c	2009-05-12 16:43:19.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grufile.c	2009-05-12 16:43:36.000000000 -0500
@@ -198,8 +198,8 @@ static long gru_file_unlocked_ioctl(stru
 	case GRU_CREATE_CONTEXT:
 		err = gru_create_new_context(arg);
 		break;
-	case GRU_SET_TASK_SLICE:
-		err = gru_set_task_slice(arg);
+	case GRU_SET_CONTEXT_OPTION:
+		err = gru_set_context_option(arg);
 		break;
 	case GRU_USER_GET_EXCEPTION_DETAIL:
 		err = gru_get_exception_detail(arg);
Index: linux/drivers/misc/sgi-gru/grulib.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grulib.h	2009-05-12 16:43:19.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grulib.h	2009-05-12 16:43:36.000000000 -0500
@@ -32,8 +32,8 @@
 /* Set Number of Request Blocks */
 #define GRU_CREATE_CONTEXT		_IOWR(GRU_IOCTL_NUM, 1, void *)
 
-/* Register task as using the slice */
-#define GRU_SET_TASK_SLICE		_IOWR(GRU_IOCTL_NUM, 5, void *)
+/*  Set Context Options */
+#define GRU_SET_CONTEXT_OPTION		_IOWR(GRU_IOCTL_NUM, 4, void *)
 
 /* Fetch exception detail */
 #define GRU_USER_GET_EXCEPTION_DETAIL	_IOWR(GRU_IOCTL_NUM, 6, void *)
@@ -96,6 +96,16 @@ struct gru_unload_context_req {
 };
 
 /*
+ * Structure used to set context options
+ */
+enum {sco_gseg_owner};
+struct gru_set_context_option_req {
+	unsigned long	gseg;
+	int		op;
+	unsigned long	val1;
+};
+
+/*
  * Structure used to pass TLB flush parameters to the driver
  */
 struct gru_flush_tlb_req {
Index: linux/drivers/misc/sgi-gru/gruprocfs.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gruprocfs.c	2009-05-12 16:43:19.000000000 -0500
+++ linux/drivers/misc/sgi-gru/gruprocfs.c	2009-05-12 16:43:36.000000000 -0500
@@ -73,7 +73,7 @@ static int statistics_show(struct seq_fi
 	printstat(s, user_flush_tlb);
 	printstat(s, user_unload_context);
 	printstat(s, user_exception);
-	printstat(s, set_task_slice);
+	printstat(s, set_context_option);
 	printstat(s, migrate_check);
 	printstat(s, migrated_retarget);
 	printstat(s, migrated_unload);
Index: linux/drivers/misc/sgi-gru/grutables.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grutables.h	2009-05-12 16:43:19.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grutables.h	2009-05-12 16:43:36.000000000 -0500
@@ -198,7 +198,7 @@ struct gru_stats_s {
 	atomic_long_t user_flush_tlb;
 	atomic_long_t user_unload_context;
 	atomic_long_t user_exception;
-	atomic_long_t set_task_slice;
+	atomic_long_t set_context_option;
 	atomic_long_t migrate_check;
 	atomic_long_t migrated_retarget;
 	atomic_long_t migrated_unload;
@@ -649,7 +649,7 @@ extern int gru_handle_user_call_os(unsig
 extern int gru_user_flush_tlb(unsigned long arg);
 extern int gru_user_unload_context(unsigned long arg);
 extern int gru_get_exception_detail(unsigned long arg);
-extern int gru_set_task_slice(long address);
+extern int gru_set_context_option(unsigned long address);
 extern int gru_cpu_fault_map_id(void);
 extern struct vm_area_struct *gru_find_vma(unsigned long vaddr);
 extern void gru_flush_all_tlb(struct gru_state *gru);


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 08/12] GRU - add user request to specify gru slice
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
                   ` (6 preceding siblings ...)
  2009-06-08 17:16 ` [Patch 07/12] GRU - generic infrastructure for context options steiner
@ 2009-06-08 17:16 ` steiner
  2009-06-08 17:16 ` [Patch 09/12] GRU - fix potential use-after-free when purging GRU tlbs steiner
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_request_slice --]
[-- Type: text/plain, Size: 3102 bytes --]

From: Jack Steiner <steiner@sgi.com>

Add a user request to specify the gru instruction slice
parameter for user contexts.


Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/grufault.c  |    4 ++++
 drivers/misc/sgi-gru/grulib.h    |    2 +-
 drivers/misc/sgi-gru/grumain.c   |    7 +++++++
 drivers/misc/sgi-gru/grutables.h |    1 +
 4 files changed, 13 insertions(+), 1 deletion(-)

Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2009-05-12 16:43:36.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2009-05-12 16:48:53.000000000 -0500
@@ -773,6 +773,10 @@ int gru_set_context_option(unsigned long
  		/* Register the current task as the GSEG owner */
 		gts->ts_tgid_owner = current->tgid;
 		break;
+	case sco_cch_req_slice:
+ 		/* Set the CCH slice option */
+		gts->ts_cch_req_slice = req.val1 & 3;
+		break;
 	default:
 		ret = -EINVAL;
 	}
Index: linux/drivers/misc/sgi-gru/grulib.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grulib.h	2009-05-12 16:43:36.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grulib.h	2009-05-12 16:48:53.000000000 -0500
@@ -98,7 +98,7 @@ struct gru_unload_context_req {
 /*
  * Structure used to set context options
  */
-enum {sco_gseg_owner};
+enum {sco_gseg_owner, sco_cch_req_slice};
 struct gru_set_context_option_req {
 	unsigned long	gseg;
 	int		op;
Index: linux/drivers/misc/sgi-gru/grumain.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grumain.c	2009-05-12 16:43:19.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grumain.c	2009-05-12 16:48:53.000000000 -0500
@@ -321,6 +321,7 @@ struct gru_thread_state *gru_alloc_gts(s
 	gts->ts_tsid = tsid;
 	gts->ts_ctxnum = NULLCTX;
 	gts->ts_tlb_int_select = -1;
+	gts->ts_cch_req_slice = -1;
 	gts->ts_sizeavail = GRU_SIZEAVAIL(PAGE_SHIFT);
 	if (vma) {
 		gts->ts_mm = current->mm;
@@ -566,6 +567,12 @@ void gru_load_context(struct gru_thread_
 		gts->ts_tlb_int_select = gru_cpu_fault_map_id();
 		cch->tlb_int_select = gts->ts_tlb_int_select;
 	}
+	if (gts->ts_cch_req_slice >= 0) {
+		cch->req_slice_set_enable = 1;
+		cch->req_slice = gts->ts_cch_req_slice;
+	} else {
+		cch->req_slice_set_enable =0;
+	}
 	cch->tfm_done_bit_enable = 0;
 	cch->dsr_allocation_map = gts->ts_dsr_map;
 	cch->cbr_allocation_map = gts->ts_cbr_map;
Index: linux/drivers/misc/sgi-gru/grutables.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grutables.h	2009-05-12 16:43:36.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grutables.h	2009-05-12 16:48:53.000000000 -0500
@@ -380,6 +380,7 @@ struct gru_thread_state {
 						   required for contest */
 	unsigned char		ts_cbr_au_count;/* Number of CBR resources
 						   required for contest */
+	char			ts_cch_req_slice;/* CCH packet slice */
 	char			ts_blade;	/* If >= 0, migrate context if
 						   ref from diferent blade */
 	char			ts_force_cch_reload;


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 09/12] GRU - fix potential use-after-free when purging GRU tlbs
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
                   ` (7 preceding siblings ...)
  2009-06-08 17:16 ` [Patch 08/12] GRU - add user request to specify gru slice steiner
@ 2009-06-08 17:16 ` steiner
  2009-06-08 17:16 ` [Patch 10/12] GRU - fixes to grudump utility steiner
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_flush_tlb_fix --]
[-- Type: text/plain, Size: 1354 bytes --]

From: Jack Steiner <steiner@sgi.com>

Fix potential SGI GRU bug that could cause a use-after-free. If one
thread in a task is flushing the GRU and another thread destroys the GRU context,
there is the potential to access a table after it has been freed.

Copy the gms pointer to a local variable before unlocking the gts table.
Note that no refcnt is needed for the gms - the reference is held indirectly
by the task's mm_struct.

Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/grufault.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2009-06-05 15:33:05.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2009-06-05 15:33:05.000000000 -0500
@@ -706,6 +706,7 @@ int gru_user_flush_tlb(unsigned long arg
 {
 	struct gru_thread_state *gts;
 	struct gru_flush_tlb_req req;
+	struct gru_mm_struct *gms;
 
 	STAT(user_flush_tlb);
 	if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
@@ -718,8 +719,9 @@ int gru_user_flush_tlb(unsigned long arg
 	if (!gts)
 		return -EINVAL;
 
-	gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.len);
+	gms = gts->ts_gms;
 	gru_unlock_gts(gts);
+	gru_flush_tlb_range(gms, req.vaddr, req.len);
 
 	return 0;
 }


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 10/12] GRU - fixes to grudump utility
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
                   ` (8 preceding siblings ...)
  2009-06-08 17:16 ` [Patch 09/12] GRU - fix potential use-after-free when purging GRU tlbs steiner
@ 2009-06-08 17:16 ` steiner
  2009-06-08 17:16 ` [Patch 11/12] GRU - remove references to the obsolete global status handle steiner
  2009-06-08 17:17 ` [Patch 12/12] GRU - copyright fixes steiner
  11 siblings, 0 replies; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_grudump_fixes --]
[-- Type: text/plain, Size: 2506 bytes --]

From: Jack Steiner <steiner@sgi.com>

Minor fixes to the SGI GRU grudump facility:
	- fix address where user data is written
	- add gru number to data passed to user
	- indicate if context is locked


Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/grukdump.c |    8 ++++++--
 drivers/misc/sgi-gru/grulib.h   |    4 ++--
 2 files changed, 8 insertions(+), 4 deletions(-)

Index: linux/drivers/misc/sgi-gru/grukdump.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grukdump.c	2009-06-05 15:16:57.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grukdump.c	2009-06-05 15:20:36.000000000 -0500
@@ -26,7 +26,7 @@
 
 static int gru_user_copy_handle(void __user **dp, void *s)
 {
-	if (copy_to_user(dp, s, GRU_HANDLE_BYTES))
+	if (copy_to_user(*dp, s, GRU_HANDLE_BYTES))
 		return -1;
 	*dp += GRU_HANDLE_BYTES;
 	return 0;
@@ -109,7 +109,7 @@ static int gru_dump_context(struct gru_s
 {
 	struct gru_dump_context_header hdr;
 	struct gru_dump_context_header __user *uhdr = ubuf;
-	struct gru_context_configuration_handle *cch;
+	struct gru_context_configuration_handle *cch, *ubufcch;
 	struct gru_thread_state *gts;
 	int try, cch_locked, cbrcnt = 0, dsrcnt = 0, bytes = 0, ret = 0;
 	void *grubase;
@@ -125,8 +125,11 @@ static int gru_dump_context(struct gru_s
 	}
 
 	ubuf += sizeof(hdr);
+	ubufcch = ubuf;
 	if (gru_user_copy_handle(&ubuf, cch))
 		goto fail;
+	if (cch_locked)
+		ubufcch->delresp = 0;
 	bytes = sizeof(hdr) + GRU_CACHE_LINE_BYTES;
 
 	if (cch_locked || !lock_cch) {
@@ -155,6 +158,7 @@ static int gru_dump_context(struct gru_s
 		return ret;
 
 	hdr.magic = GRU_DUMP_MAGIC;
+	hdr.gid = gru->gs_gid;
 	hdr.ctxnum = ctxnum;
 	hdr.cbrcnt = cbrcnt;
 	hdr.dsrcnt = dsrcnt;
Index: linux/drivers/misc/sgi-gru/grulib.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grulib.h	2009-06-05 15:16:57.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grulib.h	2009-06-05 15:20:46.000000000 -0500
@@ -120,7 +120,7 @@ struct gru_flush_tlb_req {
 enum {dcs_pid, dcs_gid};
 struct gru_dump_chiplet_state_req {
 	unsigned int	op;
-	int		gid;
+	unsigned int	gid;
 	int		ctxnum;
 	char		data_opt;
 	char		lock_cch;
@@ -134,7 +134,7 @@ struct gru_dump_chiplet_state_req {
 #define GRU_DUMP_MAGIC	0x3474ab6c
 struct gru_dump_context_header {
 	unsigned int	magic;
-	unsigned char	gid;
+	unsigned int	gid;
 	unsigned char	ctxnum;
 	unsigned char	cbrcnt;
 	unsigned char	dsrcnt;


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 11/12] GRU - remove references to the obsolete global status handle
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
                   ` (9 preceding siblings ...)
  2009-06-08 17:16 ` [Patch 10/12] GRU - fixes to grudump utility steiner
@ 2009-06-08 17:16 ` steiner
  2009-06-08 17:17 ` [Patch 12/12] GRU - copyright fixes steiner
  11 siblings, 0 replies; 17+ messages in thread
From: steiner @ 2009-06-08 17:16 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_delete_gsh --]
[-- Type: text/plain, Size: 1122 bytes --]

From: Jack Steiner <steiner@sgi.com>

Delete references to the SGI GRU GSH hardware resources.
These GRU resources have been deleted from the hardware.
(These resources have never benn used, anyway).

Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/gruhandles.h |    2 --
 1 file changed, 2 deletions(-)

Index: linux/drivers/misc/sgi-gru/gruhandles.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gruhandles.h	2009-06-06 17:26:53.000000000 -0500
+++ linux/drivers/misc/sgi-gru/gruhandles.h	2009-06-07 11:32:57.000000000 -0500
@@ -39,7 +39,6 @@
 #define GRU_NUM_CBE		128
 #define GRU_NUM_TFH		128
 #define GRU_NUM_CCH		16
-#define GRU_NUM_GSH		1
 
 /* Maximum resource counts that can be reserved by user programs */
 #define GRU_NUM_USER_CBR	GRU_NUM_CBE
@@ -56,7 +55,6 @@
 #define GRU_CBE_BASE		(GRU_MCS_BASE + 0x10000)
 #define GRU_TFH_BASE		(GRU_MCS_BASE + 0x18000)
 #define GRU_CCH_BASE		(GRU_MCS_BASE + 0x20000)
-#define GRU_GSH_BASE		(GRU_MCS_BASE + 0x30000)
 
 /* User gseg constants */
 #define GRU_GSEG_STRIDE		(4 * 1024 * 1024)


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Patch 12/12] GRU - copyright fixes
  2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
                   ` (10 preceding siblings ...)
  2009-06-08 17:16 ` [Patch 11/12] GRU - remove references to the obsolete global status handle steiner
@ 2009-06-08 17:17 ` steiner
  11 siblings, 0 replies; 17+ messages in thread
From: steiner @ 2009-06-08 17:17 UTC (permalink / raw)
  To: akpm, linux-kernel

[-- Attachment #1: uv_gru_copyright_fixes --]
[-- Type: text/plain, Size: 3217 bytes --]

From: Jack Steiner <steiner@sgi.com>

Fix the copyright statements in a couple of GRU files. No
functional changes are being made.

Signed-off-by: Jack Steiner <steiner@sgi.com>

---
 drivers/misc/sgi-gru/grukdump.c |   18 ++++++++++++++----
 drivers/misc/sgi-gru/grumain.c  |   18 ++++++++++++++----
 2 files changed, 28 insertions(+), 8 deletions(-)

Index: linux/drivers/misc/sgi-gru/grukdump.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grukdump.c	2009-06-08 10:28:25.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grukdump.c	2009-06-08 10:28:59.000000000 -0500
@@ -3,11 +3,21 @@
  *
  *            Dump GRU State
  *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
+ *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
  *
- * Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
 #include <linux/kernel.h>
Index: linux/drivers/misc/sgi-gru/grumain.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grumain.c	2009-06-08 10:28:25.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grumain.c	2009-06-08 10:29:11.000000000 -0500
@@ -3,11 +3,21 @@
  *
  *            DRIVER TABLE MANAGER + GRU CONTEXT LOAD/UNLOAD
  *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
+ *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
  *
- * Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
 #include <linux/kernel.h>


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Patch 02/12] GRU - add user request to explicitly unload a gru context
  2009-06-08 17:16 ` [Patch 02/12] GRU - add user request to explicitly unload a gru context steiner
@ 2009-06-08 23:05   ` Andrew Morton
  2009-06-12 17:51     ` Jack Steiner
  0 siblings, 1 reply; 17+ messages in thread
From: Andrew Morton @ 2009-06-08 23:05 UTC (permalink / raw)
  To: steiner; +Cc: linux-kernel

On Mon, 08 Jun 2009 12:16:50 -0500
steiner@sgi.com wrote:

>  /*
> + * Free all kernel contexts that are not currently in use.
> + *   Returns 0 if all freed, else number of inuse context.
> + */
> +static int gru_free_kernel_contexts(void)
> +{
> +	struct gru_blade_state *bs;
> +	struct gru_thread_state *kgts;
> +	int bid, ret = 0;
> +
> +	for (bid = 0; bid < GRU_MAX_BLADES; bid++) {
> +		bs = gru_base[bid];
> +		if (!bs)
> +			continue;
> +		if (down_write_trylock(&bs->bs_kgts_sema)) {

trylocks are always lame - they add a rarely-executed code path where
bugs can lurk.  They're often an admission that the locking is screwed
up.

I don't know if the latter is true here, but it would be helpful to add
a comment explaining what's going on, and why this unusual and
troublesome locking primitive is being used.

> +			kgts = bs->bs_kgts;
> +			if (kgts && kgts->ts_gru)
> +				gru_unload_context(kgts, 0);
> +			kfree(kgts);
> +			bs->bs_kgts = NULL;
> +			up_write(&bs->bs_kgts_sema);

nit: the kfree() can be moved outside the locked region.

> +		} else {
> +			ret++;
> +		}
> +	}
> +	return ret;
> +}

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Patch 04/12] GRU - collect per-context user statistics
  2009-06-08 17:16 ` [Patch 04/12] GRU - collect per-context user statistics steiner
@ 2009-06-08 23:07   ` Andrew Morton
  2009-06-10  3:08     ` Jack Steiner
  0 siblings, 1 reply; 17+ messages in thread
From: Andrew Morton @ 2009-06-08 23:07 UTC (permalink / raw)
  To: steiner; +Cc: linux-kernel

On Mon, 08 Jun 2009 12:16:52 -0500
steiner@sgi.com wrote:

>  /*
> + * Fetch GSEG statisticss
> + */
> +long gru_get_gseg_statistics(unsigned long arg)
> +{
> +	struct gru_thread_state *gts;
> +	struct gru_get_gseg_statistics_req req;
> +
> +	if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
> +		return -EFAULT;
> +
> +	gts = gru_find_lock_gts(req.gseg);
> +	if (gts) {
> +		memcpy(&req.stats, &gts->ustats, sizeof(gts->ustats));
> +		gru_unlock_gts(gts);
> +	} else {
> +		memset(&req.stats, 0, sizeof(gts->ustats));
> +	}
> +
> +	if (copy_to_user((void __user *)arg, &req, sizeof(req)))
> +		return -EFAULT;
> +
> +	return 0;
> +}

So..  what's happening in the super-secret undocumented gts==NULL path?

It _looks_ like userspace passed into this ioctl a handle for something
which the kernel doesn't know about.  If so, shouldn't we return
-EINVAL or something?  


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Patch 04/12] GRU - collect per-context user statistics
  2009-06-08 23:07   ` Andrew Morton
@ 2009-06-10  3:08     ` Jack Steiner
  0 siblings, 0 replies; 17+ messages in thread
From: Jack Steiner @ 2009-06-10  3:08 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

On Mon, Jun 08, 2009 at 04:07:40PM -0700, Andrew Morton wrote:
> On Mon, 08 Jun 2009 12:16:52 -0500
> steiner@sgi.com wrote:
> 
> >  /*
> > + * Fetch GSEG statisticss
> > + */
> > +long gru_get_gseg_statistics(unsigned long arg)
> > +{
> > +	struct gru_thread_state *gts;
> > +	struct gru_get_gseg_statistics_req req;
> > +
> > +	if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
> > +		return -EFAULT;
> > +
> > +	gts = gru_find_lock_gts(req.gseg);
> > +	if (gts) {
> > +		memcpy(&req.stats, &gts->ustats, sizeof(gts->ustats));
> > +		gru_unlock_gts(gts);
> > +	} else {
> > +		memset(&req.stats, 0, sizeof(gts->ustats));
> > +	}
> > +
> > +	if (copy_to_user((void __user *)arg, &req, sizeof(req)))
> > +		return -EFAULT;
> > +
> > +	return 0;
> > +}
> 
> So..  what's happening in the super-secret undocumented gts==NULL path?
> 
> It _looks_ like userspace passed into this ioctl a handle for something
> which the kernel doesn't know about.  If so, shouldn't we return
> -EINVAL or something?  

It makes sense but certainly needs a comment (will send later) to
explain the logic.

User space creates arrays of GRU contexts for threaded processes. The
library code that prints statistics scans the array & generates
statistic for each context. If an context was never referenced, there is
no GTS & all statistics are implicitly zero.

This could have been handled other ways but it is rare than an entry was
never referenced. A return of -EINVAL current is considered a bug, ie.
address is not a valid GRU address.


--- jack

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Patch 02/12] GRU - add user request to explicitly unload a gru context
  2009-06-08 23:05   ` Andrew Morton
@ 2009-06-12 17:51     ` Jack Steiner
  0 siblings, 0 replies; 17+ messages in thread
From: Jack Steiner @ 2009-06-12 17:51 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

On Mon, Jun 08, 2009 at 04:05:25PM -0700, Andrew Morton wrote:
> On Mon, 08 Jun 2009 12:16:50 -0500
> steiner@sgi.com wrote:
> 
> >  /*
> > + * Free all kernel contexts that are not currently in use.
> > + *   Returns 0 if all freed, else number of inuse context.
> > + */
> > +static int gru_free_kernel_contexts(void)
> > +{
> > +	struct gru_blade_state *bs;
> > +	struct gru_thread_state *kgts;
> > +	int bid, ret = 0;
> > +
> > +	for (bid = 0; bid < GRU_MAX_BLADES; bid++) {
> > +		bs = gru_base[bid];
> > +		if (!bs)
> > +			continue;
> > +		if (down_write_trylock(&bs->bs_kgts_sema)) {
> 
> trylocks are always lame - they add a rarely-executed code path where
> bugs can lurk.  They're often an admission that the locking is screwed
> up.
> 
> I don't know if the latter is true here, but it would be helpful to add
> a comment explaining what's going on, and why this unusual and
> troublesome locking primitive is being used.

Agree that trylock is frequently a crappy way to avoid a real fix
for potential ABBA deadlocks. However, in this case no potential locking inversion
is being avoided. The code in gru_free_kernel_contexts() is simply trying
to free any non-busy contexts where "busy" is defined as locked.
Contexts that are "busy" are simply skipped.

Also, this is a path that is rarely used. It exists primarily for stress testing.

I'll add comments to code to make this clearer.



> 
> > +			kgts = bs->bs_kgts;
> > +			if (kgts && kgts->ts_gru)
> > +				gru_unload_context(kgts, 0);
> > +			kfree(kgts);
> > +			bs->bs_kgts = NULL;
> > +			up_write(&bs->bs_kgts_sema);
> 
> nit: the kfree() can be moved outside the locked region.

Yuck. Done...


> 
> > +		} else {
> > +			ret++;
> > +		}
> > +	}
> > +	return ret;
> > +}

--- jack

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2009-06-12 17:51 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-08 17:16 [Patch 00/12] GRU - GRU Driver Updates steiner
2009-06-08 17:16 ` [Patch 01/12] GRU - fix cache coherency issues with instruction retry steiner
2009-06-08 17:16 ` [Patch 02/12] GRU - add user request to explicitly unload a gru context steiner
2009-06-08 23:05   ` Andrew Morton
2009-06-12 17:51     ` Jack Steiner
2009-06-08 17:16 ` [Patch 03/12] GRU - fix automatic retry of gru instruction failures steiner
2009-06-08 17:16 ` [Patch 04/12] GRU - collect per-context user statistics steiner
2009-06-08 23:07   ` Andrew Morton
2009-06-10  3:08     ` Jack Steiner
2009-06-08 17:16 ` [Patch 05/12] GRU - delete user request for fetching chiplet status steiner
2009-06-08 17:16 ` [Patch 06/12] GRU - cleanup gru inline functions steiner
2009-06-08 17:16 ` [Patch 07/12] GRU - generic infrastructure for context options steiner
2009-06-08 17:16 ` [Patch 08/12] GRU - add user request to specify gru slice steiner
2009-06-08 17:16 ` [Patch 09/12] GRU - fix potential use-after-free when purging GRU tlbs steiner
2009-06-08 17:16 ` [Patch 10/12] GRU - fixes to grudump utility steiner
2009-06-08 17:16 ` [Patch 11/12] GRU - remove references to the obsolete global status handle steiner
2009-06-08 17:17 ` [Patch 12/12] GRU - copyright fixes steiner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).