DragonFly bugs List (threaded) for 2007-07
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
Re: ccd on NATA problem - ata0: FAILURE - oversized DMA transfer attempt 73728 > 65536
:IIUC, in old-ATA, ad_strategy took care of transfer sizes larger than
:the maximum I/O size of the device, but not in NATA (I guess GEOM layer
:is handling it, right?). Adjusting si_iosize_max (initially faked to
:be 131072 when attached) in ccdinit() seems to work around this problem.
:
:Cheers.
There's even an XXX comment next to that assignment. At the time
that assignment is made the CCD hasn't loaded its components yet
so we do not know what the actual limitations are.
CCD has an iterator in ccdstart() to deal with components. I think
what we need to do is to add some logic to ccdbuffer() to incorporate
the limits of the lower level device.
So, please try this patch. I've included a kprintf() so we can get
positive confirmation that it actually does what it is supposed to.
The advantage of this patch is that it does not artificially limit
the max iosize for the CCD request itself. e.g. if a person happens
to configure an interleave of 64K across two disks CCD which are
each limited to 64K I/O's, CCD will still process a 128K I/O in
parallel.
Please note this patch is almost completely untested.
-Matt
Index: sys/ccdvar.h
===================================================================
RCS file: /cvs/src/sys/sys/ccdvar.h,v
retrieving revision 1.6
diff -u -p -r1.6 ccdvar.h
--- sys/ccdvar.h 17 May 2007 03:20:11 -0000 1.6
+++ sys/ccdvar.h 9 Jul 2007 17:29:55 -0000
@@ -206,6 +206,7 @@ int sc_flags; /* flags */
int sc_cflags; /* configuration flags */
u_int64_t sc_size; /* size of ccd in sectors */
int sc_ileave; /* interleave */
+ int sc_maxiosize; /* maximum I/O size */
u_int sc_nccdisks; /* number of components */
#define CCD_MAXNDISKS 65536
struct ccdcinfo *sc_cinfo; /* component info */
Index: dev/disk/ccd/ccd.c
===================================================================
RCS file: /cvs/src/sys/dev/disk/ccd/ccd.c,v
retrieving revision 1.48
diff -u -p -r1.48 ccd.c
--- dev/disk/ccd/ccd.c 19 Jun 2007 19:09:46 -0000 1.48
+++ dev/disk/ccd/ccd.c 9 Jul 2007 17:42:52 -0000
@@ -398,6 +398,7 @@
/* Allocate space for the component info. */
cs->sc_cinfo = kmalloc(cs->sc_nccdisks * sizeof(struct ccdcinfo),
M_DEVBUF, M_WAITOK);
+ cs->sc_maxiosize = MAXPHYS;
/*
* Verify that each component piece exists and record
@@ -427,6 +428,10 @@ ci->ci_path = kmalloc(ci->ci_pathlen,
bcopy(tmppath, ci->ci_path, ci->ci_pathlen);
ci->ci_dev = vn_todev(vp);
+ if (ci->ci_dev->si_iosize_max &&
+ cs->sc_maxiosize > ci->ci_dev->si_iosize_max) {
+ cs->sc_maxiosize = ci->ci_dev->si_iosize_max;
+ }
/*
* Get partition information for the component.
@@ -489,6 +494,8 @@ ci->ci_skip = skip;
ci->ci_size = size;
cs->sc_size += size;
}
+ kprintf("ccd%d: max component iosize is %d\n",
+ cs->sc_unit, cs->sc_maxiosize);
/*
* Don't allow the interleave to be smaller than
@@ -1048,9 +1055,11 @@ cbp->cb_buf.b_flags |= bio->bio_buf->b_
cbp->cb_buf.b_data = addr;
cbp->cb_vp = ci->ci_vp;
if (cs->sc_ileave == 0)
- cbc = dbtob((off_t)(ci->ci_size - cbn));
+ cbc = dbtob((off_t)(ci->ci_size - cbn));
else
- cbc = dbtob((off_t)(cs->sc_ileave - cboff));
+ cbc = dbtob((off_t)(cs->sc_ileave - cboff));
+ if (cbc > cs->sc_maxiosize)
+ cbc = cs->sc_maxiosize;
cbp->cb_buf.b_bcount = (cbc < bcount) ? cbc : bcount;
cbp->cb_buf.b_bufsize = cbp->cb_buf.b_bcount;
@@ -1090,6 +1099,8 @@ if (cs->sc_ileave == 0)
cbc = dbtob((off_t)(ci->ci_size - cbn));
else
cbc = dbtob((off_t)(cs->sc_ileave - cboff));
+ if (cbc > cs->sc_maxiosize)
+ cbc = cs->sc_maxiosize;
cbp->cb_buf.b_bcount = (cbc < bcount) ? cbc : bcount;
cbp->cb_buf.b_bufsize = cbp->cb_buf.b_bcount;
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]