aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorJack Steiner <steiner@sgi.com>2009-06-17 19:28:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-18 16:04:02 -0400
commiteb5bd5e52a8eafb1ddb42f983d41f97552afa106 (patch)
treee23bb25f5f6530bf6adc6cabdf3642d9611cfc00 /drivers/misc
parent9120dec47f150636d85b3dba03318ccecd181c79 (diff)
gru: update gru kernel self tests
Change the kernel self tests that can be optionally executed on GRU initialization. This is primarily for testing. Eliminate the BUG statements on failure and return bad status. Add ioctl interface to execute the tests on demand. 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')
-rw-r--r--drivers/misc/sgi-gru/grufile.c3
-rw-r--r--drivers/misc/sgi-gru/grukservices.c150
-rw-r--r--drivers/misc/sgi-gru/grulib.h3
-rw-r--r--drivers/misc/sgi-gru/grutables.h2
4 files changed, 142 insertions, 16 deletions
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index b1567ce868e9..796ac704795e 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -250,6 +250,9 @@ static long gru_file_unlocked_ioctl(struct file *file, unsigned int req,
250 case GRU_USER_CALL_OS: 250 case GRU_USER_CALL_OS:
251 err = gru_handle_user_call_os(arg); 251 err = gru_handle_user_call_os(arg);
252 break; 252 break;
253 case GRU_KTEST:
254 err = gru_ktest(arg);
255 break;
253 case GRU_GET_CONFIG_INFO: 256 case GRU_GET_CONFIG_INFO:
254 err = gru_get_config_info(arg); 257 err = gru_get_config_info(arg);
255 break; 258 break;
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c
index 9dff33cb72e3..7d7952b27e03 100644
--- a/drivers/misc/sgi-gru/grukservices.c
+++ b/drivers/misc/sgi-gru/grukservices.c
@@ -846,13 +846,14 @@ EXPORT_SYMBOL_GPL(gru_copy_gpa);
846/* ------------------- KERNEL QUICKTESTS RUN AT STARTUP ----------------*/ 846/* ------------------- KERNEL QUICKTESTS RUN AT STARTUP ----------------*/
847/* Temp - will delete after we gain confidence in the GRU */ 847/* Temp - will delete after we gain confidence in the GRU */
848 848
849int quicktest(void) 849static int quicktest0(unsigned long arg)
850{ 850{
851 unsigned long word0; 851 unsigned long word0;
852 unsigned long word1; 852 unsigned long word1;
853 void *cb; 853 void *cb;
854 void *dsr; 854 void *dsr;
855 unsigned long *p; 855 unsigned long *p;
856 int ret = -EIO;
856 857
857 if (gru_get_cpu_resources(GRU_CACHE_LINE_BYTES, &cb, &dsr)) 858 if (gru_get_cpu_resources(GRU_CACHE_LINE_BYTES, &cb, &dsr))
858 return MQE_BUG_NO_RESOURCES; 859 return MQE_BUG_NO_RESOURCES;
@@ -861,26 +862,148 @@ int quicktest(void)
861 word1 = 0; 862 word1 = 0;
862 863
863 gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); 864 gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
864 if (gru_wait(cb) != CBS_IDLE) 865 if (gru_wait(cb) != CBS_IDLE) {
865 BUG(); 866 printk(KERN_DEBUG "GRU quicktest0: CBR failure 1\n");
867 goto done;
868 }
866 869
867 if (*p != MAGIC) 870 if (*p != MAGIC) {
868 BUG(); 871 printk(KERN_DEBUG "GRU: quicktest0 bad magic 0x%lx\n", *p);
872 goto done;
873 }
869 gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA); 874 gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
870 if (gru_wait(cb) != CBS_IDLE) 875 if (gru_wait(cb) != CBS_IDLE) {
871 BUG(); 876 printk(KERN_DEBUG "GRU quicktest0: CBR failure 2\n");
872 gru_free_cpu_resources(cb, dsr); 877 goto done;
878 }
873 879
874 if (word0 != word1 || word1 != MAGIC) { 880 if (word0 != word1 || word1 != MAGIC) {
875 printk 881 printk(KERN_DEBUG
876 ("GRU quicktest err: found 0x%lx, expected 0x%lx\n", 882 "GRU quicktest0 err: found 0x%lx, expected 0x%lx\n",
877 word1, MAGIC); 883 word1, MAGIC);
878 BUG(); /* ZZZ should not be fatal */ 884 goto done;
879 } 885 }
886 ret = 0;
880 887
881 return 0; 888done:
889 gru_free_cpu_resources(cb, dsr);
890 return ret;
882} 891}
883 892
893#define ALIGNUP(p, q) ((void *)(((unsigned long)(p) + (q) - 1) & ~(q - 1)))
894
895static int quicktest1(unsigned long arg)
896{
897 struct gru_message_queue_desc mqd;
898 void *p, *mq;
899 unsigned long *dw;
900 int i, ret = -EIO;
901 char mes[GRU_CACHE_LINE_BYTES], *m;
902
903 /* Need 1K cacheline aligned that does not cross page boundary */
904 p = kmalloc(4096, 0);
905 mq = ALIGNUP(p, 1024);
906 memset(mes, 0xee, sizeof(mes));
907 dw = mq;
908
909 gru_create_message_queue(&mqd, mq, 8 * GRU_CACHE_LINE_BYTES, 0, 0, 0);
910 for (i = 0; i < 6; i++) {
911 mes[8] = i;
912 do {
913 ret = gru_send_message_gpa(&mqd, mes, sizeof(mes));
914 } while (ret == MQE_CONGESTION);
915 if (ret)
916 break;
917 }
918 if (ret != MQE_QUEUE_FULL || i != 4)
919 goto done;
920
921 for (i = 0; i < 6; i++) {
922 m = gru_get_next_message(&mqd);
923 if (!m || m[8] != i)
924 break;
925 gru_free_message(&mqd, m);
926 }
927 ret = (i == 4) ? 0 : -EIO;
928
929done:
930 kfree(p);
931 return ret;
932}
933
934static int quicktest2(unsigned long arg)
935{
936 static DECLARE_COMPLETION(cmp);
937 unsigned long han;
938 int blade_id = 0;
939 int numcb = 4;
940 int ret = 0;
941 unsigned long *buf;
942 void *cb0, *cb;
943 int i, k, istatus, bytes;
944
945 bytes = numcb * 4 * 8;
946 buf = kmalloc(bytes, GFP_KERNEL);
947 if (!buf)
948 return -ENOMEM;
949
950 ret = -EBUSY;
951 han = gru_reserve_async_resources(blade_id, numcb, 0, &cmp);
952 if (!han)
953 goto done;
954
955 gru_lock_async_resource(han, &cb0, NULL);
956 memset(buf, 0xee, bytes);
957 for (i = 0; i < numcb; i++)
958 gru_vset(cb0 + i * GRU_HANDLE_STRIDE, uv_gpa(&buf[i * 4]), 0,
959 XTYPE_DW, 4, 1, IMA_INTERRUPT);
960
961 ret = 0;
962 for (k = 0; k < numcb; k++) {
963 gru_wait_async_cbr(han);
964 for (i = 0; i < numcb; i++) {
965 cb = cb0 + i * GRU_HANDLE_STRIDE;
966 istatus = gru_check_status(cb);
967 if (istatus == CBS_ACTIVE)
968 continue;
969 if (istatus == CBS_EXCEPTION)
970 ret = -EFAULT;
971 else if (buf[i] || buf[i + 1] || buf[i + 2] ||
972 buf[i + 3])
973 ret = -EIO;
974 }
975 }
976 BUG_ON(cmp.done);
977
978 gru_unlock_async_resource(han);
979 gru_release_async_resources(han);
980done:
981 kfree(buf);
982 return ret;
983}
984
985/*
986 * Debugging only. User hook for various kernel tests
987 * of driver & gru.
988 */
989int gru_ktest(unsigned long arg)
990{
991 int ret = -EINVAL;
992
993 switch (arg & 0xff) {
994 case 0:
995 ret = quicktest0(arg);
996 break;
997 case 1:
998 ret = quicktest1(arg);
999 break;
1000 case 2:
1001 ret = quicktest2(arg);
1002 break;
1003 }
1004 return ret;
1005
1006}
884 1007
885int gru_kservices_init(struct gru_state *gru) 1008int gru_kservices_init(struct gru_state *gru)
886{ 1009{
@@ -891,9 +1014,6 @@ int gru_kservices_init(struct gru_state *gru)
891 return 0; 1014 return 0;
892 1015
893 init_rwsem(&bs->bs_kgts_sema); 1016 init_rwsem(&bs->bs_kgts_sema);
894
895 if (gru_options & GRU_QUICKLOOK)
896 quicktest();
897 return 0; 1017 return 0;
898} 1018}
899 1019
diff --git a/drivers/misc/sgi-gru/grulib.h b/drivers/misc/sgi-gru/grulib.h
index 6ab872665e7f..87586551d16f 100644
--- a/drivers/misc/sgi-gru/grulib.h
+++ b/drivers/misc/sgi-gru/grulib.h
@@ -56,6 +56,9 @@
56/* Get some config options (primarily for tests & emulator) */ 56/* Get some config options (primarily for tests & emulator) */
57#define GRU_GET_CONFIG_INFO _IOWR(GRU_IOCTL_NUM, 51, void *) 57#define GRU_GET_CONFIG_INFO _IOWR(GRU_IOCTL_NUM, 51, void *)
58 58
59/* Various kernel self-tests */
60#define GRU_KTEST _IOWR(GRU_IOCTL_NUM, 52, void *)
61
59#define CONTEXT_WINDOW_BYTES(th) (GRU_GSEG_PAGESIZE * (th)) 62#define CONTEXT_WINDOW_BYTES(th) (GRU_GSEG_PAGESIZE * (th))
60#define THREAD_POINTER(p, th) (p + GRU_GSEG_PAGESIZE * (th)) 63#define THREAD_POINTER(p, th) (p + GRU_GSEG_PAGESIZE * (th))
61 64
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h
index ca81800146ff..6dfb3e69411f 100644
--- a/drivers/misc/sgi-gru/grutables.h
+++ b/drivers/misc/sgi-gru/grutables.h
@@ -258,7 +258,6 @@ extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
258 258
259#define OPT_DPRINT 1 259#define OPT_DPRINT 1
260#define OPT_STATS 2 260#define OPT_STATS 2
261#define GRU_QUICKLOOK 4
262 261
263 262
264#define IRQ_GRU 110 /* Starting IRQ number for interrupts */ 263#define IRQ_GRU 110 /* Starting IRQ number for interrupts */
@@ -662,6 +661,7 @@ extern int gru_fault(struct vm_area_struct *, struct vm_fault *vmf);
662extern struct gru_mm_struct *gru_register_mmu_notifier(void); 661extern struct gru_mm_struct *gru_register_mmu_notifier(void);
663extern void gru_drop_mmu_notifier(struct gru_mm_struct *gms); 662extern void gru_drop_mmu_notifier(struct gru_mm_struct *gms);
664 663
664extern int gru_ktest(unsigned long arg);
665extern void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start, 665extern void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start,
666 unsigned long len); 666 unsigned long len);
667 667