Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/virtio/block/virtio_blk.c
Show First 20 Lines • Show All 317 Lines • ▼ Show 20 Lines | vtblk_attach(device_t dev) | ||||
/* | /* | ||||
* With the current sglist(9) implementation, it is not easy | * With the current sglist(9) implementation, it is not easy | ||||
* for us to support a maximum segment size as adjacent | * for us to support a maximum segment size as adjacent | ||||
* segments are coalesced. For now, just make sure it's larger | * segments are coalesced. For now, just make sure it's larger | ||||
* than the maximum supported transfer size. | * than the maximum supported transfer size. | ||||
*/ | */ | ||||
if (virtio_with_feature(dev, VIRTIO_BLK_F_SIZE_MAX)) { | if (virtio_with_feature(dev, VIRTIO_BLK_F_SIZE_MAX)) { | ||||
if (blkcfg.size_max < MAXPHYS) { | if (blkcfg.size_max < maxphys) { | ||||
error = ENOTSUP; | error = ENOTSUP; | ||||
device_printf(dev, "host requires unsupported " | device_printf(dev, "host requires unsupported " | ||||
"maximum segment size feature\n"); | "maximum segment size feature\n"); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
} | } | ||||
sc->vtblk_max_nsegs = vtblk_maximum_segments(sc, &blkcfg); | sc->vtblk_max_nsegs = vtblk_maximum_segments(sc, &blkcfg); | ||||
▲ Show 20 Lines • Show All 283 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
device_t dev; | device_t dev; | ||||
int nsegs; | int nsegs; | ||||
dev = sc->vtblk_dev; | dev = sc->vtblk_dev; | ||||
nsegs = VTBLK_MIN_SEGMENTS; | nsegs = VTBLK_MIN_SEGMENTS; | ||||
if (virtio_with_feature(dev, VIRTIO_BLK_F_SEG_MAX)) { | if (virtio_with_feature(dev, VIRTIO_BLK_F_SEG_MAX)) { | ||||
nsegs += MIN(blkcfg->seg_max, MAXPHYS / PAGE_SIZE + 1); | nsegs += MIN(blkcfg->seg_max, maxphys / PAGE_SIZE + 1); | ||||
if (sc->vtblk_flags & VTBLK_FLAG_INDIRECT) | if (sc->vtblk_flags & VTBLK_FLAG_INDIRECT) | ||||
nsegs = MIN(nsegs, VIRTIO_MAX_INDIRECT); | nsegs = MIN(nsegs, VIRTIO_MAX_INDIRECT); | ||||
} else | } else | ||||
nsegs += 1; | nsegs += 1; | ||||
return (nsegs); | return (nsegs); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | vtblk_alloc_disk(struct vtblk_softc *sc, struct virtio_blk_config *blkcfg) | ||||
/* | /* | ||||
* The VirtIO maximum I/O size is given in terms of segments. | * The VirtIO maximum I/O size is given in terms of segments. | ||||
* However, FreeBSD limits I/O size by logical buffer size, not | * However, FreeBSD limits I/O size by logical buffer size, not | ||||
* by physically contiguous pages. Therefore, we have to assume | * by physically contiguous pages. Therefore, we have to assume | ||||
* no pages are contiguous. This may impose an artificially low | * no pages are contiguous. This may impose an artificially low | ||||
* maximum I/O size. But in practice, since QEMU advertises 128 | * maximum I/O size. But in practice, since QEMU advertises 128 | ||||
* segments, this gives us a maximum IO size of 125 * PAGE_SIZE, | * segments, this gives us a maximum IO size of 125 * PAGE_SIZE, | ||||
* which is typically greater than MAXPHYS. Eventually we should | * which is typically greater than maxphys. Eventually we should | ||||
* just advertise MAXPHYS and split buffers that are too big. | * just advertise maxphys and split buffers that are too big. | ||||
* | * | ||||
* Note we must subtract one additional segment in case of non | * Note we must subtract one additional segment in case of non | ||||
* page aligned buffers. | * page aligned buffers. | ||||
*/ | */ | ||||
dp->d_maxsize = (sc->vtblk_max_nsegs - VTBLK_MIN_SEGMENTS - 1) * | dp->d_maxsize = (sc->vtblk_max_nsegs - VTBLK_MIN_SEGMENTS - 1) * | ||||
PAGE_SIZE; | PAGE_SIZE; | ||||
if (dp->d_maxsize < PAGE_SIZE) | if (dp->d_maxsize < PAGE_SIZE) | ||||
dp->d_maxsize = PAGE_SIZE; /* XXX */ | dp->d_maxsize = PAGE_SIZE; /* XXX */ | ||||
▲ Show 20 Lines • Show All 730 Lines • Show Last 20 Lines |