Subject: Re: kern/3765: ccd mirror panic on sun4m
To: None <gnats-bugs@gnats.netbsd.org, fair@digital.clock.org>
From: Paul Kranenburg <pk@cs.few.eur.nl>
List: netbsd-bugs
Date: 06/20/1997 16:21:46
> an attempt to use a mirror ccd on NetBSD-current on sun4m
> causes the following:
>
> pmap_extract: invalid pte of type 0
> panic: dvma_mapin: null page frame
I think the twin transactions started by ccd on mirrored configurations
should wait for each other to complete. Otherwise, the original buffer
may be dismantled while the "mirrored" I/O is still in progress.
Can you give this patch a try, please?
-------------------------------------------------------------------------------
*** /usr/src/sys/dev/ccd.c Fri Jun 20 16:08:02 1997
--- ccd.c Fri Jun 20 16:09:02 1997
***************
*** 132,142 ****
--- 132,144 ----
int cb_unit; /* target unit */
int cb_comp; /* target component */
int cb_flags; /* misc. flags */
+ struct ccdbuf *cb_other; /* ptr to twin mirror buffer */
LIST_ENTRY(ccdbuf) cb_list; /* entry on freelist */
};
/* cb_flags */
#define CBF_MIRROR 0x01 /* we're for a mirror component */
+ #define CBF_WAITOTHER 0x02 /* wait for mirror component to complete */
/*
* Number of freelist buffers per component. Overridable in kernel
***************
*** 880,885 ****
--- 882,888 ----
cbp->cb_obp = bp;
cbp->cb_unit = cs->sc_unit;
cbp->cb_comp = ccdisk;
+ cbp->cb_other = NULL;
/* First buffer is dealt with. */
cbpp[0] = cbp;
***************
*** 903,908 ****
--- 906,915 ----
cbp->cb_buf.b_dev = ci2->ci_dev; /* XXX */
cbp->cb_buf.b_vp = ci2->ci_vp;
cbp->cb_comp = ci2 - cs->sc_cinfo;
+ cbp->cb_other = cbpp[0];
+ cbpp[0]->cb_other = cbp;
+ cbpp[0]->cb_flags |= CBF_WAITOTHER;
+ cbp->cb_flags |= CBF_WAITOTHER;
cbpp[1] = cbp;
}
}
***************
*** 974,979 ****
--- 981,992 ----
}
count = cbp->cb_buf.b_bcount;
cbflags = cbp->cb_flags;
+
+ if ((cbflags & CBF_WAITOTHER) != 0) {
+ if (cbp->cb_other == NULL)
+ panic("ccdiodone: other == NULL");
+ cbp->cb_other->cb_flags &= ~CBF_WAITOTHER;
+ }
CCDPUTBUF(cs, cbp);
/*
***************
*** 986,994 ****
bp->b_resid -= count;
if (bp->b_resid < 0)
panic("ccdiodone: count");
! if (bp->b_resid == 0)
ccdintr(&ccd_softc[unit], bp);
! }
splx(s);
}
--- 999,1009 ----
bp->b_resid -= count;
if (bp->b_resid < 0)
panic("ccdiodone: count");
! if (bp->b_resid == 0 && (cbflags & CBF_WAITOTHER) == 0)
ccdintr(&ccd_softc[unit], bp);
! } else if (bp->b_resid == 0 && (cbflags & CBF_WAITOTHER) == 0)
! ccdintr(&ccd_softc[unit], bp);
!
splx(s);
}