*BSD News Article 68758


Return to BSD News archive

Newsgroups: comp.bugs.2bsd
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!news.mira.net.au!vic.news.telstra.net!act.news.telstra.net!psgrain!newsfeed.internetmci.com!salliemae!europa.chnt.gtegsc.com!wlbr!moe!sms
From: sms@moe.2bsd.com (Steven M. Schultz)
Subject: TU81+ cache handling broken (#319)
Archive-Name: comp.bugs.2bsd
Organization: 2BSD, Simi Valley CA USA
Message-ID: <DrJ96K.Mv1@moe.2bsd.com>
Date: Fri, 17 May 1996 04:44:44 GMT
Lines: 230

Subject: TU81+ cache handling broken (#319)
Index:	sys/pdpuba/tmscp.c 2.11BSD

Description:
	The logic added to support use of the cache on TU81+ drives is
	effectively a NOP.

Repeat-By:
	On an 11/44 with a typical root filesystem a 'dump' of the root fs
	to a TU81+ without the cache enabled takes about 3 minutes.

	mt -f /dev/rmt0 cacheon

	Note that no errors are reported.

	Also note that the dump time remains at 3 minutes.

Fix:
	Thanks to Terry Kennedy for spotting the problem and providing a 44 
	that could be bounced around for testing.

	The problem was that the compiler did what I *said* rather than what
	I *meant* ;)

	In tmscp.c the code was present to enable and disable the cache but
	there were two minor 'oversights'.

	One is that:

		if ((tms->Tflags & _HASCACHE|_ONLINE) != _HASCACHE|_ONLINE)

	does *not* do what it first appears to be doing.  What was really
	desired was:

		if ((tms->Tflags & (_HASCACHE|_ONLINE)) != (_HASCACHE|_ONLINE))

	The extra parentheses make a big difference - without them the ioctl
	to enable or disable the cache is ignored without error.  Out of 
	paranoia extra parens were added in several places in the rest of 
	the driver.

	The other problem was that the '_CACHE_ON' bit (telling the driver to
	enable the cache) was being cleared during the open of the drive.  This
	was changed to make the 'cache on' bit sticky - it persists across
	device opens and closes until a 'mt -f /dev/rmt0 cacheoff' is done
	(or the appropriate 'ioctl(...,MTIOCTOP,...)' is done by any program).

	With the patch applied and the cache enabled on a TU81+ the time to
	'dump' the root filesystem was cut between 40 and 50% (between
	1min30sec and 2min instead of 3min).

	To apply this patch cut where indicated, saving to a file (/tmp/319)
	and then:

		patch -p0 < /tmp/319

	If you have cache capable drives such as the TU81+ then you will want
	to rebuild and install a new kernel:

		cd /sys/YOUR_KERNEL
		make
		mv /unix /ounix
		mv /netnix /onetnix
		mv unix /unix
		mv netnix /netnix
		chmod 744 /netnix /unix
		reboot

	You may also wish to rebuild and install the GENERIC kernel.  It is
	a good idea to keep a copy of this in /genunix in case of emergencies:

		cd /sys/GENERIC
		make
		mv unix /genunix

	As always this and previous updates to 2.11BSD are available via 
	anonymous FTP to either FTP.IIPO.GTEGSC.COM or FTP.2BSD.COM in the
	directory /pub/2.11BSD.

==========================cut here=======================
*** /sys/pdpuba/tmscp.c.old	Fri Dec 22 20:49:26 1995
--- /sys/pdpuba/tmscp.c	Tue May 14 22:53:23 1996
***************
*** 1,6 ****
  #define	TMSDEBUG	1
  
! /*	@(#)tmscp.c	1.5 (2.11BSD GTE) 1995/12/08 */
  
  #if	!defined(lint) && defined(DOSCCS)
  static	char	*sccsid = "@(#)tmscp.c	1.24	(ULTRIX)	1/21/86";
--- 1,6 ----
  #define	TMSDEBUG	1
  
! /*	@(#)tmscp.c	1.6 (2.11BSD GTE) 1996/5/14 */
  
  #if	!defined(lint) && defined(DOSCCS)
  static	char	*sccsid = "@(#)tmscp.c	1.24	(ULTRIX)	1/21/86";
***************
*** 34,39 ****
--- 34,45 ----
   * 
   * Modification History:
   *
+  * 14-May-96 - sms
+  *	Missing parens caused mtflush,mtcache,mtnocache to be always skipped.
+  *	The use cache bit was being cleared in tmscpopen(). The use cache bit
+  *	is sticky in that once set via MTCACHE it stays set until cleared by
+  *	MTNOCACHE.
+  *
   * 14-Dec-95 - sms@wlv...
   *	Success!  But the size of the driver is even more of a problem now.
   *	If the crash dump option is defined the driver could exceed the max
***************
*** 475,481 ****
  	    bzero(&mp->mscp_time, sizeof (mp->mscp_time));
  	    mp->mscp_cntdep = 0;
  	    mp->mscp_opcode = M_OP_STCON;
! 	    ((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN|TMSCP_INT;
  	    i = tmscpaddr->tmscpip;      /* initiate polling */
  	    restorseg5(seg5);
  	    return;
--- 481,487 ----
  	    bzero(&mp->mscp_time, sizeof (mp->mscp_time));
  	    mp->mscp_cntdep = 0;
  	    mp->mscp_opcode = M_OP_STCON;
! 	    ((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN|TMSCP_INT);
  	    i = tmscpaddr->tmscpip;      /* initiate polling */
  	    restorseg5(seg5);
  	    return;
***************
*** 625,631 ****
  		mp->mscp_unit = unit;		/* unit? */
  		mp->mscp_cmdref = (u_short)&tms->tms_type;
  					    /* need to sleep on something */
! 		((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN | TMSCP_INT;
  		normalseg5();
  		i = tmscpaddr->tmscpip;
  		/* 
--- 631,637 ----
  		mp->mscp_unit = unit;		/* unit? */
  		mp->mscp_cmdref = (u_short)&tms->tms_type;
  					    /* need to sleep on something */
! 		((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN | TMSCP_INT);
  		normalseg5();
  		i = tmscpaddr->tmscpip;
  		/* 
***************
*** 650,656 ****
   * such as density choices, cache presence, etc.
  */
  	tms->tms_flags = 0;
! 	tms->Tflags = _ONLINE | _INUSE;		/* Clear all other flags */
  	tmscpcommand(dev, TMS_SENSE, 1);
  	if	(!(tms->Tflags & _ONLINE))
  		goto oops;
--- 656,663 ----
   * such as density choices, cache presence, etc.
  */
  	tms->tms_flags = 0;
! 	i = tms->Tflags & _CACHE_ON;
! 	tms->Tflags = _ONLINE | _INUSE | i;	/* Clear all other flags */
  	tmscpcommand(dev, TMS_SENSE, 1);
  	if	(!(tms->Tflags & _ONLINE))
  		goto oops;
***************
*** 936,942 ****
  		mp->mscp_unit = unit;
  		dp->b_active = 2;
  		sc->sc_ctab.b_actf = dp->b_forw; /* remove from controller q */
! 		((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN|TMSCP_INT;
  		if	(tmscpaddr->tmscpsa&TMSCP_ERR)
  			log(LOG_INFO, tmscpfatalerr, sc->sc_unit,
  					TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa);
--- 943,949 ----
  		mp->mscp_unit = unit;
  		dp->b_active = 2;
  		sc->sc_ctab.b_actf = dp->b_forw; /* remove from controller q */
! 		((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN|TMSCP_INT);
  		if	(tmscpaddr->tmscpsa&TMSCP_ERR)
  			log(LOG_INFO, tmscpfatalerr, sc->sc_unit,
  					TMSUNIT(bp->b_dev), tmscpaddr->tmscpsa);
***************
*** 1039,1045 ****
  		mp->mscp_modifier |= M_MD_CLSEX;
  		}
  
! 	((Trl *)mp->mscp_dscptr)->hsh |= TMSCP_OWN|TMSCP_INT;
  	i = tmscpaddr->tmscpip;              /* initiate polling */
  	dp->b_qsize++;
  	/*
--- 1046,1052 ----
  		mp->mscp_modifier |= M_MD_CLSEX;
  		}
  
! 	((Trl *)mp->mscp_dscptr)->hsh |= (TMSCP_OWN|TMSCP_INT);
  	i = tmscpaddr->tmscpip;              /* initiate polling */
  	dp->b_qsize++;
  	/*
***************
*** 1338,1345 ****
  		case	MTFLUSH:
  		case	MTCACHE:
  		case	MTNOCACHE:
! 			if	((tms->Tflags & _HASCACHE|_ONLINE) !=
! 				 _HASCACHE|_ONLINE)
  				return(0);
  		case	MTREW:
  		case	MTOFFL:
--- 1345,1352 ----
  		case	MTFLUSH:
  		case	MTCACHE:
  		case	MTNOCACHE:
! 			if	((tms->Tflags & (_HASCACHE|_ONLINE)) !=
! 				 (_HASCACHE|_ONLINE))
  				return(0);
  		case	MTREW:
  		case	MTOFFL:
*** /VERSION.old	Wed May  8 20:44:21 1996
--- /VERSION	Wed May 15 19:58:26 1996
***************
*** 1,4 ****
! Current Patch Level: 318
  
  2.11 BSD
  ============
--- 1,4 ----
! Current Patch Level: 319
  
  2.11 BSD
  ============