summaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru/grufault.c
diff options
context:
space:
mode:
authorJack Steiner <steiner@sgi.com>2009-06-17 16:28:30 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-18 13:04:03 -0700
commit7e796a72a2691d7094fd62da61097294d0d59ce4 (patch)
tree9e8d4e1eae9a2d23f604f0af5d101979dc7afec7 /drivers/misc/sgi-gru/grufault.c
parentd6e2fbce0d70c2072a1c478dbd37b34d27129d74 (diff)
gru: collect per-context user statistics
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> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-gru/grufault.c')
-rw-r--r--drivers/misc/sgi-gru/grufault.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index 6d0681236db..cdd151b30dc 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -498,6 +498,7 @@ irqreturn_t gru_intr(int irq, void *dev_id)
*/
if (!gts->ts_force_cch_reload &&
down_read_trylock(&gts->ts_mm->mmap_sem)) {
+ gts->ustats.fmm_tlbdropin++;
gru_try_dropin(gts, tfh, NULL);
up_read(&gts->ts_mm->mmap_sem);
} else {
@@ -516,6 +517,7 @@ static int gru_user_dropin(struct gru_thread_state *gts,
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);
@@ -719,6 +721,31 @@ int gru_user_flush_tlb(unsigned long arg)
}
/*
+ * Fetch GSEG statisticss
+ */
+long gru_get_gseg_statistics(unsigned long arg)
+{
+ struct gru_thread_state *gts;
+ struct gru_get_gseg_statistics_req req;
+
+ if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
+ return -EFAULT;
+
+ gts = gru_find_lock_gts(req.gseg);
+ if (gts) {
+ memcpy(&req.stats, &gts->ustats, sizeof(gts->ustats));
+ gru_unlock_gts(gts);
+ } else {
+ memset(&req.stats, 0, sizeof(gts->ustats));
+ }
+
+ if (copy_to_user((void __user *)arg, &req, sizeof(req)))
+ return -EFAULT;
+
+ return 0;
+}
+
+/*
* Register the current task as the user of the GSEG slice.
* Needed for TLB fault interrupt targeting.
*/