o Switch to use non-mergeable RX buffers to avoid mbuf adjustment needs
o Operate with copy of iov as we expect later it was not modified
This commit is contained in:
parent
02b08c9092
commit
1aac28e753
@ -138,17 +138,16 @@ static int pio_enable_irq(struct vtbe_softc *sc, int enable);
|
||||
static void
|
||||
vtbe_txstart_locked(struct vtbe_softc *sc)
|
||||
{
|
||||
struct virtio_net_hdr_mrg_rxbuf *vnh;
|
||||
struct iovec iov[DESC_COUNT];
|
||||
struct virtio_net_hdr *vnh;
|
||||
struct vqueue_info *vq;
|
||||
struct iovec *riov;
|
||||
struct iovec *tiov;
|
||||
struct ifnet *ifp;
|
||||
struct mbuf *m;
|
||||
struct uio uio;
|
||||
int enqueued;
|
||||
int iolen;
|
||||
int error;
|
||||
int *addr;
|
||||
int reg;
|
||||
int len;
|
||||
int n;
|
||||
@ -186,24 +185,16 @@ vtbe_txstart_locked(struct vtbe_softc *sc)
|
||||
|
||||
n = vq_getchain(sc->beri_mem_offset, vq, iov,
|
||||
DESC_COUNT, NULL);
|
||||
KASSERT(n == 2,
|
||||
("Unexpected amount of descriptors (%d)", n));
|
||||
|
||||
KASSERT(n >= 1 && n <= DESC_COUNT,
|
||||
("wrong descriptors num %d", n));
|
||||
|
||||
addr = iov[0].iov_base;
|
||||
len = iov[0].iov_len;
|
||||
|
||||
tiov = getcopy(iov, n);
|
||||
vnh = iov[0].iov_base;
|
||||
memset(vnh, 0, sc->hdrsize);
|
||||
vnh->num_buffers = htobe16(1);
|
||||
|
||||
iov[0].iov_len -= sc->hdrsize;
|
||||
iov[0].iov_base = (void *)((uintptr_t)iov[0].iov_base +
|
||||
sc->hdrsize);
|
||||
riov = &iov[0];
|
||||
|
||||
uio.uio_resid = iov[0].iov_len;
|
||||
uio.uio_iov = riov;
|
||||
len = iov[1].iov_len;
|
||||
uio.uio_resid = len;
|
||||
uio.uio_iov = &tiov[1];
|
||||
uio.uio_segflg = UIO_SYSSPACE;
|
||||
uio.uio_iovcnt = 1;
|
||||
uio.uio_offset = 0;
|
||||
@ -213,9 +204,10 @@ vtbe_txstart_locked(struct vtbe_softc *sc)
|
||||
if (error)
|
||||
panic("m_mbuftouio failed\n");
|
||||
|
||||
iolen = (len - iov[0].iov_len - sc->hdrsize);
|
||||
vq_relchain(vq, iov, 0, iolen + sc->hdrsize);
|
||||
paddr_unmap((void *)addr, len);
|
||||
iolen = (len - uio.uio_resid + sc->hdrsize);
|
||||
|
||||
free(tiov, M_DEVBUF);
|
||||
vq_relchain(vq, iov, n, iolen);
|
||||
|
||||
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
|
||||
|
||||
@ -391,6 +383,7 @@ static void
|
||||
vtbe_proc_rx(struct vtbe_softc *sc, struct vqueue_info *vq)
|
||||
{
|
||||
struct iovec iov[DESC_COUNT];
|
||||
struct iovec *tiov;
|
||||
struct ifnet *ifp;
|
||||
struct uio uio;
|
||||
struct mbuf *m;
|
||||
@ -406,13 +399,15 @@ vtbe_proc_rx(struct vtbe_softc *sc, struct vqueue_info *vq)
|
||||
KASSERT(n >= 1 && n <= DESC_COUNT,
|
||||
("wrong n %d", n));
|
||||
|
||||
tiov = getcopy(iov, n);
|
||||
|
||||
iolen = 0;
|
||||
for (i = 1; i < n; i++) {
|
||||
iolen += iov[i].iov_len;
|
||||
}
|
||||
|
||||
uio.uio_resid = iolen;
|
||||
uio.uio_iov = &iov[1];
|
||||
uio.uio_iov = &tiov[1];
|
||||
uio.uio_segflg = UIO_SYSSPACE;
|
||||
uio.uio_iovcnt = (n - 1);
|
||||
uio.uio_rw = UIO_WRITE;
|
||||
@ -434,6 +429,7 @@ vtbe_proc_rx(struct vtbe_softc *sc, struct vqueue_info *vq)
|
||||
CURVNET_RESTORE();
|
||||
|
||||
done:
|
||||
free(tiov, M_DEVBUF);
|
||||
vq_relchain(vq, iov, n, iolen + sc->hdrsize);
|
||||
}
|
||||
|
||||
@ -569,7 +565,7 @@ vtbe_attach(device_t dev)
|
||||
sc = device_get_softc(dev);
|
||||
sc->dev = dev;
|
||||
|
||||
sc->hdrsize = sizeof(struct virtio_net_hdr_mrg_rxbuf);
|
||||
sc->hdrsize = sizeof(struct virtio_net_hdr);
|
||||
|
||||
if (bus_alloc_resources(dev, vtbe_spec, sc->res)) {
|
||||
device_printf(dev, "could not allocate resources\n");
|
||||
@ -602,7 +598,6 @@ vtbe_attach(device_t dev)
|
||||
|
||||
/* Our features */
|
||||
reg = htobe32(VIRTIO_NET_F_MAC |
|
||||
VIRTIO_NET_F_MRG_RXBUF |
|
||||
VIRTIO_F_NOTIFY_ON_EMPTY);
|
||||
WRITE4(sc, VIRTIO_MMIO_HOST_FEATURES, reg);
|
||||
|
||||
|
@ -186,7 +186,7 @@ vq_relchain(struct vqueue_info *vq, struct iovec *iov, int n, uint32_t iolen)
|
||||
vu->idx = htobe16(uidx);
|
||||
|
||||
/* Clean up */
|
||||
for (i = 1; i < (n-1); i++) {
|
||||
for (i = 0; i < n; i++) {
|
||||
paddr_unmap((void *)iov[i].iov_base, iov[i].iov_len);
|
||||
}
|
||||
}
|
||||
@ -244,3 +244,17 @@ setup_offset(device_t dev, uint32_t *offset)
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct iovec *
|
||||
getcopy(struct iovec *iov, int n)
|
||||
{
|
||||
struct iovec *tiov;
|
||||
int i;
|
||||
|
||||
tiov = malloc(n * sizeof(struct iovec), M_DEVBUF, M_NOWAIT);
|
||||
for (i = 0; i < n; i++) {
|
||||
tiov[i].iov_base = iov[i].iov_base;
|
||||
tiov[i].iov_len = iov[i].iov_len;
|
||||
}
|
||||
|
||||
return (tiov);
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ void paddr_unmap(void *phys, uint32_t size);
|
||||
int vq_getchain(uint32_t beri_mem_offset, struct vqueue_info *vq,
|
||||
struct iovec *iov, int n_iov, uint16_t *flags);
|
||||
void vq_relchain(struct vqueue_info *vq, struct iovec *iov, int n, uint32_t iolen);
|
||||
struct iovec * getcopy(struct iovec *iov, int n);
|
||||
|
||||
int setup_pio(device_t dev, char *name, device_t *pio_dev);
|
||||
int setup_offset(device_t dev, uint32_t *offset);
|
||||
|
@ -151,6 +151,7 @@ vtblk_proc(struct beri_vtblk_softc *sc, struct vqueue_info *vq)
|
||||
struct iovec iov[VTBLK_MAXSEGS + 2];
|
||||
uint16_t flags[VTBLK_MAXSEGS + 2];
|
||||
struct virtio_blk_outhdr *vbh;
|
||||
struct iovec *tiov;
|
||||
uint8_t *status;
|
||||
off_t offset;
|
||||
int iolen;
|
||||
@ -160,10 +161,10 @@ vtblk_proc(struct beri_vtblk_softc *sc, struct vqueue_info *vq)
|
||||
|
||||
n = vq_getchain(sc->beri_mem_offset, vq, iov,
|
||||
VTBLK_MAXSEGS + 2, flags);
|
||||
|
||||
KASSERT(n >= 2 && n <= VTBLK_MAXSEGS + 2,
|
||||
("wrong n value %d", n));
|
||||
|
||||
tiov = getcopy(iov, n);
|
||||
vbh = iov[0].iov_base;
|
||||
|
||||
status = iov[n-1].iov_base;
|
||||
@ -181,7 +182,7 @@ vtblk_proc(struct beri_vtblk_softc *sc, struct vqueue_info *vq)
|
||||
switch (type) {
|
||||
case VIRTIO_BLK_T_OUT:
|
||||
case VIRTIO_BLK_T_IN:
|
||||
err = vtblk_rdwr(sc, iov + 1, i - 1,
|
||||
err = vtblk_rdwr(sc, tiov + 1, i - 1,
|
||||
offset, type, iolen);
|
||||
break;
|
||||
case VIRTIO_BLK_T_GET_ID:
|
||||
@ -205,6 +206,7 @@ vtblk_proc(struct beri_vtblk_softc *sc, struct vqueue_info *vq)
|
||||
} else
|
||||
*status = VIRTIO_BLK_S_OK;
|
||||
|
||||
free(tiov, M_DEVBUF);
|
||||
vq_relchain(vq, iov, n, 1);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user