* [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(>s->ts_mm->mmap_sem)) {
+ gts->ustats.fmm_tlbdropin++;
gru_try_dropin(gts, tfh, NULL);
up_read(>s->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, >s->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, >s->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, >s->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).