[Patch 11/25] GRU - interrupt fix for processors without core 0

Previous thread: [PATCH] mips: irq: add stackoverflow detection by Adam Jiang on Thursday, August 26, 2010 - 6:19 am. (3 messages)

Next thread: [PATCH 1/2] MCE, AMD: Limit MCE decoding to current families for now by Borislav Petkov on Thursday, August 26, 2010 - 7:06 am. (1 message)
From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

This patch set contains a collection of patches to the SGI UV GRU
driver. These patches fix various bugs found in the testing
of the driver on real hardware.

No changes are made to non-UV files.


--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Update the GRU instruction macros to match what is actually
implemented in initial silicon.

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


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

Index: linux/drivers/misc/sgi-gru/gru_instructions.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gru_instructions.h	2010-06-09 08:11:31.528038315 -0500
+++ linux/drivers/misc/sgi-gru/gru_instructions.h	2010-06-09 08:11:38.907960603 -0500
@@ -217,8 +217,6 @@ struct gru_instruction {
 #define EOP_ERR_XOR	0x03 /* Logical XOR with memory */
 #define EOP_ERR_ADD	0x04 /* Add value to memory */
 #define EOP_ERR_CSWAP	0x08 /* Compare with operand2, write operand1 if match*/
-#define EOP_ERR_EPOLL	0x09 /* Poll for equality */
-#define EOP_ERR_NPOLL	0x0a /* Poll for inequality */
 
 /* GAMXR - SGI Arithmetic unit */
 #define EOP_XR_CSWAP	0x0b /* Masked compare exchange */

--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Add VM_NONLINEAR to the vm_flags used to map the GRU.

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

---
 drivers/misc/sgi-gru/grufile.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux/drivers/misc/sgi-gru/grufile.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufile.c	2010-06-09 08:11:39.751457793 -0500
+++ linux/drivers/misc/sgi-gru/grufile.c	2010-06-09 08:11:40.740099769 -0500
@@ -110,7 +110,7 @@ static int gru_file_mmap(struct file *fi
 
 	vma->vm_flags |=
 	    (VM_IO | VM_DONTCOPY | VM_LOCKED | VM_DONTEXPAND | VM_PFNMAP |
-			VM_RESERVED);
+			VM_RESERVED | VM_NONLINEAR);
 	vma->vm_page_prot = PAGE_SHARED;
 	vma->vm_ops = &gru_vm_ops;
 

--

From: steiner
Date: Thursday, August 26, 2010 - 6:20 am

From: Jack Steiner <steiner@sgi.com>

Update the CBRSTATE definitions to match what was actually
implemented in hardware.

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

---
 drivers/misc/sgi-gru/gruhandles.h |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

Index: linux/drivers/misc/sgi-gru/gruhandles.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gruhandles.h	2010-07-19 10:25:57.000000000 -0500
+++ linux/drivers/misc/sgi-gru/gruhandles.h	2010-07-19 13:03:39.982295167 -0500
@@ -478,15 +478,19 @@ enum gru_cbr_state {
 	CBRSTATE_INACTIVE,
 	CBRSTATE_IDLE,
 	CBRSTATE_PE_CHECK,
+	CBRSTATE_DSR_PRE,
 	CBRSTATE_QUEUED,
+	CBRSTATE_ISSUED,
 	CBRSTATE_WAIT_RESPONSE,
-	CBRSTATE_INTERRUPTED,
-	CBRSTATE_INTERRUPTED_MISS_FMM,
+	CBRSTATE_DSR_POST,
 	CBRSTATE_BUSY_INTERRUPT_MISS_FMM,
+	CBRSTATE_INTERRUPTED_MISS_FMM,
+	CBRSTATE_BUSY_INTERRUPT_MISS_UPM,
 	CBRSTATE_INTERRUPTED_MISS_UPM,
-	CBRSTATE_BUSY_INTERRUPTED_MISS_UPM,
-	CBRSTATE_REQUEST_ISSUE,
 	CBRSTATE_BUSY_INTERRUPT,
+	CBRSTATE_INTERRUPTED,
+	CBRSTATE_BCPY_CHECK,
+	CBRSTATE_WAIT_DONE,
 };
 
 /* CBE cbrexecstatus bits  - defined in gru_instructions.h*/

--

From: steiner
Date: Thursday, August 26, 2010 - 6:20 am

From: Jack Steiner <steiner@sgi.com>

Change the name of GRU_GSEG_PAGESIZE to GRU_MIN_GSEG_PAGESIZE
to more accurately reflect it's use. This is in preparation for
allocating contexts using hugepages.

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

---
 drivers/misc/sgi-gru/gru.h              |   10 ++--------
 drivers/misc/sgi-gru/gru_instructions.h |    2 +-
 2 files changed, 3 insertions(+), 9 deletions(-)

Index: linux/drivers/misc/sgi-gru/gru.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gru.h	2010-06-09 08:11:48.856038221 -0500
+++ linux/drivers/misc/sgi-gru/gru.h	2010-06-09 08:11:51.328084904 -0500
@@ -28,15 +28,9 @@
 #define GRU_DS_BASE			0x20000
 
 /*
- * Size used to map GRU GSeg
+ * Minimum page size used to map a GRU context
  */
-#if defined(CONFIG_IA64)
-#define GRU_GSEG_PAGESIZE	(256 * 1024UL)
-#elif defined(CONFIG_X86_64)
-#define GRU_GSEG_PAGESIZE	(256 * 1024UL)		/* ZZZ 2MB ??? */
-#else
-#error "Unsupported architecture"
-#endif
+#define GRU_MIN_GSEG_PAGESIZE	(256 * 1024UL)
 
 /*
  * Statictics kept for each context.
Index: linux/drivers/misc/sgi-gru/gru_instructions.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gru_instructions.h	2010-06-09 08:11:50.264036100 -0500
+++ linux/drivers/misc/sgi-gru/gru_instructions.h	2010-06-09 08:11:51.332083779 -0500
@@ -687,6 +687,6 @@ static inline void *gru_get_data_pointer
  */
 static inline int gru_get_tri(void *vaddr)
 {
-	return ((unsigned long)vaddr & (GRU_GSEG_PAGESIZE - 1)) - GRU_DS_BASE;
+	return ((unsigned long)vaddr & (GRU_MIN_GSEG_PAGESIZE - 1)) - GRU_DS_BASE;
 }
 #endif		/* __GRU_INSTRUCTIONS_H__ */

--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Add support for dumpping the GRU GSH state. This provides addition debugging information
for GRU failures.

Add missing cache flush instructions. For performance reasons, the CBE does not
alway maintain cache-coherency.

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

---
 drivers/misc/sgi-gru/grukdump.c |   17 ++++++++++++++++-
 drivers/misc/sgi-gru/grulib.h   |    2 ++
 2 files changed, 18 insertions(+), 1 deletion(-)

Index: linux/drivers/misc/sgi-gru/grukdump.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grukdump.c	2010-07-19 10:23:08.926244572 -0500
+++ linux/drivers/misc/sgi-gru/grukdump.c	2010-07-19 13:10:56.766719840 -0500
@@ -54,10 +54,16 @@ static int gru_dump_context_data(void *g
 	cb = gseg + GRU_CB_BASE;
 	cbe = grubase + GRU_CBE_BASE;
 	tfh = grubase + GRU_TFH_BASE;
+	sync_core();
+	gru_flush_cache(cbe);
 
 	for_each_cbr_in_allocation_map(i, &cch->cbr_allocation_map, scr) {
-		if (flush_cbrs)
+		if (flush_cbrs) {
 			gru_flush_cache(cb);
+			gru_flush_cache(tfh + i * GRU_HANDLE_STRIDE);
+		}
+		gru_flush_cache(cbe + i * GRU_HANDLE_STRIDE);
+		sync_core();
 		if (gru_user_copy_handle(&ubuf, cb))
 			goto fail;
 		if (gru_user_copy_handle(&ubuf, tfh + i * GRU_HANDLE_STRIDE))
@@ -130,6 +136,7 @@ static int gru_dump_context(struct gru_s
 	memset(&hdr, 0, sizeof(hdr));
 	grubase = gru->gs_gru_base_vaddr;
 	cch = get_cch(grubase, ctxnum);
+	gru_flush_cache(cch);
 	for (try = 0; try < CCH_LOCK_ATTEMPTS; try++) {
 		cch_locked =  trylock_cch_handle(cch);
 		if (cch_locked)
@@ -184,6 +191,12 @@ fail:
 	unlock_cch_handle(cch);
 	return -EFAULT;
 }
+static void dump_gsh_state(struct gru_state *gru,
+			   struct gru_dump_chiplet_state_req *req)
+{
+	memset(&req->gsh_cb_state, 0, sizeof(req->gsh_cb_state));
+	memset(&req->gsh_cch_state, 0, sizeof(req->gsh_cch_state));
+}
 
 int gru_dump_chiplet_request(unsigned long arg)
 {
@@ -214,6 +227,8 @@ int ...
From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Delete unused structure that was left over from debugging.

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

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

Index: linux/drivers/misc/sgi-gru/gru.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gru.h	2010-06-09 08:11:45.375993599 -0500
+++ linux/drivers/misc/sgi-gru/gru.h	2010-06-09 08:11:48.856038221 -0500
@@ -39,21 +39,6 @@
 #endif
 
 /*
- * Structure for obtaining GRU resource information
- */
-struct gru_chiplet_info {
-	int	node;
-	int	chiplet;
-	int	blade;
-	int	total_dsr_bytes;
-	int	total_cbr;
-	int	total_user_dsr_bytes;
-	int	total_user_cbr;
-	int	free_user_dsr_bytes;
-	int	free_user_cbr;
-};
-
-/*
  * Statictics kept for each context.
  */
 struct gru_gseg_statistics {

--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Misc clean:
	- update debug messages
	- update stale comments in the code


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

---
 drivers/misc/sgi-gru/grufault.c     |    1 -
 drivers/misc/sgi-gru/grukservices.h |    3 +--
 drivers/misc/sgi-gru/grulib.h       |    1 -
 drivers/misc/sgi-gru/grumain.c      |   26 +++++++++++++-------------
 drivers/misc/sgi-gru/grutlbpurge.c  |    1 -
 5 files changed, 14 insertions(+), 18 deletions(-)

Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2010-06-09 08:11:45.803958078 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2010-06-09 08:11:47.573040296 -0500
@@ -209,7 +209,6 @@ static int non_atomic_pte_lookup(struct
  *
  * Convert a user virtual address to a physical address
  * Only supports Intel large pages (2MB only) on x86_64.
- *	ZZZ - hugepage support is incomplete
  *
  * NOTE: mmap_sem is already held on entry to this function. This
  * guarantees existence of the page tables.
Index: linux/drivers/misc/sgi-gru/grukservices.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grukservices.h	2010-06-09 08:11:30.008045922 -0500
+++ linux/drivers/misc/sgi-gru/grukservices.h	2010-06-09 08:11:47.573040296 -0500
@@ -36,9 +36,8 @@
  * 	- multiple senders
  *	- cross partition message
  *
- * Missing features ZZZ:
+ * Missing features:
  * 	- user options for dealing with timeouts, queue full, etc.
- * 	- gru_create_message_queue() needs interrupt vector info
  */
 
 struct gru_message_queue_desc {
Index: linux/drivers/misc/sgi-gru/grulib.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grulib.h	2010-06-09 08:11:45.407956625 -0500
+++ linux/drivers/misc/sgi-gru/grulib.h	2010-06-09 08:11:47.593081003 -0500
@@ -25,7 +25,6 @@
 
 /*
  * Maximum number of GRU segments that ...
From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

If the GRU malfunctions, print a message instead of panicing the system.
This simplifies debugging since some of the debug tools can be used on
a live system. Flush the cache on instruction timeouts in case the
malfunction is related to a coherency issue (never seen this but I'm paranoid).

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

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

Index: linux/drivers/misc/sgi-gru/gruhandles.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gruhandles.c	2010-06-09 08:11:43.724081727 -0500
+++ linux/drivers/misc/sgi-gru/gruhandles.c	2010-06-09 08:11:46.697237522 -0500
@@ -71,7 +71,7 @@ static void report_instruction_timeout(v
 	else if (TYPE_IS(TFH, goff))
 		id = "TFH";
 
-	panic(KERN_ALERT "GRU %p (%s) is malfunctioning\n", h, id);
+	printk(KERN_ALERT "GRU:%d %p (%s) is malfunctioning\n", smp_processor_id(), h, id);
 }
 
 static int wait_instruction_complete(void *h, enum mcs_op opc)
@@ -85,6 +85,7 @@ static int wait_instruction_complete(voi
 		if (status != CCHSTATUS_ACTIVE)
 			break;
 		if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time)) {
+			gru_flush_cache(h);
 			report_instruction_timeout(h);
 			start_time = get_cycles();
 		}

--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Currently, the GRU driver processes TLB misses by sending an interrupt to the cpu.
The TLB is updated from the interrupt handler.

Some workloads have unused cpus. This patch (still experimental) uses idle
cpus to poll for TLB misses. When a miss occurs, the TLB is updated directly
w/o having to send interrupts to the cpu.

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

---
 drivers/misc/sgi-gru/gru.h       |    1 
 drivers/misc/sgi-gru/grufault.c  |   50 ++++++++++++++++++++++++++++++++++-----
 drivers/misc/sgi-gru/grufile.c   |   20 +++++++++++++++
 drivers/misc/sgi-gru/grulib.h    |   10 +++++++
 drivers/misc/sgi-gru/grumain.c   |   33 +++++++++++--------------
 drivers/misc/sgi-gru/gruprocfs.c |    2 +
 drivers/misc/sgi-gru/grutables.h |    7 ++++-
 7 files changed, 97 insertions(+), 26 deletions(-)

Index: linux/drivers/misc/sgi-gru/gru.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gru.h	2010-07-19 10:23:16.266244020 -0500
+++ linux/drivers/misc/sgi-gru/gru.h	2010-07-19 10:25:40.974376072 -0500
@@ -71,7 +71,6 @@ struct gru_gseg_statistics {
 #define GRU_OPT_MISS_USER_POLL	0x0001	/* User will poll CB for faults */
 #define GRU_OPT_MISS_FMM_INTR	0x0002	/* Send interrupt to cpu to
 					   handle fault */
-#define GRU_OPT_MISS_FMM_POLL	0x0003	/* Use system polling thread */
 #define GRU_OPT_MISS_MASK	0x0003	/* Mask for TLB MISS option */
 
 
Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2010-07-19 10:25:31.203387741 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2010-07-19 10:25:40.978392010 -0500
@@ -156,7 +156,7 @@ static void get_clear_fault_map(struct g
 	unsigned long i, k;
 	struct gru_tlb_fault_map *tfm;
 
-	tfm = get_tfm_for_cpu(gru, gru_cpu_fault_map_id());
+	tfm = get_tfm_for_cpu(gru, gru_cpu_fault_map_id(gru));
 	prefetchw(tfm);		/* Helps on ...
From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

SGI UV driver. Delete some debug code that has outlived it's usefullness.
The code is not part of a supported API

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

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

Index: linux/drivers/misc/sgi-gru/grufile.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufile.c	2010-06-09 08:11:43.712036004 -0500
+++ linux/drivers/misc/sgi-gru/grufile.c	2010-06-09 08:11:44.973081222 -0500
@@ -166,28 +166,6 @@ static int gru_create_new_context(unsign
 	return ret;
 }
 
-/*
- * Get GRU configuration info (temp - for emulator testing)
- */
-static long gru_get_config_info(unsigned long arg)
-{
-	struct gru_config_info info;
-	int nodesperblade;
-
-	if (num_online_nodes() > 1 &&
-			(uv_node_to_blade_id(1) == uv_node_to_blade_id(0)))
-		nodesperblade = 2;
-	else
-		nodesperblade = 1;
-	info.cpus = num_online_cpus();
-	info.nodes = num_online_nodes();
-	info.blades = info.nodes / nodesperblade;
-	info.chiplets = GRU_CHIPLETS_PER_BLADE * info.blades;
-
-	if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-		return -EFAULT;
-	return 0;
-}
 
 /*
  * gru_file_unlocked_ioctl
@@ -226,9 +204,6 @@ static long gru_file_unlocked_ioctl(stru
 	case GRU_KTEST:
 		err = gru_ktest(arg);
 		break;
-	case GRU_GET_CONFIG_INFO:
-		err = gru_get_config_info(arg);
-		break;
 	case GRU_DUMP_CHIPLET_STATE:
 		err = gru_dump_chiplet_request(arg);
 		break;
Index: linux/drivers/misc/sgi-gru/grulib.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grulib.h	2010-06-09 08:11:41.655538228 -0500
+++ linux/drivers/misc/sgi-gru/grulib.h	2010-06-09 08:11:44.973081222 -0500
@@ -53,9 +53,6 @@
 /* For user TLB flushing (primarily for tests) */
 #define GRU_USER_FLUSH_TLB		_IOWR(GRU_IOCTL_NUM, 50, void ...
From: steiner
Date: Thursday, August 26, 2010 - 6:20 am

From: Jack Steiner <steiner@sgi.com>

Update the GRU driver version to 1.0.

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

---
 drivers/misc/sgi-gru/grutables.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux/drivers/misc/sgi-gru/grutables.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grutables.h	2010-06-09 08:11:46.307537752 -0500
+++ linux/drivers/misc/sgi-gru/grutables.h	2010-06-09 08:11:50.819414779 -0500
@@ -165,7 +165,7 @@ extern unsigned int gru_max_gids;
 #define GRU_MAX_GRUS		(GRU_MAX_BLADES * GRU_CHIPLETS_PER_BLADE)
 
 #define GRU_DRIVER_ID_STR	"SGI GRU Device Driver"
-#define GRU_DRIVER_VERSION_STR	"0.85"
+#define GRU_DRIVER_VERSION_STR	"1.00"
 
 #define gru_random()    get_cycles()
 

--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Header file cleanup & reorganization. A variant of the gru_instructions.h
header file is part of the user API. Move items that are NOT part of the
user API from this header file to internal header files.

	- move the CBX definition
	- move the exception retrybits
	- remove the option for mapped/unmapped mode from the
	  instruction macros. Users always run in mapped mode; the
	  kernel always runs in ummapped mode. This option does not
	  need to an option exposed via the macros

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

---
 drivers/misc/sgi-gru/gru_instructions.h |   88 +++++++-------------------------
 drivers/misc/sgi-gru/gruhandles.h       |    1 
 drivers/misc/sgi-gru/grulib.h           |   34 ++++++++++++
 3 files changed, 55 insertions(+), 68 deletions(-)

Index: linux/drivers/misc/sgi-gru/gru_instructions.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gru_instructions.h	2010-06-09 08:11:43.303963161 -0500
+++ linux/drivers/misc/sgi-gru/gru_instructions.h	2010-06-09 08:11:50.264036100 -0500
@@ -71,21 +71,6 @@ extern void gru_wait_abort_proc(void *cb
 #define CBSS_PUT_NACKED			5
 
 /*
- * Structure used to fetch exception detail for CBs that terminate with
- * CBS_EXCEPTION
- */
-struct control_block_extended_exc_detail {
-	unsigned long	cb;
-	int		opc;
-	int		ecause;
-	int		exopc;
-	long		exceptdet0;
-	int		exceptdet1;
-	int		cbrstate;
-	int		cbrexecstatus;
-};
-
-/*
  * Instruction formats
  */
 
@@ -289,19 +274,6 @@ struct gru_instruction {
 #define CBR_EXS_EXCEPTION			(1 << CBR_EXS_EXCEPTION_BIT)
 #define CBR_EXS_CB_INT_PENDING			(1 << CBR_EXS_CB_INT_PENDING_BIT)
 
-/*
- * Exceptions are retried for the following cases. If any OTHER bits are set
- * in ecause, the exception is not retryable.
- */
-#define EXCEPTION_RETRY_BITS (CBE_CAUSE_EXECUTION_HW_ERROR |		\
-			      CBE_CAUSE_TLBHW_ERROR |			\
-			      CBE_CAUSE_RA_REQUEST_TIMEOUT ...
From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Don't allow users to create GRU contexts with 0 CBRs. This does
not make sense & is not allowed by the chiplet. The chiplet will flag this
as an error and fail to allocate the context.

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

---
 drivers/misc/sgi-gru/grufile.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux/drivers/misc/sgi-gru/grufile.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufile.c	2010-06-09 08:11:46.261068458 -0500
+++ linux/drivers/misc/sgi-gru/grufile.c	2010-06-09 08:11:47.151963284 -0500
@@ -175,7 +175,7 @@ static int gru_create_new_context(unsign
 
 	if (req.data_segment_bytes > max_user_dsr_bytes)
 		return -EINVAL;
-	if (req.control_blocks > max_user_cbrs || !req.maximum_thread_count)
+	if (req.control_blocks == 0 || req.control_blocks > max_user_cbrs || !req.maximum_thread_count)
 		return -EINVAL;
 
 	if (!(req.options & GRU_OPT_MISS_MASK))

--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

The GRU vdata structure must have a reference count. 

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

---
 drivers/misc/sgi-gru/grufile.c   |   21 +++++++++++++++++++--
 drivers/misc/sgi-gru/grumain.c   |    1 +
 drivers/misc/sgi-gru/gruprocfs.c |    1 +
 drivers/misc/sgi-gru/grutables.h |    2 ++
 4 files changed, 23 insertions(+), 2 deletions(-)

Index: linux/drivers/misc/sgi-gru/grufile.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufile.c	2010-07-19 10:25:41.002455321 -0500
+++ linux/drivers/misc/sgi-gru/grufile.c	2010-07-19 10:25:49.182243660 -0500
@@ -65,6 +65,19 @@ static struct miscdevice gru_miscdev;
  * Called when unmapping a device mapping. Frees all gru resources
  * and tables belonging to the vma.
  */
+static void gru_vma_open(struct vm_area_struct *vma)
+{
+	struct gru_vma_data *vdata;
+
+	if (!vma->vm_private_data)
+		return;
+	STAT(vdata_open);
+	vdata = vma->vm_private_data;
+	atomic_inc(&vdata->vd_refcnt);
+	gru_dbg(grudev, "vma %p, file %p, vdata %p\n", vma, vma->vm_file,
+				vdata);
+}
+
 static void gru_vma_close(struct vm_area_struct *vma)
 {
 	struct gru_vma_data *vdata;
@@ -75,9 +88,12 @@ static void gru_vma_close(struct vm_area
 		return;
 
 	vdata = vma->vm_private_data;
+	gru_dbg(grudev, "vma %p, file %p, vdata %p, refcnt %d\n", vma, vma->vm_file,
+				vdata, atomic_read(&vdata->vd_refcnt));
+	if (atomic_dec_return(&vdata->vd_refcnt) != 0)
+		return;
+
 	vma->vm_private_data = NULL;
-	gru_dbg(grudev, "vma %p, file %p, vdata %p\n", vma, vma->vm_file,
-				vdata);
 	list_for_each_safe(entry, next, &vdata->vd_head) {
 		gts =
 		    list_entry(entry, struct gru_thread_state, ts_next);
@@ -597,6 +613,7 @@ static struct miscdevice gru_miscdev = {
 };
 
 const struct vm_operations_struct gru_vm_ops = {
+	.open		= gru_vma_open,
 	.close		= gru_vma_close,
 	.fault		= gru_fault,
 };
Index: ...
From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Reorder the servicing of CBR completion interrupts & TLB miss interrupts.
There is a small performance gain to service TLB misses first. Completion
interrupts are rare.


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

---
 drivers/misc/sgi-gru/grufault.c |   24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2010-07-19 10:25:40.978392010 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2010-07-19 10:25:45.626240841 -0500
@@ -7,7 +7,7 @@
  * These misses are reported either via interrupts or user polling of
  * the user CB.
  *
- *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *  Copyright (c) 2008-2010 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
@@ -559,19 +559,10 @@ static irqreturn_t gru_intr(int chiplet,
 		imap.fault_bits[0], imap.fault_bits[1],
 		dmap.fault_bits[0], dmap.fault_bits[1]);
 
-	for_each_cbr_in_tfm(cbrnum, dmap.fault_bits) {
-		STAT(intr_cbr);
-		cmp = gru->gs_async_wq[cbrnum];
-		if (cmp)
-			complete(cmp);
-		gru_dbg(grudev, "gid %d, cbr_done %d, done %d\n",
-			gru->gs_gid, cbrnum, cmp ? cmp->done : -1);
-	}
-
 	for_each_cbr_in_tfm(cbrnum, imap.fault_bits) {
-		STAT(intr_tfh);
 		tfh = get_tfh_by_index(gru, cbrnum);
 		prefetchw(tfh);	/* Helps on hdw, required for emulator */
+		STAT(intr_tfh);
 
 		/*
 		 * When hardware sets a bit in the faultmap, it implicitly
@@ -596,6 +587,8 @@ static irqreturn_t gru_intr(int chiplet,
 			gts->ustats.interrupts++;
 		gts->ustats.fmm_tlbmiss++;
 		multi = 1;
+		if (!gts->ts_mm)
+			continue;
 		if (!gts->ts_force_cch_reload &&
 					down_read_trylock(&gts->ts_mm->mmap_sem)) {
 			gru_try_dropin(gru, gts, ...
From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Add the GRU hub number to the output of the GRU cch_status &
gru_status files (in /proc/sgi_uv/gru).

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


---
 drivers/misc/sgi-gru/gruprocfs.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

Index: linux/drivers/misc/sgi-gru/gruprocfs.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gruprocfs.c	2010-06-09 08:11:42.456084620 -0500
+++ linux/drivers/misc/sgi-gru/gruprocfs.c	2010-06-09 08:11:44.561086699 -0500
@@ -217,18 +217,18 @@ static int gru_seq_show(struct seq_file
 	struct gru_state *gru = GID_TO_GRU(gid);
 
 	if (gid == 0) {
-		seq_printf(file, "#%5s%5s%7s%6s%6s%8s%6s%6s\n", "gid", "nid",
+		seq_printf(file, "#%5s%5s%7s%6s%6s%8s%6s%6s\n", "hub", "gid",
 			   "ctx", "cbr", "dsr", "ctx", "cbr", "dsr");
-		seq_printf(file, "#%5s%5s%7s%6s%6s%8s%6s%6s\n", "", "", "busy",
-			   "busy", "busy", "free", "free", "free");
+		seq_printf(file, "#%5s%5s%7s%6s%6s%8s%6s%6s\n", "", "", "total",
+			   "total", "total", "free", "free", "free");
 	}
 	if (gru) {
 		ctxfree = GRU_NUM_CCH - gru->gs_active_contexts;
 		cbrfree = hweight64(gru->gs_cbr_map) * GRU_CBR_AU_SIZE;
 		dsrfree = hweight64(gru->gs_dsr_map) * GRU_DSR_AU_BYTES;
-		seq_printf(file, " %5d%5d%7ld%6ld%6ld%8ld%6ld%6ld\n",
-			   gru->gs_gid, gru->gs_blade_id, GRU_NUM_CCH - ctxfree,
-			   GRU_NUM_CBE - cbrfree, GRU_NUM_DSR_BYTES - dsrfree,
+		seq_printf(file, " %5d%5d%7d%6d%6d%8ld%6ld%6ld\n",
+			   gru->gs_blade_id, gru->gs_gid,
+			   GRU_NUM_CCH, GRU_NUM_CBE, GRU_NUM_DSR_BYTES,
 			   ctxfree, cbrfree, dsrfree);
 	}
 

--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Rework the way the mmap_sem is used by the GRU driver. The old code
had a few pathes that acquired the lock for write. By changing
the place that the mmu_notifier was allocated/freed, the mmap_sem
is no longer acquired for write. This eliminates some contention on the lock
and improves performance of threaded tests that use the gru.
This also eliminates an endcase where zap_vma_range() could be called without
holding the mmap_sem .

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

---
 drivers/misc/sgi-gru/grufault.c    |   11 ++++---
 drivers/misc/sgi-gru/grufile.c     |   16 +++++++----
 drivers/misc/sgi-gru/gruhandles.c  |    5 ---
 drivers/misc/sgi-gru/grumain.c     |   51 ++++++++++++++++++++++---------------
 drivers/misc/sgi-gru/grutables.h   |   11 +++++++
 drivers/misc/sgi-gru/grutlbpurge.c |   18 +++----------
 6 files changed, 63 insertions(+), 49 deletions(-)

Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2010-07-19 10:23:54.846243726 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2010-07-19 10:25:31.203387741 -0500
@@ -98,7 +98,7 @@ static struct gru_thread_state *gru_allo
 	struct vm_area_struct *vma;
 	struct gru_thread_state *gts = ERR_PTR(-EINVAL);
 
-	down_write(&mm->mmap_sem);
+	down_read(&mm->mmap_sem);
 	vma = gru_find_vma(current->mm, vaddr);
 	if (!vma)
 		goto err;
@@ -107,11 +107,10 @@ static struct gru_thread_state *gru_allo
 	if (IS_ERR(gts))
 		goto err;
 	mutex_lock(&gts->ts_ctxlock);
-	downgrade_write(&mm->mmap_sem);
 	return gts;
 
 err:
-	up_write(&mm->mmap_sem);
+	up_read(&mm->mmap_sem);
 	return gts;
 }
 
@@ -764,18 +763,20 @@ static int gru_unload_all_contexts(void)
 	struct gru_thread_state *gts;
 	struct gru_state *gru;
 	int gid, ctxnum;
+	struct gru_blade_state *blade;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	foreach_gid(gid) {
 		gru = ...
From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

GRU interrupts for the kernel context are targeted to core 0
of the lowest socket on the blade.

Fix an endcase for 6-socket processors that do not have a
APICID for core 0. (There are potentially 8 cores in the
socket. A 6 core socket has 2 cores disabled. If core 0 was
disabled, the old code did not work).

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

---
 drivers/misc/sgi-gru/grumain.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux/drivers/misc/sgi-gru/grumain.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grumain.c	2010-06-09 08:11:43.740083860 -0500
+++ linux/drivers/misc/sgi-gru/grumain.c	2010-06-09 08:11:44.128107324 -0500
@@ -618,7 +618,7 @@ void gru_load_context(struct gru_thread_
 		cch->unmap_enable = 1;
 		cch->tfm_done_bit_enable = 1;
 		cch->cb_int_enable = 1;
-		cch->tlb_int_select = 0;	/* For now, ints go to cpu 0 */
+		cch->tlb_int_select = uv_cpu_core_number(0); /* For now, ints go to cpu 0 */
 	} else {
 		cch->unmap_enable = 0;
 		cch->tfm_done_bit_enable = 0;

--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

The GRU hardware has reserved a few bits for software use.
Add these "software reserved" fields to the structure definitions.

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

---
 drivers/misc/sgi-gru/gru_instructions.h |   19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

Index: linux/drivers/misc/sgi-gru/gru_instructions.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gru_instructions.h	2010-06-09 08:11:38.907960603 -0500
+++ linux/drivers/misc/sgi-gru/gru_instructions.h	2010-06-09 08:11:43.303963161 -0500
@@ -112,7 +112,8 @@ struct gru_instruction_bits {
     unsigned char		reserved3: 1;
     unsigned char		tlb_fault_color: 1;
     /* DW 1 */
-    unsigned long		idef4;		/* 42 bits: TRi1, BufSize */
+    unsigned int		idef4;		/* 32 bits: TRi1, BufSize */
+    unsigned int		sw_reserved;
     /* DW 2-6 */
     unsigned long		idef1;		/* BAddr0 */
     unsigned long		idef5;		/* Nelem */
@@ -136,7 +137,13 @@ struct gru_instruction {
 		unsigned int	tri0;
 	};
     };
-    unsigned long		tri1_bufsize;		/* DW 1 */
+    union {
+	unsigned long		tri1_bufsize_64;	/* DW 1 */
+	struct {
+    		unsigned int	tri1_bufsize_32;
+		unsigned int	sw_reserved;
+	};
+    };
     unsigned long		baddr0;			/* DW 2 */
     unsigned long		nelem;			/* DW 3 */
     unsigned long		op1_stride;		/* DW 4 */
@@ -411,7 +418,7 @@ static inline void gru_ivload(void *cb,
 
 	ins->baddr0 = (long)mem_addr;
 	ins->nelem = nelem;
-	ins->tri1_bufsize = tri1;
+	ins->tri1_bufsize_64 = tri1;
 	gru_start_instruction(ins, __opdword(OP_IVLOAD, 0, xtype, IAA_RAM, 0,
 					tri0, CB_IMA(hints)));
 }
@@ -424,7 +431,7 @@ static inline void gru_ivstore(void *cb,
 
 	ins->baddr0 = (long)mem_addr;
 	ins->nelem = nelem;
-	ins->tri1_bufsize = tri1;
+	ins->tri1_bufsize_64 = tri1;
 	gru_start_instruction(ins, __opdword(OP_IVSTORE, 0, xtype, IAA_RAM, 0,
 					tri0, CB_IMA(hints)));
 }
@@ -452,7 ...
From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Flush the GRU TLB when the GRU driver is loaded. There may be stale
entries in the TLB if a previous GRU was unloaded since the system
was last reset.

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

---
 drivers/misc/sgi-gru/grutlbpurge.c |    2 ++
 1 file changed, 2 insertions(+)

Index: linux/drivers/misc/sgi-gru/grutlbpurge.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grutlbpurge.c	2010-06-09 08:11:42.087537647 -0500
+++ linux/drivers/misc/sgi-gru/grutlbpurge.c	2010-06-09 08:11:42.891554573 -0500
@@ -380,4 +380,6 @@ void gru_tgh_flush_init(struct gru_state
 	/* first starting TGH index to use for remote purges */
 	gru->gs_tgh_first_remote = (cpus + (1 << shift) - 1) >> shift;
 
+	/* flush the GRU TLB in case there are stale entries present */
+	gru_flush_all_tlb(gru);
 }

--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

This patch substantially reworks the way the GRU driver steals
contexts from users in order to use the GRU resources for kernel use.

The new version fixes some ugly locking bugs and is overall more efficient.

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

---
 drivers/misc/sgi-gru/grufault.c     |    2 
 drivers/misc/sgi-gru/grukservices.c |  271 +++++++++++++++++-------------------
 drivers/misc/sgi-gru/gruprocfs.c    |   12 +
 drivers/misc/sgi-gru/grutables.h    |   37 +++-
 drivers/misc/sgi-gru/grutlbpurge.c  |    2 
 5 files changed, 167 insertions(+), 157 deletions(-)

Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2010-07-19 10:23:21.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2010-07-19 10:23:54.846243726 -0500
@@ -564,7 +564,7 @@ static irqreturn_t gru_intr(int chiplet,
 
 	for_each_cbr_in_tfm(cbrnum, dmap.fault_bits) {
 		STAT(intr_cbr);
-		cmp = gru->gs_blade->bs_async_wq;
+		cmp = gru->gs_async_wq[cbrnum];
 		if (cmp)
 			complete(cmp);
 		gru_dbg(grudev, "gid %d, cbr_done %d, done %d\n",
Index: linux/drivers/misc/sgi-gru/grukservices.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grukservices.c	2010-07-19 10:23:10.000000000 -0500
+++ linux/drivers/misc/sgi-gru/grukservices.c	2010-07-19 10:23:54.854242947 -0500
@@ -95,14 +95,20 @@
  */
 
 
-#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 GRU_NUM_KERNEL_CBR	1
-#define GRU_NUM_KERNEL_DSR_BYTES 256
-#define GRU_NUM_KERNEL_DSR_CL	(GRU_NUM_KERNEL_DSR_BYTES /		\
-					GRU_CACHE_LINE_BYTES)
+#define HAN_TO_BID(h)	((h) - 1)
+#define BID_TO_HAN(b)	((b) + 1)
+#define HAN_TO_BS(h)	gru_base[HAN_TO_BID(h)]
+
+/* Total CBRs in a kernel context for a blade */
+#define ...
From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Add a flag to the GRU cch_status file to indicate if the cch is locked.
This is useful for debugging.

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


---
 drivers/misc/sgi-gru/gruprocfs.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

Index: linux/drivers/misc/sgi-gru/gruprocfs.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gruprocfs.c	2010-06-09 08:11:42.043954832 -0500
+++ linux/drivers/misc/sgi-gru/gruprocfs.c	2010-06-09 08:11:42.456084620 -0500
@@ -190,21 +190,22 @@ static int cch_seq_show(struct seq_file
 	const char *mode[] = { "??", "UPM", "INTR", "OS_POLL" };
 
 	if (gid == 0)
-		seq_printf(file, "#%5s%5s%6s%7s%9s%6s%8s%8s\n", "gid", "bid",
-			   "ctx#", "asid", "pid", "cbrs", "dsbytes", "mode");
+		seq_printf(file, "#%5s%5s%6s%7s%9s%6s%8s%8s%7s\n", "gid", "bid",
+			   "ctx#", "asid", "pid", "cbrs", "dsbytes", "mode", "locked");
 	if (gru)
 		for (i = 0; i < GRU_NUM_CCH; i++) {
 			ts = gru->gs_gts[i];
 			if (!ts)
 				continue;
-			seq_printf(file, " %5d%5d%6d%7d%9d%6d%8d%8s\n",
+			seq_printf(file, " %5d%5d%6d%7d%9d%6d%8d%8s%7s\n",
 				   gru->gs_gid, gru->gs_blade_id, i,
 				   is_kernel_context(ts) ? 0 : ts->ts_gms->ms_asids[gid].mt_asid,
 				   is_kernel_context(ts) ? 0 : ts->ts_tgid_owner,
 				   ts->ts_cbr_au_count * GRU_CBR_AU_SIZE,
-				   ts->ts_cbr_au_count * GRU_DSR_AU_BYTES,
+				   ts->ts_dsr_au_count * GRU_DSR_AU_BYTES,
 				   mode[ts->ts_user_options &
-					GRU_OPT_MISS_MASK]);
+					GRU_OPT_MISS_MASK],
+				   mutex_is_locked(&ts->ts_ctxlock) ? "LOCKED" : "-");
 		}
 
 	return 0;

--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

In some cases, for performance reasons flushing the SGI GRU cbe
needs to dirty the cacheline before doing the cacheline flush. This ensures
that the dirty cacheline actually goes back to the caching home agent.
Update a reserved field in the CBE instead of a field that might be used. This
_should_ not be required (dirtying any field should be ok) but early
silicon has an issue here.

Note that flushing the CL is not a requirement - only a performance enhancement.

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


---
 drivers/misc/sgi-gru/grufault.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2010-06-09 08:11:40.285085853 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2010-06-09 08:11:41.157110138 -0500
@@ -306,7 +306,7 @@ upm:
 static void gru_flush_cache_cbe(struct gru_control_block_extended *cbe)
 {
 	if (unlikely(cbe)) {
-		cbe->cbrexecstatus = 0;         /* make CL dirty */
+		cbe->reserved6 = 0;         /* make CL dirty */
 		gru_flush_cache(cbe);
 	}
 }

--

From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Skip purging the GRU TLB if the purge request is for the GRU
itself. The driver will not create TLB mappings for vmas
that map the GRU address space. Purging them is unnecessary.

This is only an optimization and is not functionally required. However, if
GRU resources are oversubscribed (unusual except for stress tests),
purging can be frequent.

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


---
 drivers/misc/sgi-gru/grufault.c    |    8 ++++----
 drivers/misc/sgi-gru/grufile.c     |    2 +-
 drivers/misc/sgi-gru/gruprocfs.c   |    1 +
 drivers/misc/sgi-gru/grutables.h   |    3 ++-
 drivers/misc/sgi-gru/grutlbpurge.c |   11 +++++++++--
 5 files changed, 17 insertions(+), 8 deletions(-)

Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2010-06-09 08:11:31.480037430 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2010-06-09 08:11:39.747460083 -0500
@@ -57,11 +57,11 @@ static inline int is_gru_paddr(unsigned
 /*
  * Find the vma of a GRU segment. Caller must hold mmap_sem.
  */
-struct vm_area_struct *gru_find_vma(unsigned long vaddr)
+struct vm_area_struct *gru_find_vma(struct mm_struct *mm, unsigned long vaddr)
 {
 	struct vm_area_struct *vma;
 
-	vma = find_vma(current->mm, vaddr);
+	vma = find_vma(mm, vaddr);
 	if (vma && vma->vm_start <= vaddr && vma->vm_ops == &gru_vm_ops)
 		return vma;
 	return NULL;
@@ -82,7 +82,7 @@ static struct gru_thread_state *gru_find
 	struct gru_thread_state *gts = NULL;
 
 	down_read(&mm->mmap_sem);
-	vma = gru_find_vma(vaddr);
+	vma = gru_find_vma(current->mm, vaddr);
 	if (vma)
 		gts = gru_find_thread_state(vma, TSID(vaddr, vma));
 	if (gts)
@@ -99,7 +99,7 @@ static struct gru_thread_state *gru_allo
 	struct gru_thread_state *gts = ERR_PTR(-EINVAL);
 
 	down_write(&mm->mmap_sem);
-	vma = gru_find_vma(vaddr);
+	vma = gru_find_vma(current->mm, vaddr);
 	if (!vma)
 		goto ...
From: steiner
Date: Thursday, August 26, 2010 - 6:19 am

From: Jack Steiner <steiner@sgi.com>

Update the GRU TLB dropin statistics. Add counts to indicate
number of TLB miss interrupts and a separate count of TLB
entries actually written. Also minor code cleanup of the TLB fault path.


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

---
 drivers/misc/sgi-gru/gru.h       |    3 ++-
 drivers/misc/sgi-gru/grufault.c  |   33 +++++++++++++++++++++++++--------
 drivers/misc/sgi-gru/gruprocfs.c |    1 +
 drivers/misc/sgi-gru/grutables.h |    1 +
 4 files changed, 29 insertions(+), 9 deletions(-)

Index: linux/drivers/misc/sgi-gru/gru.h
===================================================================
--- linux.orig/drivers/misc/sgi-gru/gru.h	2010-06-09 08:11:31.372037434 -0500
+++ linux/drivers/misc/sgi-gru/gru.h	2010-06-09 08:11:40.281083913 -0500
@@ -61,7 +61,8 @@ struct gru_gseg_statistics {
 	unsigned long	upm_tlbmiss;
 	unsigned long	tlbdropin;
 	unsigned long	context_stolen;
-	unsigned long	reserved[10];
+	unsigned long	interrupts;
+	unsigned long	reserved[9];
 };
 
 /* Flags for GRU options on the gru_create_context() call */
Index: linux/drivers/misc/sgi-gru/grufault.c
===================================================================
--- linux.orig/drivers/misc/sgi-gru/grufault.c	2010-06-09 08:11:39.747460083 -0500
+++ linux/drivers/misc/sgi-gru/grufault.c	2010-06-09 08:11:40.285085853 -0500
@@ -289,8 +289,10 @@ static int gru_vtop(struct gru_thread_st
 	return VTOP_SUCCESS;
 
 inval:
+	STAT(tlb_dropin_fail_invalid);
 	return VTOP_INVALID;
 upm:
+	STAT(tlb_dropin_fail_retry);
 	return VTOP_RETRY;
 }
 
@@ -422,7 +424,7 @@ static int gru_try_dropin(struct gru_sta
 	if (ret == VTOP_INVALID)
 		goto failinval;
 	if (ret == VTOP_RETRY)
-		goto failupm;
+		goto failretry;
 
 	if (!(gts->ts_sizeavail & GRU_SIZEAVAIL(pageshift))) {
 		gts->ts_sizeavail |= GRU_SIZEAVAIL(pageshift);
@@ -438,9 +440,9 @@ static int gru_try_dropin(struct gru_sta
 	}
 
 	gru_cb_set_istatus_active(cbk);
-	gts->ustats.tlbdropin++;
 ...
Previous thread: [PATCH] mips: irq: add stackoverflow detection by Adam Jiang on Thursday, August 26, 2010 - 6:19 am. (3 messages)

Next thread: [PATCH 1/2] MCE, AMD: Limit MCE decoding to current families for now by Borislav Petkov on Thursday, August 26, 2010 - 7:06 am. (1 message)