diff options
author | Mark Johnston <markj@FreeBSD.org> | 2024-10-25 17:51:16 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2024-10-25 17:51:16 +0000 |
commit | fff518117b40cbc3bca49073eed85dc725ebae4c (patch) | |
tree | ad8221baf702824ef6de6eb5c39a710257b54b13 | |
parent | b9500cbd38967686a801b1ed3ab1dd5b5b5571fb (diff) | |
download | src-fff518117b40.tar.gz src-fff518117b40.zip |
virtio_p9fs: Fix handling of a full request queue
If, when submitting a request, the virtqueue is full, we sleep until an
interrupt has fired, then restart the request. However, while sleeping
the channel lock is dropped, and in the meantime another thread may have
reset the per-channel SG list, so upon retrying we'd (re)submit whatever
happened to be left over in the previous request.
Fix the problem by rebuilding the SG list after sleeping.
Sponsored by: Klara, Inc.
-rw-r--r-- | sys/dev/virtio/p9fs/virtio_p9fs.c | 3 |
1 files changed, 1 insertions, 2 deletions
diff --git a/sys/dev/virtio/p9fs/virtio_p9fs.c b/sys/dev/virtio/p9fs/virtio_p9fs.c index cdcd9c125dbb..42f47a4f63cb 100644 --- a/sys/dev/virtio/p9fs/virtio_p9fs.c +++ b/sys/dev/virtio/p9fs/virtio_p9fs.c @@ -152,6 +152,7 @@ vt9p_request(void *handle, struct p9_req_t *req) /* Grab the channel lock*/ VT9P_LOCK(chan); +req_retry: sglist_reset(sg); /* Handle out VirtIO ring buffers */ error = sglist_append(sg, req->tc->sdata, req->tc->size); @@ -170,9 +171,7 @@ vt9p_request(void *handle, struct p9_req_t *req) } writable = sg->sg_nseg - readable; -req_retry: error = virtqueue_enqueue(vq, req, sg, readable, writable); - if (error != 0) { if (error == ENOSPC) { /* |