the following diff make mfi(4) use 64-bit frames, and support 64-bit
dma addresses. these changes are based on freebsd's mfi(4). however,
freebsd only uses 64-bit frames 'if (sizeof(bus_addr_t)) == 8',
whereas this patch uses 64-bit frames unconditionally, for both 32-bit
and 64-bit platforms. I did it unconditionally, because it makes the
code a bit simpler.
according to my tests, this does have a slightly negative speed
impact on i386.
I've tested it with the following script.
#!/bin/sh
for i in 1 2 3
do
cd /usr/obj
sudo rm -rf *
cd /usr/src
time (make -j4 obj /dev/null 21 \
make -j4 includes /dev/null 21 \
make -j4 build /dev/null 21)
done
I ran this twice on each combination of i386/amd64, current code/with
patch. these are the results (numbers after each run are the mean
averages for that run):
i386
32-bit mfi frames (current code)
run 1
32m11.25s real33m48.65s user10m42.95s system
32m25.02s real33m51.56s user10m50.86s system
32m32.85s real33m51.49s user10m54.01s system
32m23.04s 33m50.57s 10m49.27s
run 2
32m32.08s real33m51.22s user10m49.67s system
32m26.76s real33m47.27s user10m52.08s system
32m34.42s real33m46.22s user10m51.88s system
32m31.09s 33m48.24s 10m51.21s
64-bit mfi frames (with patch)
run 1
32m39.15s real33m38.95s user10m59.97s system
32m24.67s real33m36.85s user11m6.44s system
32m25.48s real33m35.04s user11m3.67s system
32m29.76s 33m36.95s 11m3.20s
run 2
32m25.55s real33m39.58s user11m6.11s system
33m04.37s real33m34.70s user11m9.84s system
32m33.54s real33m41.38s user11m7.65s system
32m41.15s 33m38.55s 11m7.87s
amd64
32-bit mfi frames (current code)
run 1
17m43.44s real17m49.14s user 8m19.46s system
17m51.65s real17m49.07s user 8m29.63s system
17m50.89s real17m49.28s user 8m28.45s system
17m48.66s 17m49.16s 8m25.85s
run 2
17m49.82s real17m47.05s user 8m32.91s system
17m49.68s real17m51.12s user 8m27.38s system
17m51.37s real17m47.93s user 8m33.09s system
17m50.29s 17m48.70s 8m31.13s
64-bit mfi frames (with patch)
run 1
17m44.04s real17m51.22s user 8m21.02s system
17m51.86s real17m51.00s user 8m28.67s system
17m51.87s real17m50.50s user 8m30.44s system
17m49.26s 17m51.04s 8m26.71s
run 2
17m54.74s real17m54.06s user 8m29.78s system
17m53.51s real17m49.95s user 8m33.98s system
17m50.85s real17m49.76s user 8m32.85s system
17m53.03s 17m51.26s 8m32.20s
so, the question is, is the impact on i386 enough to warrant using
32-bit frames on 32-bit platforms? if so, should this be decided
at runtime or compile time?
any other thoughts?
--
jake...@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lonestar.org
Index: mfi.c
===
RCS file: /cvs/src/sys/dev/ic/mfi.c,v
retrieving revision 1.114
diff -u -p mfi.c
--- mfi.c 30 Dec 2010 08:53:50 - 1.114
+++ mfi.c 14 Mar 2011 20:05:59 -
@@ -618,7 +618,7 @@ int
mfi_attach(struct mfi_softc *sc, enum mfi_iop iop)
{
struct scsibus_attach_args saa;
- uint32_tstatus, frames;
+ uint32_tstatus, frames, max_sgl;
int i;
switch (iop) {
@@ -648,7 +648,8 @@ mfi_attach(struct mfi_softc *sc, enum mfi_iop iop)
status = mfi_fw_state(sc);
sc-sc_max_cmds = status MFI_STATE_MAXCMD_MASK;
- sc-sc_max_sgl = (status MFI_STATE_MAXSGL_MASK) 16;
+ max_sgl = (status MFI_STATE_MAXSGL_MASK) 16;
+ sc-sc_max_sgl = min(max_sgl, (128 * 1024) / PAGE_SIZE + 1);
DNPRINTF(MFI_D_MISC, %s: max commands: %u, max sgl: %u\n,
DEVNAME(sc), sc-sc_max_cmds, sc-sc_max_sgl);
@@ -662,8 +663,7 @@ mfi_attach(struct mfi_softc *sc, enum mfi_iop iop)
}
/* frame memory */
- /* we are not doing 64 bit IO so only calculate # of 32 bit frames */
- frames = (sizeof(struct mfi_sg32) * sc-sc_max_sgl +
+ frames = (sizeof(struct mfi_sgl) * sc-sc_max_sgl +
MFI_FRAME_SIZE - 1) / MFI_FRAME_SIZE + 1;
sc-sc_frames_size = frames * MFI_FRAME_SIZE;
sc-sc_frames = mfi_allocmem(sc, sc-sc_frames_size * sc-sc_max_cmds);
@@ -1105,7 +1105,7 @@ mfi_create_sgl(struct mfi_ccb *ccb, int flags)
struct mfi_softc*sc = ccb-ccb_sc;
struct mfi_frame_header *hdr;
bus_dma_segment_t *sgd;
- union mfi_sgl *sgl;
+ struct mfi_sgl *sgl;
int error, i;
DNPRINTF(MFI_D_DMA, %s: mfi_create_sgl