NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/38273 panic: LOCKDEBUG, "lockdebug_barrier: spin lock held", from ld_ataraid_start_raid0()
The following reply was made to PR kern/38273; it has been noted by GNATS.
From: Juan RP <xtraeme%gmail.com@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc:
Subject: Re: kern/38273 panic: LOCKDEBUG,
"lockdebug_barrier: spin lock held", from ld_ataraid_start_raid0()
Date: Wed, 17 Sep 2008 16:58:17 +0200
Hi,
please try this patch. I've built a NetBSD/amd64 full release with
src on RAID0 and obj/destdir/tools on RAID1 with ataraid(4)
successfully with all debugging options enabled.
$ dmesg|grep 'ld[0-9]'
ld0 at ataraid0 vendtype 5 unit 0: Intel MatrixRAID ATA RAID-0 array
ld0: 233 GB, 30416 cyl, 255 head, 63 sec, 512 bytes/sect x 488636416 sectors
ld1 at ataraid0 vendtype 5 unit 1: Intel MatrixRAID ATA RAID-1 array
ld1: 117 GB, 15306 cyl, 255 head, 63 sec, 512 bytes/sect x 245905408 sectors
$
/dev/ld0a 226G 1.0G 214G 0% /mnt/raid0
/dev/ld1a 114G 949M 107G 0% /mnt/raid1
Index: ld_ataraid.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ld_ataraid.c,v
retrieving revision 1.32
diff -b -u -p -r1.32 ld_ataraid.c
--- ld_ataraid.c 16 Sep 2008 11:45:30 -0000 1.32
+++ ld_ataraid.c 17 Sep 2008 13:13:08 -0000
@@ -90,6 +90,12 @@ struct ld_ataraid_softc {
struct vnode *sc_vnodes[ATA_RAID_MAX_DISKS];
void (*sc_iodone)(struct buf *);
+
+ pool_cache_t sc_cbufpool;
+
+ SIMPLEQ_HEAD(, cbuf) sc_cbufq;
+
+ void *sc_sih_cookie;
};
static int ld_ataraid_match(struct device *, struct cfdata *, void *);
@@ -97,6 +103,10 @@ static void ld_ataraid_attach(struct dev
static int ld_ataraid_dump(struct ld_softc *, void *, int, int);
+static int cbufpool_ctor(void *, void *, int);
+static void cbufpool_dtor(void *, void *);
+
+static void ld_ataraid_start_vstrategy(void *);
static int ld_ataraid_start_span(struct ld_softc *, struct buf *);
static int ld_ataraid_start_raid0(struct ld_softc *, struct buf *);
@@ -113,9 +123,6 @@ static int ld_ataraid_biodisk(struct ld_
CFATTACH_DECL_NEW(ld_ataraid, sizeof(struct ld_ataraid_softc),
ld_ataraid_match, ld_ataraid_attach, NULL, NULL);
-static int ld_ataraid_initialized;
-static struct pool ld_ataraid_cbufpl;
-
struct cbuf {
struct buf cb_buf; /* new I/O buf */
struct buf *cb_obp; /* ptr. to original I/O buf */
@@ -127,8 +134,8 @@ struct cbuf {
#define CBUF_IODONE 0x00000001 /* I/O is already successfully
done */
};
-#define CBUF_GET() pool_get(&ld_ataraid_cbufpl, PR_NOWAIT);
-#define CBUF_PUT(cbp) pool_put(&ld_ataraid_cbufpl, (cbp))
+#define CBUF_GET() pool_cache_get(sc->sc_cbufpool, PR_NOWAIT);
+#define CBUF_PUT(cbp) pool_cache_put(sc->sc_cbufpool, (cbp))
static int
ld_ataraid_match(device_t parent, cfdata_t match, void *aux)
@@ -151,11 +158,10 @@ ld_ataraid_attach(device_t parent, devic
ld->sc_dv = self;
- if (ld_ataraid_initialized == 0) {
- ld_ataraid_initialized = 1;
- pool_init(&ld_ataraid_cbufpl, sizeof(struct cbuf), 0,
- 0, 0, "ldcbuf", NULL, IPL_BIO);
- }
+ sc->sc_cbufpool = pool_cache_init(sizeof(struct cbuf), 0,
+ 0, 0, "ldcbuf", NULL, IPL_BIO, cbufpool_ctor, cbufpool_dtor, sc);
+ sc->sc_sih_cookie = softint_establish(SOFTINT_BIO,
+ ld_ataraid_start_vstrategy, sc);
sc->sc_aai = aai; /* this data persists */
@@ -246,9 +252,33 @@ ld_ataraid_attach(device_t parent, devic
panic("%s: bioctl registration failed\n",
device_xname(ld->sc_dv));
#endif
+ SIMPLEQ_INIT(&sc->sc_cbufq);
ldattach(ld);
}
+static int
+cbufpool_ctor(void *arg, void *obj, int flags)
+{
+ struct ld_ataraid_softc *sc = arg;
+ struct ld_softc *ld = &sc->sc_ld;
+ struct cbuf *cbp = obj;
+
+ /* We release/reacquire the spinlock before calling buf_init() */
+ mutex_exit(&ld->sc_mutex);
+ buf_init(&cbp->cb_buf);
+ mutex_enter(&ld->sc_mutex);
+
+ return 0;
+}
+
+static void
+cbufpool_dtor(void *arg, void *obj)
+{
+ struct cbuf *cbp = obj;
+
+ buf_destroy(&cbp->cb_buf);
+}
+
static struct cbuf *
ld_ataraid_make_cbuf(struct ld_ataraid_softc *sc, struct buf *bp,
u_int comp, daddr_t bn, void *addr, long bcount)
@@ -257,8 +287,7 @@ ld_ataraid_make_cbuf(struct ld_ataraid_s
cbp = CBUF_GET();
if (cbp == NULL)
- return (NULL);
- buf_init(&cbp->cb_buf);
+ return NULL;
cbp->cb_buf.b_flags = bp->b_flags;
cbp->cb_buf.b_oflags = bp->b_oflags;
cbp->cb_buf.b_cflags = bp->b_cflags;
@@ -277,7 +306,24 @@ ld_ataraid_make_cbuf(struct ld_ataraid_s
cbp->cb_other = NULL;
cbp->cb_flags = 0;
- return (cbp);
+ return cbp;
+}
+
+static void
+ld_ataraid_start_vstrategy(void *arg)
+{
+ struct ld_ataraid_softc *sc = arg;
+ struct cbuf *cbp;
+
+ while ((cbp = SIMPLEQ_FIRST(&sc->sc_cbufq)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_cbufq, cb_q);
+ if ((cbp->cb_buf.b_flags & B_READ) == 0) {
+ mutex_enter(&cbp->cb_buf.b_vp->v_interlock);
+ cbp->cb_buf.b_vp->v_numoutput++;
+ mutex_exit(&cbp->cb_buf.b_vp->v_interlock);
+ }
+ VOP_STRATEGY(cbp->cb_buf.b_vp, &cbp->cb_buf);
+ }
}
static int
@@ -286,7 +332,6 @@ ld_ataraid_start_span(struct ld_softc *l
struct ld_ataraid_softc *sc = (void *) ld;
struct ataraid_array_info *aai = sc->sc_aai;
struct ataraid_disk_info *adi;
- SIMPLEQ_HEAD(, cbuf) cbufq;
struct cbuf *cbp;
char *addr;
daddr_t bn;
@@ -294,7 +339,6 @@ ld_ataraid_start_span(struct ld_softc *l
u_int comp;
/* Allocate component buffers. */
- SIMPLEQ_INIT(&cbufq);
addr = bp->b_data;
/* Find the first component. */
@@ -316,12 +360,11 @@ ld_ataraid_start_span(struct ld_softc *l
cbp = ld_ataraid_make_cbuf(sc, bp, comp, bn, addr, rcount);
if (cbp == NULL) {
/* Free the already allocated component buffers. */
- while ((cbp = SIMPLEQ_FIRST(&cbufq)) != NULL) {
- SIMPLEQ_REMOVE_HEAD(&cbufq, cb_q);
- buf_destroy(&cbp->cb_buf);
+ while ((cbp = SIMPLEQ_FIRST(&sc->sc_cbufq)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_cbufq, cb_q);
CBUF_PUT(cbp);
}
- return (EAGAIN);
+ return EAGAIN;
}
/*
@@ -331,31 +374,22 @@ ld_ataraid_start_span(struct ld_softc *l
adi = &aai->aai_disks[++comp];
bn = 0;
- SIMPLEQ_INSERT_TAIL(&cbufq, cbp, cb_q);
+ SIMPLEQ_INSERT_TAIL(&sc->sc_cbufq, cbp, cb_q);
addr += rcount;
}
/* Now fire off the requests. */
- while ((cbp = SIMPLEQ_FIRST(&cbufq)) != NULL) {
- SIMPLEQ_REMOVE_HEAD(&cbufq, cb_q);
- if ((cbp->cb_buf.b_flags & B_READ) == 0) {
- mutex_enter(&cbp->cb_buf.b_vp->v_interlock);
- cbp->cb_buf.b_vp->v_numoutput++;
- mutex_exit(&cbp->cb_buf.b_vp->v_interlock);
- }
- VOP_STRATEGY(cbp->cb_buf.b_vp, &cbp->cb_buf);
- }
+ softint_schedule(sc->sc_sih_cookie);
- return (0);
+ return 0;
}
static int
ld_ataraid_start_raid0(struct ld_softc *ld, struct buf *bp)
{
- struct ld_ataraid_softc *sc = (void *) ld;
+ struct ld_ataraid_softc *sc = (void *)ld;
struct ataraid_array_info *aai = sc->sc_aai;
struct ataraid_disk_info *adi;
- SIMPLEQ_HEAD(, cbuf) cbufq;
struct cbuf *cbp, *other_cbp;
char *addr;
daddr_t bn, cbn, tbn, off;
@@ -363,10 +397,9 @@ ld_ataraid_start_raid0(struct ld_softc *
u_int comp;
const int read = bp->b_flags & B_READ;
const int mirror = aai->aai_level & AAI_L_RAID1;
- int error;
+ int error = 0;
/* Allocate component buffers. */
- SIMPLEQ_INIT(&cbufq);
addr = bp->b_data;
bn = bp->b_rawblkno;
@@ -417,14 +450,13 @@ resource_shortage:
error = EAGAIN;
free_and_exit:
/* Free the already allocated component buffers. */
- while ((cbp = SIMPLEQ_FIRST(&cbufq)) != NULL) {
- SIMPLEQ_REMOVE_HEAD(&cbufq, cb_q);
- buf_destroy(&cbp->cb_buf);
+ while ((cbp = SIMPLEQ_FIRST(&sc->sc_cbufq)) != NULL) {
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_cbufq, cb_q);
CBUF_PUT(cbp);
}
- return (error);
+ return error;
}
- SIMPLEQ_INSERT_TAIL(&cbufq, cbp, cb_q);
+ SIMPLEQ_INSERT_TAIL(&sc->sc_cbufq, cbp, cb_q);
if (mirror && !read && comp < aai->aai_width) {
comp += aai->aai_width;
adi = &aai->aai_disks[comp];
@@ -433,7 +465,8 @@ free_and_exit:
comp, cbn, addr, rcount);
if (other_cbp == NULL)
goto resource_shortage;
- SIMPLEQ_INSERT_TAIL(&cbufq, other_cbp, cb_q);
+ SIMPLEQ_INSERT_TAIL(&sc->sc_cbufq,
+ other_cbp, cb_q);
other_cbp->cb_other = cbp;
cbp->cb_other = other_cbp;
}
@@ -443,17 +476,9 @@ free_and_exit:
}
/* Now fire off the requests. */
- while ((cbp = SIMPLEQ_FIRST(&cbufq)) != NULL) {
- SIMPLEQ_REMOVE_HEAD(&cbufq, cb_q);
- if ((cbp->cb_buf.b_flags & B_READ) == 0) {
- mutex_enter(&cbp->cb_buf.b_vp->v_interlock);
- cbp->cb_buf.b_vp->v_numoutput++;
- mutex_exit(&cbp->cb_buf.b_vp->v_interlock);
- }
- VOP_STRATEGY(cbp->cb_buf.b_vp, &cbp->cb_buf);
- }
+ softint_schedule(sc->sc_sih_cookie);
- return (0);
+ return error;
}
/*
@@ -530,7 +555,6 @@ ld_ataraid_iodone_raid0(struct buf *vbp)
other_cbp->cb_flags |= CBUF_IODONE;
}
count = cbp->cb_buf.b_bcount;
- buf_destroy(&cbp->cb_buf);
CBUF_PUT(cbp);
if (other_cbp != NULL)
---- END ----
Home |
Main Index |
Thread Index |
Old Index