[OpenAFS-devel] afs and the r5000 rev 1

Chas Williams chas@cmf.nrl.navy.mil
Fri, 12 Oct 2001 11:06:56 -0400 (EDT)


i noticed that the latest version of afs from ibm/transarc has a fix
for the r5000 rev 1 "problem".  i have had a fix for this problem for
quite a while and was holding off on submission since i heard that
sgi was going to make a workaround.  as of 6.5.13 sgi still apparently
hasnt fixed the kernel, so i guess i will submit my fix to afs.

apparently the rev 1 r5000 chips implement 'cvt' incorrectly.  the irix
kernel works around this problem by checking each text page mapped into
memory and doing a fixup on the cvt instructions.  it tries to maintain
a hash of these pages using fid2() or fid() if fid2() returns ENOSYS. 
afs, in an effort to prevent people from doing checkpoints on an afs
filesystem, makes fid2() return EINVAL.  this also keeps the kernel from
mapping executables that are in afs space on the broken r5000's.

this is the patch i have been using for the past couple years while
waiting for an official fix.  it makes fid2() return ENOSYS, so you
now need to have to have v_ckpt.  however i disabled the rest of the
CKPT code since i have no idea how well that code actually works.
additionally, this behavior is only functional on machines with the
'broken' r5000 h/w.  i cant think of a better way to fix this problem
since i cant change the irix kernel.


diff -r -u openafs-1.2.0/src/afs/IRIX/osi_vfs.h openafs/src/afs/IRIX/osi_vfs.h
--- openafs-1.2.0/src/afs/IRIX/osi_vfs.h	Sat Nov  4 05:03:23 2000
+++ openafs/src/afs/IRIX/osi_vfs.h	Thu Oct 11 17:32:19 2001
@@ -291,6 +291,9 @@
 #ifdef VNODE_TRACING
 	struct ktrace 	*v_trace;		/* trace header structure    */
 #endif
+#ifdef CKPT
+	ckpt_handle_t	v_ckpt;			/* ckpt lookup info */
+#endif
 } vnode1_t;
 
 extern struct pfdat *vnode_get_dpages(vnode_t*);
diff -r -u openafs-1.2.0/src/afs/IRIX/osi_vfsops.c openafs/src/afs/IRIX/osi_vfsops.c
--- openafs-1.2.0/src/afs/IRIX/osi_vfsops.c	Thu Jul 12 15:58:20 2001
+++ openafs/src/afs/IRIX/osi_vfsops.c	Thu Oct 11 14:08:57 2001
@@ -523,7 +523,7 @@
     register afs_int32 code = 0;
     afs_int32 ret;
 
-#if defined(AFS_SGI64_ENV) && defined(CKPT)
+#if defined(AFS_SGI64_ENV) && defined(CKPT) && !defined(_R5000_CVT_WAR)
     afs_fid2_t *afid2;
 #endif    
 
@@ -533,7 +533,7 @@
 
     *avcp = NULL;
 
-#if defined(AFS_SGI64_ENV) && defined(CKPT)
+#if defined(AFS_SGI64_ENV) && defined(CKPT) && !defined(_R5000_CVT_WAR)
     afid2 = (afs_fid2_t*)fidp;
     if (afid2->af_len == sizeof(afs_fid2_t) - sizeof(afid2->af_len)) {
 	/* It's a checkpoint restart fid. */
diff -r -u openafs-1.2.0/src/afs/IRIX/osi_vnodeops.c openafs/src/afs/IRIX/osi_vnodeops.c
--- openafs-1.2.0/src/afs/IRIX/osi_vnodeops.c	Tue Aug  7 20:03:30 2001
+++ openafs/src/afs/IRIX/osi_vnodeops.c	Fri Oct 12 09:55:06 2001
@@ -1258,7 +1258,7 @@
     return 0;
 }
 
-#if defined(AFS_SGI64_ENV) && defined(CKPT)
+#if defined(AFS_SGI64_ENV) && defined(CKPT) && !defined(_R5000_CVT_WAR)
 int afs_fid2(OSI_VC_DECL(avc), struct fid *fidp)
 {
     struct cell *tcell;
@@ -1283,10 +1283,21 @@
  * return of ENOSYS would make the code fail over to VOP_FID. We can't let
  * that happen, since we do a VN_HOLD there in the expectation that 
  * posthandle will be called to release the vnode.
+ *
+ * afs_fid2 is used to support the R5000 workarounds (_R5000_CVT_WAR)
  */
 int afs_fid2(OSI_VC_DECL(avc), struct fid *fidp)
 {
+#if defined(_R5000_CVT_WAR)
+    extern int R5000_cvt_war;
+
+    if (R5000_cvt_war)
+	return ENOSYS;
+    else
+	return EINVAL;
+#else
     return EINVAL;
+#endif
 }
 #endif /* AFS_SGI64_ENV && CKPT */
 
diff -u -r openafs/src/libafs/MakefileProto.IRIX.in openafs-1.2.0/src/libafs/MakefileProto.IRIX.in
--- openafs/src/libafs/MakefileProto.IRIX.in	Thu Oct 11 14:08:34 2001
+++ openafs-1.2.0/src/libafs/MakefileProto.IRIX.in	Mon Sep 10 23:30:49 2001
@@ -182,7 +182,7 @@
 IP19_KDEFS = -DIP19 -DEVEREST -DMP -DR4000 \
 	-mips3  -D_PAGESZ=16384 -D_MIPS3_ADDRSPACE -64
 IP20_KDEFS = -DIP20 -DR4000 -DJUMP_WAR -DBADVA_WAR -DTRITON -DUSE_PCI_PIO \
-		$(KDEFS_32)
+		-D_R5000_CVT_WAR=1 -DCKPT -D_MTEXT_VFS $(KDEFS_32)
 IP21_KDEFS = -DIP21 -DEVEREST -DMP -DTFP -TARG:processor=r8000 $(KDEFS_64)
 IP25_KDEFS = -DIP25 -DEVEREST -DMP -DR10000 -TARG:processor=r10000 $(KDEFS_64)
 IP26_KDEFS = -DIP26 -DTFP -TARG:sync=off -TARG:processor=r8000 $(KDEFS_64)