Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Mar 2000 10:02:24 -0700 (MST)
From:      Nate Williams <nate@yogotech.com>
To:        freebsd-bugs@FreeBSD.org
Subject:   Fwd: GNATS request
Message-ID:  <200003111702.KAA02135@nomad.yogotech.com>

next in thread | raw e-mail | index | archive | help
This was sent to the CVS bugs mailing list for some reason..
------- start of forwarded message -------
From: jan@vandenbosch.org
To: bug-cvs@gnu.org
Subject: Unidentified subject!
Date: Sat, 11 Mar 2000 16:34:58 +0100 (CET)

>Submitter-Id:   net
>Originator: 	 Jan van den Bosch
>Organization:	 net
>Confidential:  no
>Synopsis:	Archive QIC02 tape-unit device randomly halts.
>Severity:	serious
>Priority:	low 
>Category: 	cvs
>Class:		sw-bug
>Release:	cvs-1.10
>Environment:
    	
System: FreeBSD jvdbgw.icts.tue.nl 3.2-RELEASE FreeBSD 3.2-RELEASE #24: Wed Mar 8 23:00:02 CET 2000 jan@jvdbgw.icts.tue.nl:/usr/src/sys/compile/XANTOS i386


>Description:

The wt QIC02 tapedriver in thwe FreeBSD 3.x has a nice bug (could be
also in NetBSD and other BSD's ???)
The wt driver sometimes comes in a deadlock state (waiting for an 
wake-up event that never occurs). It may happen when you are doing 
longer backups on - I assume - some "slow" PC's like mine. 
The backup does not finish correctly, it "hangs".
The code is in /sys/i386/isa/wt.c.
The solution is simple. After changing it,
the bug never occurred (to me) again. 

Reason:
In the Interrupt routine wtintr() there is no provision for 
stopping the timeout() if all i/o (one block) is completed
(state 'i/o finished'). If an interrupt is generated at this moment,
it comes in an unexpected state ('continue i/o'). In this state,
there is of course no wakeup, so it keeps sleeping ... 

Patch:
*Allways put the timer off* if i/o is finished.
Add this line in the function body of wtintr(sc):
	untimeout(wtimer, (caddr_t)t, t->co_handler);

Remark:
In NetBSD ther is no call-out handler, the patch is even
more simple.

>How-To-Repeat:

Problem shows up every time I was making a longer backup, 
on my old 486 PC system.
(May be on a fast system it does not occure, because it is a timing problem)

>Fix:

----context diff, patch in /sys/i386/isa directory:

*** wt.c	Wed Mar  8 22:57:56 2000
--- wt.c.orig	Fri Sep 10 10:29:44 1999
***************
*** 165,174 ****
  #ifdef	DEVFS
  	void	*devfs_token_r;
  #endif
- 	/* JVDB added 03082000 */
- 	struct callout_handle co_handler;
- 		/* Callout handler for receiving & UNSETTING timeouts */
- 	/**/
  } wtinfo_t;
  
  static wtinfo_t wttab[NWT];                    /* tape info by unit number */
--- 165,170 ----
***************
*** 259,267 ****
  {
  	wtinfo_t *t = wttab + id->id_unit;
  
- /* JVDB inserted 03082000  */
- 	callout_handle_init(&t->co_handler);    /* installing callout */
- /**/
  	id->id_ointr = wtintr;
  	if (t->type == ARCHIVE) {
  		printf ("wt%d: type <Archive>\n", t->unit);
--- 255,260 ----
***************
*** 272,278 ****
  	t->dens = -1;                           /* unknown density */
  	isa_dmainit(t->chan, 1024);
  
- 
  #ifdef DEVFS
  	t->devfs_token_r = 
  		devfs_add_devswf(&wt_cdevsw, id->id_unit, DV_CHR, 0, 0, 
--- 265,270 ----
***************
*** 440,448 ****
  		((struct mtget*)arg)->mt_resid = 0;
  		((struct mtget*)arg)->mt_fileno = 0;            /* file */
  		((struct mtget*)arg)->mt_blkno = 0;             /* block */
- 		/* JVDB added 231294 */
- 		((struct mtget*)arg)->mt_density = t->dens;    /* density */
- 		/**/
  		return (0);
  	case MTIOCTOP:
  		break;
--- 432,437 ----
***************
*** 458,474 ****
  	case MTNOCACHE:         /* disable controller cache */
  		return (0);
  	case MTREW:             /* rewind */
  		if (t->flags & TPREW)   /* rewind is running */
  			return (0);
  		if (error = wtwait (t, PCATCH, "wtorew"))
  			return (error);
  		wtrewind (t);
  		return (0);
- 	case MTOFFL:            /* JVDB  put the drive offline */
- 				/* actually do a reset ...*/
- 		wtreset(t);
- 		return 0;
- 		/**/
  	case MTFSF:             /* forward space file */
  		for (count=((struct mtop*)arg)->mt_count; count>0; --count) {
  			if (error = wtwait (t, PCATCH, "wtorfm"))
--- 447,459 ----
  	case MTNOCACHE:         /* disable controller cache */
  		return (0);
  	case MTREW:             /* rewind */
+ 	case MTOFFL:            /* rewind and put the drive offline */
  		if (t->flags & TPREW)   /* rewind is running */
  			return (0);
  		if (error = wtwait (t, PCATCH, "wtorew"))
  			return (error);
  		wtrewind (t);
  		return (0);
  	case MTFSF:             /* forward space file */
  		for (count=((struct mtop*)arg)->mt_count; count>0; --count) {
  			if (error = wtwait (t, PCATCH, "wtorfm"))
***************
*** 680,689 ****
  			t->flags |= TPVOL;      /* end of file */
  		else
  			t->flags |= TPEXCEP;    /* i/o error */
- 	/* JVDB added 03082000 */
- 		/* stop timer going off !!!!*/
- 		untimeout(wtimer, (caddr_t)t, t->co_handler);
- 	/**/
  		wakeup ((caddr_t)t);
  		return;
  	}
--- 665,670 ----
***************
*** 695,704 ****
  	}
  	if (t->dmacount > t->dmatotal)          /* short last block */
  		t->dmacount = t->dmatotal;
- 	/* JVDB added 03082000 */
- 		/* stop time going off !!!!*/
- 		untimeout(wtimer, t, t->co_handler);
- 	/**/
  	wakeup ((caddr_t)t);	/* wake up user level */
  	TRACE (("i/o finished, %d\n", t->dmacount));
  }
--- 676,681 ----
***************
*** 867,875 ****
  		t->flags |= TPTIMER;
  		/* Some controllers seem to lose dma interrupts too often.
  		 * To make the tape stream we need 1 tick timeout. */
- 		/** JVDB added 03082000; set the handler */
- 		t->co_handler = 
- 		/**/
  		timeout (wtimer, (caddr_t)t, (t->flags & TPACTIVE) ? 1 : hz);
  	}
  }
--- 844,849 ----

--QAA00903.952787866/jvdbgw.icts.tue.nl--


------- end of forwarded message -------


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200003111702.KAA02135>