aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru/grufault.c
diff options
context:
space:
mode:
authorJack Steiner <steiner@sgi.com>2009-06-17 19:28:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-18 16:04:03 -0400
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 6d0681236db5..cdd151b30dc7 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)
498 */ 498 */
499 if (!gts->ts_force_cch_reload && 499 if (!gts->ts_force_cch_reload &&
500 down_read_trylock(&gts->ts_mm->mmap_sem)) { 500 down_read_trylock(&gts->ts_mm->mmap_sem)) {
501 gts->ustats.fmm_tlbdropin++;
501 gru_try_dropin(gts, tfh, NULL); 502 gru_try_dropin(gts, tfh, NULL);
502 up_read(&gts->ts_mm->mmap_sem); 503 up_read(&gts->ts_mm->mmap_sem);
503 } else { 504 } else {
@@ -516,6 +517,7 @@ static int gru_user_dropin(struct gru_thread_state *gts,
516 struct gru_mm_struct *gms = gts->ts_gms; 517 struct gru_mm_struct *gms = gts->ts_gms;
517 int ret; 518 int ret;
518 519
520 gts->ustats.upm_tlbdropin++;
519 while (1) { 521 while (1) {
520 wait_event(gms->ms_wait_queue, 522 wait_event(gms->ms_wait_queue,
521 atomic_read(&gms->ms_range_active) == 0); 523 atomic_read(&gms->ms_range_active) == 0);
@@ -719,6 +721,31 @@ int gru_user_flush_tlb(unsigned long arg)
719} 721}
720 722
721/* 723/*
724 * Fetch GSEG statisticss
725 */
726long gru_get_gseg_statistics(unsigned long arg)
727{
728 struct gru_thread_state *gts;
729 struct gru_get_gseg_statistics_req req;
730
731 if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
732 return -EFAULT;
733
734 gts = gru_find_lock_gts(req.gseg);
735 if (gts) {
736 memcpy(&req.stats, &gts->ustats, sizeof(gts->ustats));
737 gru_unlock_gts(gts);
738 } else {
739 memset(&req.stats, 0, sizeof(gts->ustats));
740 }
741
742 if (copy_to_user((void __user *)arg, &req, sizeof(req)))
743 return -EFAULT;
744
745 return 0;
746}
747
748/*
722 * Register the current task as the user of the GSEG slice. 749 * Register the current task as the user of the GSEG slice.
723 * Needed for TLB fault interrupt targeting. 750 * Needed for TLB fault interrupt targeting.
724 */ 751 */