aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru
diff options
context:
space:
mode:
authorJack Steiner <steiner@sgi.com>2009-12-15 19:48:12 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-16 10:20:16 -0500
commit563447d7eb04c9b382f90a132be126a21a635647 (patch)
tree66db9c281ed1b64fcdceab1beb34350339bf306c /drivers/misc/sgi-gru
parent4107e1d38a23028c2a3bc23dd948265dbe6becba (diff)
gru: add additional GRU statistics
Add additional GRU statistics & debug messages. 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')
-rw-r--r--drivers/misc/sgi-gru/grufault.c18
-rw-r--r--drivers/misc/sgi-gru/grufile.c2
-rw-r--r--drivers/misc/sgi-gru/gruhandles.c11
-rw-r--r--drivers/misc/sgi-gru/grukservices.c35
-rw-r--r--drivers/misc/sgi-gru/grumain.c10
-rw-r--r--drivers/misc/sgi-gru/gruprocfs.c25
-rw-r--r--drivers/misc/sgi-gru/grutables.h18
-rw-r--r--drivers/misc/sgi-gru/grutlbpurge.c6
8 files changed, 77 insertions, 48 deletions
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index a78aa798d50b..7d757e9c42f0 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -303,7 +303,7 @@ static int gru_try_dropin(struct gru_thread_state *gts,
303 struct gru_tlb_fault_handle *tfh, 303 struct gru_tlb_fault_handle *tfh,
304 struct gru_instruction_bits *cbk) 304 struct gru_instruction_bits *cbk)
305{ 305{
306 int pageshift = 0, asid, write, ret, atomic = !cbk; 306 int pageshift = 0, asid, write, ret, atomic = !cbk, indexway;
307 unsigned long gpa = 0, vaddr = 0; 307 unsigned long gpa = 0, vaddr = 0;
308 308
309 /* 309 /*
@@ -333,6 +333,7 @@ static int gru_try_dropin(struct gru_thread_state *gts,
333 write = (tfh->cause & TFHCAUSE_TLB_MOD) != 0; 333 write = (tfh->cause & TFHCAUSE_TLB_MOD) != 0;
334 vaddr = tfh->missvaddr; 334 vaddr = tfh->missvaddr;
335 asid = tfh->missasid; 335 asid = tfh->missasid;
336 indexway = tfh->indexway;
336 if (asid == 0) 337 if (asid == 0)
337 goto failnoasid; 338 goto failnoasid;
338 339
@@ -361,11 +362,12 @@ static int gru_try_dropin(struct gru_thread_state *gts,
361 gru_cb_set_istatus_active(cbk); 362 gru_cb_set_istatus_active(cbk);
362 tfh_write_restart(tfh, gpa, GAA_RAM, vaddr, asid, write, 363 tfh_write_restart(tfh, gpa, GAA_RAM, vaddr, asid, write,
363 GRU_PAGESIZE(pageshift)); 364 GRU_PAGESIZE(pageshift));
364 STAT(tlb_dropin);
365 gru_dbg(grudev, 365 gru_dbg(grudev,
366 "%s: tfh 0x%p, vaddr 0x%lx, asid 0x%x, ps %d, gpa 0x%lx\n", 366 "%s: gid %d, gts 0x%p, tfh 0x%p, vaddr 0x%lx, asid 0x%x, indexway 0x%x,"
367 ret ? "non-atomic" : "atomic", tfh, vaddr, asid, 367 " rw %d, ps %d, gpa 0x%lx\n",
368 pageshift, gpa); 368 atomic ? "atomic" : "non-atomic", gts->ts_gru->gs_gid, gts, tfh, vaddr, asid,
369 indexway, write, pageshift, gpa);
370 STAT(tlb_dropin);
369 return 0; 371 return 0;
370 372
371failnoasid: 373failnoasid:
@@ -460,12 +462,14 @@ static irqreturn_t gru_intr(int chiplet, int blade)
460 dmap.fault_bits[0], dmap.fault_bits[1]); 462 dmap.fault_bits[0], dmap.fault_bits[1]);
461 463
462 for_each_cbr_in_tfm(cbrnum, dmap.fault_bits) { 464 for_each_cbr_in_tfm(cbrnum, dmap.fault_bits) {
465 STAT(intr_cbr);
463 complete(gru->gs_blade->bs_async_wq); 466 complete(gru->gs_blade->bs_async_wq);
464 gru_dbg(grudev, "gid %d, cbr_done %d, done %d\n", 467 gru_dbg(grudev, "gid %d, cbr_done %d, done %d\n",
465 gru->gs_gid, cbrnum, gru->gs_blade->bs_async_wq->done); 468 gru->gs_gid, cbrnum, gru->gs_blade->bs_async_wq->done);
466 } 469 }
467 470
468 for_each_cbr_in_tfm(cbrnum, imap.fault_bits) { 471 for_each_cbr_in_tfm(cbrnum, imap.fault_bits) {
472 STAT(intr_tfh);
469 tfh = get_tfh_by_index(gru, cbrnum); 473 tfh = get_tfh_by_index(gru, cbrnum);
470 prefetchw(tfh); /* Helps on hdw, required for emulator */ 474 prefetchw(tfh); /* Helps on hdw, required for emulator */
471 475
@@ -551,7 +555,6 @@ int gru_handle_user_call_os(unsigned long cb)
551 int ucbnum, cbrnum, ret = -EINVAL; 555 int ucbnum, cbrnum, ret = -EINVAL;
552 556
553 STAT(call_os); 557 STAT(call_os);
554 gru_dbg(grudev, "address 0x%lx\n", cb);
555 558
556 /* sanity check the cb pointer */ 559 /* sanity check the cb pointer */
557 ucbnum = get_cb_number((void *)cb); 560 ucbnum = get_cb_number((void *)cb);
@@ -561,6 +564,7 @@ int gru_handle_user_call_os(unsigned long cb)
561 gts = gru_find_lock_gts(cb); 564 gts = gru_find_lock_gts(cb);
562 if (!gts) 565 if (!gts)
563 return -EINVAL; 566 return -EINVAL;
567 gru_dbg(grudev, "address 0x%lx, gid %d, gts 0x%p\n", cb, gts->ts_gru ? gts->ts_gru->gs_gid : -1, gts);
564 568
565 if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) 569 if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
566 goto exit; 570 goto exit;
@@ -603,11 +607,11 @@ int gru_get_exception_detail(unsigned long arg)
603 if (copy_from_user(&excdet, (void __user *)arg, sizeof(excdet))) 607 if (copy_from_user(&excdet, (void __user *)arg, sizeof(excdet)))
604 return -EFAULT; 608 return -EFAULT;
605 609
606 gru_dbg(grudev, "address 0x%lx\n", excdet.cb);
607 gts = gru_find_lock_gts(excdet.cb); 610 gts = gru_find_lock_gts(excdet.cb);
608 if (!gts) 611 if (!gts)
609 return -EINVAL; 612 return -EINVAL;
610 613
614 gru_dbg(grudev, "address 0x%lx, gid %d, gts 0x%p\n", excdet.cb, gts->ts_gru ? gts->ts_gru->gs_gid : -1, gts);
611 ucbnum = get_cb_number((void *)excdet.cb); 615 ucbnum = get_cb_number((void *)excdet.cb);
612 if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) { 616 if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) {
613 ret = -EINVAL; 617 ret = -EINVAL;
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index 22b8b2733a24..9d41208a6c92 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -192,7 +192,7 @@ static long gru_file_unlocked_ioctl(struct file *file, unsigned int req,
192{ 192{
193 int err = -EBADRQC; 193 int err = -EBADRQC;
194 194
195 gru_dbg(grudev, "file %p\n", file); 195 gru_dbg(grudev, "file %p, req 0x%x, 0x%lx\n", file, req, arg);
196 196
197 switch (req) { 197 switch (req) {
198 case GRU_CREATE_CONTEXT: 198 case GRU_CREATE_CONTEXT:
diff --git a/drivers/misc/sgi-gru/gruhandles.c b/drivers/misc/sgi-gru/gruhandles.c
index f1117a7637a2..4bc9ee811fbf 100644
--- a/drivers/misc/sgi-gru/gruhandles.c
+++ b/drivers/misc/sgi-gru/gruhandles.c
@@ -27,9 +27,11 @@
27#ifdef CONFIG_IA64 27#ifdef CONFIG_IA64
28#include <asm/processor.h> 28#include <asm/processor.h>
29#define GRU_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10) 29#define GRU_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
30#define CLKS2NSEC(c) ((c) *1000000000 / local_cpu_data->itc_freq)
30#else 31#else
31#include <asm/tsc.h> 32#include <asm/tsc.h>
32#define GRU_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) 33#define GRU_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
34#define CLKS2NSEC(c) ((c) * 1000000 / tsc_khz)
33#endif 35#endif
34 36
35/* Extract the status field from a kernel handle */ 37/* Extract the status field from a kernel handle */
@@ -39,10 +41,13 @@ struct mcs_op_statistic mcs_op_statistics[mcsop_last];
39 41
40static void update_mcs_stats(enum mcs_op op, unsigned long clks) 42static void update_mcs_stats(enum mcs_op op, unsigned long clks)
41{ 43{
44 unsigned long nsec;
45
46 nsec = CLKS2NSEC(clks);
42 atomic_long_inc(&mcs_op_statistics[op].count); 47 atomic_long_inc(&mcs_op_statistics[op].count);
43 atomic_long_add(clks, &mcs_op_statistics[op].total); 48 atomic_long_add(nsec, &mcs_op_statistics[op].total);
44 if (mcs_op_statistics[op].max < clks) 49 if (mcs_op_statistics[op].max < nsec)
45 mcs_op_statistics[op].max = clks; 50 mcs_op_statistics[op].max = nsec;
46} 51}
47 52
48static void start_instruction(void *h) 53static void start_instruction(void *h)
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c
index 8c81aca0463a..4da6f56833d1 100644
--- a/drivers/misc/sgi-gru/grukservices.c
+++ b/drivers/misc/sgi-gru/grukservices.c
@@ -414,8 +414,8 @@ char *gru_get_cb_exception_detail_str(int ret, void *cb,
414 if (ret > 0 && gen->istatus == CBS_EXCEPTION) { 414 if (ret > 0 && gen->istatus == CBS_EXCEPTION) {
415 gru_get_cb_exception_detail(cb, &excdet); 415 gru_get_cb_exception_detail(cb, &excdet);
416 snprintf(buf, size, 416 snprintf(buf, size,
417 "GRU exception: cb %p, opc %d, exopc %d, ecause 0x%x," 417 "GRU:%d exception: cb %p, opc %d, exopc %d, ecause 0x%x,"
418 "excdet0 0x%lx, excdet1 0x%x", 418 "excdet0 0x%lx, excdet1 0x%x", smp_processor_id(),
419 gen, excdet.opc, excdet.exopc, excdet.ecause, 419 gen, excdet.opc, excdet.exopc, excdet.ecause,
420 excdet.exceptdet0, excdet.exceptdet1); 420 excdet.exceptdet0, excdet.exceptdet1);
421 } else { 421 } else {
@@ -604,6 +604,8 @@ static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd,
604 ret = MQE_UNEXPECTED_CB_ERR; 604 ret = MQE_UNEXPECTED_CB_ERR;
605 break; 605 break;
606 case CBSS_PAGE_OVERFLOW: 606 case CBSS_PAGE_OVERFLOW:
607 STAT(mesq_noop_page_overflow);
608 /* fallthru */
607 default: 609 default:
608 BUG(); 610 BUG();
609 } 611 }
@@ -745,6 +747,9 @@ static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
745 STAT(mesq_send_put_nacked); 747 STAT(mesq_send_put_nacked);
746 ret = send_message_put_nacked(cb, mqd, mesg, lines); 748 ret = send_message_put_nacked(cb, mqd, mesg, lines);
747 break; 749 break;
750 case CBSS_PAGE_OVERFLOW:
751 STAT(mesq_page_overflow);
752 /* fallthru */
748 default: 753 default:
749 BUG(); 754 BUG();
750 } 755 }
@@ -837,7 +842,6 @@ void *gru_get_next_message(struct gru_message_queue_desc *mqd)
837 int present = mhdr->present; 842 int present = mhdr->present;
838 843
839 /* skip NOOP messages */ 844 /* skip NOOP messages */
840 STAT(mesq_receive);
841 while (present == MQS_NOOP) { 845 while (present == MQS_NOOP) {
842 gru_free_message(mqd, mhdr); 846 gru_free_message(mqd, mhdr);
843 mhdr = mq->next; 847 mhdr = mq->next;
@@ -857,6 +861,7 @@ void *gru_get_next_message(struct gru_message_queue_desc *mqd)
857 if (mhdr->lines == 2) 861 if (mhdr->lines == 2)
858 restore_present2(mhdr, mhdr->present2); 862 restore_present2(mhdr, mhdr->present2);
859 863
864 STAT(mesq_receive);
860 return mhdr; 865 return mhdr;
861} 866}
862EXPORT_SYMBOL_GPL(gru_get_next_message); 867EXPORT_SYMBOL_GPL(gru_get_next_message);
@@ -927,24 +932,24 @@ static int quicktest0(unsigned long arg)
927 932
928 gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); 933 gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
929 if (gru_wait(cb) != CBS_IDLE) { 934 if (gru_wait(cb) != CBS_IDLE) {
930 printk(KERN_DEBUG "GRU quicktest0: CBR failure 1\n"); 935 printk(KERN_DEBUG "GRU:%d quicktest0: CBR failure 1\n", smp_processor_id());
931 goto done; 936 goto done;
932 } 937 }
933 938
934 if (*p != MAGIC) { 939 if (*p != MAGIC) {
935 printk(KERN_DEBUG "GRU: quicktest0 bad magic 0x%lx\n", *p); 940 printk(KERN_DEBUG "GRU:%d quicktest0 bad magic 0x%lx\n", smp_processor_id(), *p);
936 goto done; 941 goto done;
937 } 942 }
938 gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); 943 gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
939 if (gru_wait(cb) != CBS_IDLE) { 944 if (gru_wait(cb) != CBS_IDLE) {
940 printk(KERN_DEBUG "GRU quicktest0: CBR failure 2\n"); 945 printk(KERN_DEBUG "GRU:%d quicktest0: CBR failure 2\n", smp_processor_id());
941 goto done; 946 goto done;
942 } 947 }
943 948
944 if (word0 != word1 || word1 != MAGIC) { 949 if (word0 != word1 || word1 != MAGIC) {
945 printk(KERN_DEBUG 950 printk(KERN_DEBUG
946 "GRU quicktest0 err: found 0x%lx, expected 0x%lx\n", 951 "GRU:%d quicktest0 err: found 0x%lx, expected 0x%lx\n",
947 word1, MAGIC); 952 smp_processor_id(), word1, MAGIC);
948 goto done; 953 goto done;
949 } 954 }
950 ret = 0; 955 ret = 0;
@@ -981,8 +986,11 @@ static int quicktest1(unsigned long arg)
981 if (ret) 986 if (ret)
982 break; 987 break;
983 } 988 }
984 if (ret != MQE_QUEUE_FULL || i != 4) 989 if (ret != MQE_QUEUE_FULL || i != 4) {
990 printk(KERN_DEBUG "GRU:%d quicktest1: unexpect status %d, i %d\n",
991 smp_processor_id(), ret, i);
985 goto done; 992 goto done;
993 }
986 994
987 for (i = 0; i < 6; i++) { 995 for (i = 0; i < 6; i++) {
988 m = gru_get_next_message(&mqd); 996 m = gru_get_next_message(&mqd);
@@ -990,7 +998,12 @@ static int quicktest1(unsigned long arg)
990 break; 998 break;
991 gru_free_message(&mqd, m); 999 gru_free_message(&mqd, m);
992 } 1000 }
993 ret = (i == 4) ? 0 : -EIO; 1001 if (i != 4) {
1002 printk(KERN_DEBUG "GRU:%d quicktest2: bad message, i %d, m %p, m8 %d\n",
1003 smp_processor_id(), i, m, m ? m[8] : -1);
1004 goto done;
1005 }
1006 ret = 0;
994 1007
995done: 1008done:
996 kfree(p); 1009 kfree(p);
@@ -1069,7 +1082,7 @@ static int quicktest3(unsigned long arg)
1069 memset(buf1, get_cycles() & 255, sizeof(buf1)); 1082 memset(buf1, get_cycles() & 255, sizeof(buf1));
1070 gru_copy_gpa(uv_gpa(buf2), uv_gpa(buf1), BUFSIZE); 1083 gru_copy_gpa(uv_gpa(buf2), uv_gpa(buf1), BUFSIZE);
1071 if (memcmp(buf1, buf2, BUFSIZE)) { 1084 if (memcmp(buf1, buf2, BUFSIZE)) {
1072 printk(KERN_DEBUG "GRU quicktest3 error\n"); 1085 printk(KERN_DEBUG "GRU:%d quicktest3 error\n", smp_processor_id());
1073 ret = -EIO; 1086 ret = -EIO;
1074 } 1087 }
1075 return ret; 1088 return ret;
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
index 120c70c5a28a..ebabbdcbb97f 100644
--- a/drivers/misc/sgi-gru/grumain.c
+++ b/drivers/misc/sgi-gru/grumain.c
@@ -370,6 +370,7 @@ struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma, int tsid)
370 if (!vdata) 370 if (!vdata)
371 return NULL; 371 return NULL;
372 372
373 STAT(vdata_alloc);
373 INIT_LIST_HEAD(&vdata->vd_head); 374 INIT_LIST_HEAD(&vdata->vd_head);
374 spin_lock_init(&vdata->vd_lock); 375 spin_lock_init(&vdata->vd_lock);
375 gru_dbg(grudev, "alloc vdata %p\n", vdata); 376 gru_dbg(grudev, "alloc vdata %p\n", vdata);
@@ -552,7 +553,8 @@ void gru_unload_context(struct gru_thread_state *gts, int savestate)
552 zap_vma_ptes(gts->ts_vma, UGRUADDR(gts), GRU_GSEG_PAGESIZE); 553 zap_vma_ptes(gts->ts_vma, UGRUADDR(gts), GRU_GSEG_PAGESIZE);
553 cch = get_cch(gru->gs_gru_base_vaddr, ctxnum); 554 cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
554 555
555 gru_dbg(grudev, "gts %p\n", gts); 556 gru_dbg(grudev, "gts %p, cbrmap 0x%lx, dsrmap 0x%lx\n",
557 gts, gts->ts_cbr_map, gts->ts_dsr_map);
556 lock_cch_handle(cch); 558 lock_cch_handle(cch);
557 if (cch_interrupt_sync(cch)) 559 if (cch_interrupt_sync(cch))
558 BUG(); 560 BUG();
@@ -583,9 +585,7 @@ void gru_load_context(struct gru_thread_state *gts)
583 struct gru_context_configuration_handle *cch; 585 struct gru_context_configuration_handle *cch;
584 int i, err, asid, ctxnum = gts->ts_ctxnum; 586 int i, err, asid, ctxnum = gts->ts_ctxnum;
585 587
586 gru_dbg(grudev, "gts %p\n", gts);
587 cch = get_cch(gru->gs_gru_base_vaddr, ctxnum); 588 cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
588
589 lock_cch_handle(cch); 589 lock_cch_handle(cch);
590 cch->tfm_fault_bit_enable = 590 cch->tfm_fault_bit_enable =
591 (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL 591 (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
@@ -635,6 +635,10 @@ void gru_load_context(struct gru_thread_state *gts)
635 if (cch_start(cch)) 635 if (cch_start(cch))
636 BUG(); 636 BUG();
637 unlock_cch_handle(cch); 637 unlock_cch_handle(cch);
638
639 gru_dbg(grudev, "gid %d, gts %p, cbrmap 0x%lx, dsrmap 0x%lx, tie %d, tis %d\n",
640 gts->ts_gru->gs_gid, gts, gts->ts_cbr_map, gts->ts_dsr_map,
641 (gts->ts_user_options == GRU_OPT_MISS_FMM_INTR), gts->ts_tlb_int_select);
638} 642}
639 643
640/* 644/*
diff --git a/drivers/misc/sgi-gru/gruprocfs.c b/drivers/misc/sgi-gru/gruprocfs.c
index 4f6fc11a2637..0a57ab29cd30 100644
--- a/drivers/misc/sgi-gru/gruprocfs.c
+++ b/drivers/misc/sgi-gru/gruprocfs.c
@@ -36,8 +36,7 @@ static void printstat_val(struct seq_file *s, atomic_long_t *v, char *id)
36{ 36{
37 unsigned long val = atomic_long_read(v); 37 unsigned long val = atomic_long_read(v);
38 38
39 if (val) 39 seq_printf(s, "%16lu %s\n", val, id);
40 seq_printf(s, "%16lu %s\n", val, id);
41} 40}
42 41
43static int statistics_show(struct seq_file *s, void *p) 42static int statistics_show(struct seq_file *s, void *p)
@@ -46,7 +45,8 @@ static int statistics_show(struct seq_file *s, void *p)
46 printstat(s, vdata_free); 45 printstat(s, vdata_free);
47 printstat(s, gts_alloc); 46 printstat(s, gts_alloc);
48 printstat(s, gts_free); 47 printstat(s, gts_free);
49 printstat(s, vdata_double_alloc); 48 printstat(s, gms_alloc);
49 printstat(s, gms_free);
50 printstat(s, gts_double_allocate); 50 printstat(s, gts_double_allocate);
51 printstat(s, assign_context); 51 printstat(s, assign_context);
52 printstat(s, assign_context_failed); 52 printstat(s, assign_context_failed);
@@ -59,15 +59,15 @@ static int statistics_show(struct seq_file *s, void *p)
59 printstat(s, steal_kernel_context); 59 printstat(s, steal_kernel_context);
60 printstat(s, steal_context_failed); 60 printstat(s, steal_context_failed);
61 printstat(s, nopfn); 61 printstat(s, nopfn);
62 printstat(s, break_cow);
63 printstat(s, asid_new); 62 printstat(s, asid_new);
64 printstat(s, asid_next); 63 printstat(s, asid_next);
65 printstat(s, asid_wrap); 64 printstat(s, asid_wrap);
66 printstat(s, asid_reuse); 65 printstat(s, asid_reuse);
67 printstat(s, intr); 66 printstat(s, intr);
67 printstat(s, intr_cbr);
68 printstat(s, intr_tfh);
68 printstat(s, intr_mm_lock_failed); 69 printstat(s, intr_mm_lock_failed);
69 printstat(s, call_os); 70 printstat(s, call_os);
70 printstat(s, call_os_check_for_bug);
71 printstat(s, call_os_wait_queue); 71 printstat(s, call_os_wait_queue);
72 printstat(s, user_flush_tlb); 72 printstat(s, user_flush_tlb);
73 printstat(s, user_unload_context); 73 printstat(s, user_unload_context);
@@ -83,11 +83,9 @@ static int statistics_show(struct seq_file *s, void *p)
83 printstat(s, tlb_dropin_fail_idle); 83 printstat(s, tlb_dropin_fail_idle);
84 printstat(s, tlb_dropin_fail_fmm); 84 printstat(s, tlb_dropin_fail_fmm);
85 printstat(s, tlb_dropin_fail_no_exception); 85 printstat(s, tlb_dropin_fail_no_exception);
86 printstat(s, tlb_dropin_fail_no_exception_war);
87 printstat(s, tfh_stale_on_fault); 86 printstat(s, tfh_stale_on_fault);
88 printstat(s, mmu_invalidate_range); 87 printstat(s, mmu_invalidate_range);
89 printstat(s, mmu_invalidate_page); 88 printstat(s, mmu_invalidate_page);
90 printstat(s, mmu_clear_flush_young);
91 printstat(s, flush_tlb); 89 printstat(s, flush_tlb);
92 printstat(s, flush_tlb_gru); 90 printstat(s, flush_tlb_gru);
93 printstat(s, flush_tlb_gru_tgh); 91 printstat(s, flush_tlb_gru_tgh);
@@ -104,7 +102,6 @@ static int statistics_show(struct seq_file *s, void *p)
104 printstat(s, mesq_send_qlimit_reached); 102 printstat(s, mesq_send_qlimit_reached);
105 printstat(s, mesq_send_amo_nacked); 103 printstat(s, mesq_send_amo_nacked);
106 printstat(s, mesq_send_put_nacked); 104 printstat(s, mesq_send_put_nacked);
107 printstat(s, mesq_qf_not_full);
108 printstat(s, mesq_qf_locked); 105 printstat(s, mesq_qf_locked);
109 printstat(s, mesq_qf_noop_not_full); 106 printstat(s, mesq_qf_noop_not_full);
110 printstat(s, mesq_qf_switch_head_failed); 107 printstat(s, mesq_qf_switch_head_failed);
@@ -114,6 +111,7 @@ static int statistics_show(struct seq_file *s, void *p)
114 printstat(s, mesq_noop_qlimit_reached); 111 printstat(s, mesq_noop_qlimit_reached);
115 printstat(s, mesq_noop_amo_nacked); 112 printstat(s, mesq_noop_amo_nacked);
116 printstat(s, mesq_noop_put_nacked); 113 printstat(s, mesq_noop_put_nacked);
114 printstat(s, mesq_noop_page_overflow);
117 return 0; 115 return 0;
118} 116}
119 117
@@ -131,6 +129,7 @@ static int mcs_statistics_show(struct seq_file *s, void *p)
131 static char *id[] = {"cch_allocate", "cch_start", "cch_interrupt", 129 static char *id[] = {"cch_allocate", "cch_start", "cch_interrupt",
132 "cch_interrupt_sync", "cch_deallocate", "tgh_invalidate"}; 130 "cch_interrupt_sync", "cch_deallocate", "tgh_invalidate"};
133 131
132 seq_printf(s, "%-20s%12s%12s%12s\n", "#id", "count", "aver-clks", "max-clks");
134 for (op = 0; op < mcsop_last; op++) { 133 for (op = 0; op < mcsop_last; op++) {
135 count = atomic_long_read(&mcs_op_statistics[op].count); 134 count = atomic_long_read(&mcs_op_statistics[op].count);
136 total = atomic_long_read(&mcs_op_statistics[op].total); 135 total = atomic_long_read(&mcs_op_statistics[op].total);
@@ -150,6 +149,7 @@ static ssize_t mcs_statistics_write(struct file *file,
150 149
151static int options_show(struct seq_file *s, void *p) 150static int options_show(struct seq_file *s, void *p)
152{ 151{
152 seq_printf(s, "#bitmask: 1=trace, 2=statistics\n");
153 seq_printf(s, "0x%lx\n", gru_options); 153 seq_printf(s, "0x%lx\n", gru_options);
154 return 0; 154 return 0;
155} 155}
@@ -179,16 +179,17 @@ static int cch_seq_show(struct seq_file *file, void *data)
179 const char *mode[] = { "??", "UPM", "INTR", "OS_POLL" }; 179 const char *mode[] = { "??", "UPM", "INTR", "OS_POLL" };
180 180
181 if (gid == 0) 181 if (gid == 0)
182 seq_printf(file, "#%5s%5s%6s%9s%6s%8s%8s\n", "gid", "bid", 182 seq_printf(file, "#%5s%5s%6s%7s%9s%6s%8s%8s\n", "gid", "bid",
183 "ctx#", "pid", "cbrs", "dsbytes", "mode"); 183 "ctx#", "asid", "pid", "cbrs", "dsbytes", "mode");
184 if (gru) 184 if (gru)
185 for (i = 0; i < GRU_NUM_CCH; i++) { 185 for (i = 0; i < GRU_NUM_CCH; i++) {
186 ts = gru->gs_gts[i]; 186 ts = gru->gs_gts[i];
187 if (!ts) 187 if (!ts)
188 continue; 188 continue;
189 seq_printf(file, " %5d%5d%6d%9d%6d%8d%8s\n", 189 seq_printf(file, " %5d%5d%6d%7d%9d%6d%8d%8s\n",
190 gru->gs_gid, gru->gs_blade_id, i, 190 gru->gs_gid, gru->gs_blade_id, i,
191 ts->ts_tgid_owner, 191 is_kernel_context(ts) ? 0 : ts->ts_gms->ms_asids[gid].mt_asid,
192 is_kernel_context(ts) ? 0 : ts->ts_tgid_owner,
192 ts->ts_cbr_au_count * GRU_CBR_AU_SIZE, 193 ts->ts_cbr_au_count * GRU_CBR_AU_SIZE,
193 ts->ts_cbr_au_count * GRU_DSR_AU_BYTES, 194 ts->ts_cbr_au_count * GRU_DSR_AU_BYTES,
194 mode[ts->ts_user_options & 195 mode[ts->ts_user_options &
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h
index d83e36715e6b..76fe2987fc9f 100644
--- a/drivers/misc/sgi-gru/grutables.h
+++ b/drivers/misc/sgi-gru/grutables.h
@@ -171,7 +171,8 @@ struct gru_stats_s {
171 atomic_long_t vdata_free; 171 atomic_long_t vdata_free;
172 atomic_long_t gts_alloc; 172 atomic_long_t gts_alloc;
173 atomic_long_t gts_free; 173 atomic_long_t gts_free;
174 atomic_long_t vdata_double_alloc; 174 atomic_long_t gms_alloc;
175 atomic_long_t gms_free;
175 atomic_long_t gts_double_allocate; 176 atomic_long_t gts_double_allocate;
176 atomic_long_t assign_context; 177 atomic_long_t assign_context;
177 atomic_long_t assign_context_failed; 178 atomic_long_t assign_context_failed;
@@ -184,15 +185,15 @@ struct gru_stats_s {
184 atomic_long_t steal_kernel_context; 185 atomic_long_t steal_kernel_context;
185 atomic_long_t steal_context_failed; 186 atomic_long_t steal_context_failed;
186 atomic_long_t nopfn; 187 atomic_long_t nopfn;
187 atomic_long_t break_cow;
188 atomic_long_t asid_new; 188 atomic_long_t asid_new;
189 atomic_long_t asid_next; 189 atomic_long_t asid_next;
190 atomic_long_t asid_wrap; 190 atomic_long_t asid_wrap;
191 atomic_long_t asid_reuse; 191 atomic_long_t asid_reuse;
192 atomic_long_t intr; 192 atomic_long_t intr;
193 atomic_long_t intr_cbr;
194 atomic_long_t intr_tfh;
193 atomic_long_t intr_mm_lock_failed; 195 atomic_long_t intr_mm_lock_failed;
194 atomic_long_t call_os; 196 atomic_long_t call_os;
195 atomic_long_t call_os_check_for_bug;
196 atomic_long_t call_os_wait_queue; 197 atomic_long_t call_os_wait_queue;
197 atomic_long_t user_flush_tlb; 198 atomic_long_t user_flush_tlb;
198 atomic_long_t user_unload_context; 199 atomic_long_t user_unload_context;
@@ -208,11 +209,9 @@ struct gru_stats_s {
208 atomic_long_t tlb_dropin_fail_idle; 209 atomic_long_t tlb_dropin_fail_idle;
209 atomic_long_t tlb_dropin_fail_fmm; 210 atomic_long_t tlb_dropin_fail_fmm;
210 atomic_long_t tlb_dropin_fail_no_exception; 211 atomic_long_t tlb_dropin_fail_no_exception;
211 atomic_long_t tlb_dropin_fail_no_exception_war;
212 atomic_long_t tfh_stale_on_fault; 212 atomic_long_t tfh_stale_on_fault;
213 atomic_long_t mmu_invalidate_range; 213 atomic_long_t mmu_invalidate_range;
214 atomic_long_t mmu_invalidate_page; 214 atomic_long_t mmu_invalidate_page;
215 atomic_long_t mmu_clear_flush_young;
216 atomic_long_t flush_tlb; 215 atomic_long_t flush_tlb;
217 atomic_long_t flush_tlb_gru; 216 atomic_long_t flush_tlb_gru;
218 atomic_long_t flush_tlb_gru_tgh; 217 atomic_long_t flush_tlb_gru_tgh;
@@ -231,7 +230,7 @@ struct gru_stats_s {
231 atomic_long_t mesq_send_qlimit_reached; 230 atomic_long_t mesq_send_qlimit_reached;
232 atomic_long_t mesq_send_amo_nacked; 231 atomic_long_t mesq_send_amo_nacked;
233 atomic_long_t mesq_send_put_nacked; 232 atomic_long_t mesq_send_put_nacked;
234 atomic_long_t mesq_qf_not_full; 233 atomic_long_t mesq_page_overflow;
235 atomic_long_t mesq_qf_locked; 234 atomic_long_t mesq_qf_locked;
236 atomic_long_t mesq_qf_noop_not_full; 235 atomic_long_t mesq_qf_noop_not_full;
237 atomic_long_t mesq_qf_switch_head_failed; 236 atomic_long_t mesq_qf_switch_head_failed;
@@ -241,6 +240,7 @@ struct gru_stats_s {
241 atomic_long_t mesq_noop_qlimit_reached; 240 atomic_long_t mesq_noop_qlimit_reached;
242 atomic_long_t mesq_noop_amo_nacked; 241 atomic_long_t mesq_noop_amo_nacked;
243 atomic_long_t mesq_noop_put_nacked; 242 atomic_long_t mesq_noop_put_nacked;
243 atomic_long_t mesq_noop_page_overflow;
244 244
245}; 245};
246 246
@@ -255,8 +255,8 @@ struct mcs_op_statistic {
255 255
256extern struct mcs_op_statistic mcs_op_statistics[mcsop_last]; 256extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
257 257
258#define OPT_DPRINT 1 258#define OPT_DPRINT 1
259#define OPT_STATS 2 259#define OPT_STATS 2
260 260
261 261
262#define IRQ_GRU 110 /* Starting IRQ number for interrupts */ 262#define IRQ_GRU 110 /* Starting IRQ number for interrupts */
@@ -279,7 +279,7 @@ extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
279#define gru_dbg(dev, fmt, x...) \ 279#define gru_dbg(dev, fmt, x...) \
280 do { \ 280 do { \
281 if (gru_options & OPT_DPRINT) \ 281 if (gru_options & OPT_DPRINT) \
282 dev_dbg(dev, "%s: " fmt, __func__, x); \ 282 printk(KERN_DEBUG "GRU:%d %s: " fmt, smp_processor_id(), __func__, x);\
283 } while (0) 283 } while (0)
284#else 284#else
285#define gru_dbg(x...) 285#define gru_dbg(x...)
diff --git a/drivers/misc/sgi-gru/grutlbpurge.c b/drivers/misc/sgi-gru/grutlbpurge.c
index 421c548e51f1..240a6d361665 100644
--- a/drivers/misc/sgi-gru/grutlbpurge.c
+++ b/drivers/misc/sgi-gru/grutlbpurge.c
@@ -184,8 +184,8 @@ void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start,
184 STAT(flush_tlb_gru_tgh); 184 STAT(flush_tlb_gru_tgh);
185 asid = GRUASID(asid, start); 185 asid = GRUASID(asid, start);
186 gru_dbg(grudev, 186 gru_dbg(grudev,
187 " FLUSH gruid %d, asid 0x%x, num %ld, cbmap 0x%x\n", 187 " FLUSH gruid %d, asid 0x%x, vaddr 0x%lx, vamask 0x%x, num %ld, cbmap 0x%x\n",
188 gid, asid, num, asids->mt_ctxbitmap); 188 gid, asid, start, grupagesize, num, asids->mt_ctxbitmap);
189 tgh = get_lock_tgh_handle(gru); 189 tgh = get_lock_tgh_handle(gru);
190 tgh_invalidate(tgh, start, ~0, asid, grupagesize, 0, 190 tgh_invalidate(tgh, start, ~0, asid, grupagesize, 0,
191 num - 1, asids->mt_ctxbitmap); 191 num - 1, asids->mt_ctxbitmap);
@@ -308,6 +308,7 @@ struct gru_mm_struct *gru_register_mmu_notifier(void)
308 } else { 308 } else {
309 gms = kzalloc(sizeof(*gms), GFP_KERNEL); 309 gms = kzalloc(sizeof(*gms), GFP_KERNEL);
310 if (gms) { 310 if (gms) {
311 STAT(gms_alloc);
311 spin_lock_init(&gms->ms_asid_lock); 312 spin_lock_init(&gms->ms_asid_lock);
312 gms->ms_notifier.ops = &gru_mmuops; 313 gms->ms_notifier.ops = &gru_mmuops;
313 atomic_set(&gms->ms_refcnt, 1); 314 atomic_set(&gms->ms_refcnt, 1);
@@ -333,6 +334,7 @@ void gru_drop_mmu_notifier(struct gru_mm_struct *gms)
333 if (!gms->ms_released) 334 if (!gms->ms_released)
334 mmu_notifier_unregister(&gms->ms_notifier, current->mm); 335 mmu_notifier_unregister(&gms->ms_notifier, current->mm);
335 kfree(gms); 336 kfree(gms);
337 STAT(gms_free);
336 } 338 }
337} 339}
338 340