NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/58049: vioif(4) panics if the virtq size is too small
The following reply was made to PR kern/58049; it has been noted by GNATS.
From: Tetsuya Isaki <isaki%pastel-flower.jp@localhost>
To: Jason Thorpe <thorpej%me.com@localhost>
Cc: kern-bug-people%netbsd.org@localhost,
gnats-admin%netbsd.org@localhost,
netbsd-bugs%netbsd.org@localhost,
gnats-bugs%netbsd.org@localhost
Subject: Re: kern/58049: vioif(4) panics if the virtq size is too small
Date: Wed, 20 Mar 2024 12:44:25 +0900
At Mon, 18 Mar 2024 08:51:45 -0700,
Jason Thorpe wrote:
> When the DMA map is created, do we not yet know the max number of
> segments? Or is the problem that different queues might have
> different segment counts and the DMA maps are shared between them?
> In a perfect world, this extra test isn't needed because the bus_dma
> back-end honors the device's maximum segment count.
Thank you for comment.
I have found the cause of this problem. This is the revised patch.
--- src/sys/dev/pci/if_vioif.c
+++ src/sys/dev/pci/if_vioif.c
@@ -1280,12 +1280,14 @@ vioif_alloc_mems(struct vioif_softc *sc)
struct virtio_net_hdr *hdrs;
int dir;
+ int nsegs;
dir = VIOIF_NETQ_DIR(qid);
netq = &sc->sc_netqs[qid];
vq_num = netq->netq_vq->vq_num;
maps = netq->netq_maps;
hdrs = netq->netq_maps_kva;
+ nsegs = uimin(dmaparams[dir].dma_nsegs, vq_num - 1/*hdr*/);
for (i = 0; i < vq_num; i++) {
maps[i].vnm_hdr = &hdrs[i];
@@ -1297,7 +1299,7 @@ vioif_alloc_mems(struct vioif_softc *sc)
goto err_reqs;
r = vioif_dmamap_create(sc, &maps[i].vnm_mbuf_map,
- dmaparams[dir].dma_size, dmaparams[dir].dma_nsegs,
+ dmaparams[dir].dma_size, nsegs,
dmaparams[dir].msg_payload);
if (r != 0)
goto err_reqs;
vioif_net_load_mbuf() (in vioif_send_common_locked()) loaded more
than 8 segments(fragments) despite (my) virtio queue size was 8.
So I tried to defragment in the previous patch. But it was not
correct as you pointed out.
This is because vioif_alloc_mems() told bus_dma that it was able to
handle up to hardcoded VIRTIO_NET_TX_MAXNSEGS (=16) segments during
initialization, despite my virtio queue size was 8(!).
If the virtq size is less than or equal to VIRTIO_NET_TX_MAXNSEGS,
the max number of dmamap segments for payload must be virtq size - 1.
Thanks,
---
Tetsuya Isaki <isaki%pastel-flower.jp@localhost / isaki%NetBSD.org@localhost>
Home |
Main Index |
Thread Index |
Old Index