diff --git a/src/virtio-console.cpp b/src/virtio-console.cpp index da3b63a4..86f7b3c4 100644 --- a/src/virtio-console.cpp +++ b/src/virtio-console.cpp @@ -68,7 +68,7 @@ bool virtio_console::write_next_chars_to_host(i_device_state_access *a, uint32_t os_putchars(chunk.data(), chunk_len); } // Consume the queue and notify the driver - if (!consume_and_notify_queue(a, queue_idx, desc_idx)) { + if (!consume_queue(a, queue_idx, desc_idx)) { notify_device_needs_reset(a); return false; } @@ -106,10 +106,12 @@ bool virtio_console::write_next_chars_to_guest(i_device_state_access *a) { return false; } // Consume the queue and notify the driver - if (!consume_and_notify_queue(a, queue_idx, desc_idx, chunk_len, VIRTQ_USED_F_NO_NOTIFY)) { + if (!consume_queue(a, queue_idx, desc_idx, chunk_len, VIRTQ_USED_F_NO_NOTIFY)) { notify_device_needs_reset(a); return false; } + // After consuming a queue, we must notify the driver right-away + notify_queue_used(a); return true; } diff --git a/src/virtio-device.cpp b/src/virtio-device.cpp index cfc41a2c..ed365de0 100644 --- a/src/virtio-device.cpp +++ b/src/virtio-device.cpp @@ -438,24 +438,19 @@ bool virtio_device::prepare_queue_write(i_device_state_access *a, uint32_t queue return true; } -bool virtio_device::consume_and_notify_queue(i_device_state_access *a, uint32_t queue_idx, uint16_t desc_idx, - uint32_t written_len, uint16_t used_flags) { +bool virtio_device::consume_queue(i_device_state_access *a, uint32_t queue_idx, uint16_t desc_idx, uint32_t written_len, + uint16_t used_flags) { // A device MUST NOT consume buffers or send any used buffer notifications to the driver before DRIVER_OK. assert(driver_ok); assert(queue_idx < VIRTIO_QUEUE_COUNT); +#ifdef DEBUG_VIRTIO + std::ignore = fprintf(stderr, "virtio[%d]: consume_queue queue_idx=%d desc_idx=%d written_len=%d\n", virtio_idx, + queue_idx, desc_idx, written_len); +#endif // Retrieve queue virtq &vq = queue[queue_idx]; // Consume the buffer, so the driver is free to reuse it again - if (!vq.consume_desc(a, desc_idx, written_len, used_flags)) { - return false; - } -#ifdef DEBUG_VIRTIO - std::ignore = fprintf(stderr, "virtio[%d]: consume_and_notify_queue queue_idx=%d desc_idx=%d written_len=%d\n", - virtio_idx, queue_idx, desc_idx, written_len); -#endif - // After consuming a queue, we must notify the driver right-away - notify_queue_used(a); - return true; + return vq.consume_desc(a, desc_idx, written_len, used_flags); } void virtio_device::on_device_queue_notify(i_device_state_access *a, uint32_t queue_idx) { diff --git a/src/virtio-device.h b/src/virtio-device.h index 70edc497..d7ab76ce 100644 --- a/src/virtio-device.h +++ b/src/virtio-device.h @@ -314,14 +314,14 @@ class virtio_device { bool prepare_queue_write(i_device_state_access *a, uint32_t queue_idx, uint16_t *pdesc_idx, uint32_t *pwrite_avail_len) const; - /// Consume an available queue's descriptor (sets it as used) and notify the driver. + /// Consume an available queue's descriptor (sets it as used). /// \param queue_idx Queue index to consume and notify. /// \param desc_idx Queue's available descriptor index to set as used. /// \param written_len Amount of bytes written to the descriptor buffer. /// \param used_flags Used flags, see virtq_used_flags. /// \returns True if there are no errors, false otherwise. - bool consume_and_notify_queue(i_device_state_access *a, uint32_t queue_idx, uint16_t desc_idx, - uint32_t written_len = 0, uint16_t used_flags = 0); + bool consume_queue(i_device_state_access *a, uint32_t queue_idx, uint16_t desc_idx, uint32_t written_len = 0, + uint16_t used_flags = 0); /// \brief Called when driver request a device reset, this function must clean-up all device internal state. virtual void on_device_reset() = 0; diff --git a/src/virtio-net.cpp b/src/virtio-net.cpp index 59030d6f..f114f748 100644 --- a/src/virtio-net.cpp +++ b/src/virtio-net.cpp @@ -94,7 +94,7 @@ bool virtio_net::write_next_packet_to_host(i_device_state_access *a, uint32_t qu return false; } // Consume the queue and notify the driver - if (!consume_and_notify_queue(a, queue_idx, desc_idx)) { + if (!consume_queue(a, queue_idx, desc_idx)) { notify_device_needs_reset(a); return false; } @@ -137,10 +137,12 @@ bool virtio_net::read_next_packet_from_host(i_device_state_access *a) { return false; } // Consume and notify the queue - if (!consume_and_notify_queue(a, queue_idx, desc_idx, written_len)) { + if (!consume_queue(a, queue_idx, desc_idx, written_len)) { notify_device_needs_reset(a); return false; } + // After consuming a queue, we must notify the driver right-away + notify_queue_used(a); return true; } diff --git a/src/virtio-p9fs.cpp b/src/virtio-p9fs.cpp index eadeb10b..ad0d9f5b 100644 --- a/src/virtio-p9fs.cpp +++ b/src/virtio-p9fs.cpp @@ -2468,10 +2468,12 @@ bool virtio_p9fs_device::send_reply(virtq_serializer &&mout_msg, uint16_t tag, p return false; } // Consume the queue and notify the driver - if (!consume_and_notify_queue(out_msg.a, out_msg.queue_idx, out_msg.desc_idx, out_msg.length, 0)) { + if (!consume_queue(out_msg.a, out_msg.queue_idx, out_msg.desc_idx, out_msg.length, 0)) { notify_device_needs_reset(out_msg.a); return false; } + // After consuming a queue, we must notify the driver right-away + notify_queue_used(out_msg.a); return true; }