QUEUE_SELECT and QUEUE_NOTIFY_OFF registers are shared between all
workers operating on the same device and operations are not atomic
Type: fix
Change-Id: Ie017b1bfc7e3b6b4e59029f45db78eeffd9f3aeb
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
virtio_log_debug (vif, "control-queue: number %u, size %u", queue_num,
queue_size);
vif->virtio_pci_func->setup_queue (vm, vif, queue_num, ptr);
virtio_log_debug (vif, "control-queue: number %u, size %u", queue_num,
queue_size);
vif->virtio_pci_func->setup_queue (vm, vif, queue_num, ptr);
+ vring->queue_notify_offset =
+ vif->notify_off_multiplier *
+ vif->virtio_pci_func->get_queue_notify_off (vm, vif, queue_num);
+ virtio_log_debug (vif, "queue-notify-offset: number %u, offset %u",
+ queue_num, vring->queue_notify_offset);
if (vif->virtio_pci_func->setup_queue (vm, vif, queue_num, ptr))
return clib_error_return (0, "error in queue address setup");
if (vif->virtio_pci_func->setup_queue (vm, vif, queue_num, ptr))
return clib_error_return (0, "error in queue address setup");
+ vring->queue_notify_offset =
+ vif->notify_off_multiplier *
+ vif->virtio_pci_func->get_queue_notify_off (vm, vif, queue_num);
+ virtio_log_debug (vif, "queue-notify-offset: number %u, offset %u",
+ queue_num, vring->queue_notify_offset);
if (common_cfg == 0 || notify == 0 || dev_cfg == 0 || isr == 0)
{
vif->virtio_pci_func = &virtio_pci_legacy_func;
if (common_cfg == 0 || notify == 0 || dev_cfg == 0 || isr == 0)
{
vif->virtio_pci_func = &virtio_pci_legacy_func;
+ vif->notify_off_multiplier = 0;
virtio_log_debug (vif, "legacy virtio pci device found");
return error;
}
virtio_log_debug (vif, "legacy virtio pci device found");
return error;
}
vif->virtio_pci_func = &virtio_pci_modern_func;
if (!pci_cfg)
vif->virtio_pci_func = &virtio_pci_modern_func;
if (!pci_cfg)
- virtio_log_debug (vif, "modern virtio pci device found");
+ {
+ virtio_log_debug (vif, "modern virtio pci device found");
+ }
+ else
+ {
+ virtio_log_debug (vif, "transitional virtio pci device found");
+ }
- virtio_log_debug (vif, "transitional virtio pci device found");
vec_foreach_index (i, vif->rxq_vrings)
{
virtio_vring_t *vring = vec_elt_at_index (vif->rxq_vrings, i);
vec_foreach_index (i, vif->rxq_vrings)
{
virtio_vring_t *vring = vec_elt_at_index (vif->rxq_vrings, i);
- if (vring->kick_fd != -1)
- close (vring->kick_fd);
if (vring->used)
{
virtio_free_rx_buffers (vm, vring);
if (vring->used)
{
virtio_free_rx_buffers (vm, vring);
vec_foreach_index (i, vif->txq_vrings)
{
virtio_vring_t *vring = vec_elt_at_index (vif->txq_vrings, i);
vec_foreach_index (i, vif->txq_vrings)
{
virtio_vring_t *vring = vec_elt_at_index (vif->txq_vrings, i);
- if (vring->kick_fd != -1)
- close (vring->kick_fd);
if (vring->used)
{
virtio_free_used_desc (vm, vring);
if (vring->used)
{
virtio_free_used_desc (vm, vring);
u8 (*setup_queue) (vlib_main_t * vm, virtio_if_t * vif, u16 queue_id,
void *p);
void (*del_queue) (vlib_main_t * vm, virtio_if_t * vif, u16 queue_id);
u8 (*setup_queue) (vlib_main_t * vm, virtio_if_t * vif, u16 queue_id,
void *p);
void (*del_queue) (vlib_main_t * vm, virtio_if_t * vif, u16 queue_id);
- void (*notify_queue) (vlib_main_t * vm, virtio_if_t * vif, u16 queue_id);
+ u16 (*get_queue_notify_off) (vlib_main_t * vm, virtio_if_t * vif,
+ u16 queue_id);
+ void (*notify_queue) (vlib_main_t * vm, virtio_if_t * vif, u16 queue_id,
+ u16 queue_notify_offset);
u16 (*set_config_irq) (vlib_main_t * vm, virtio_if_t * vif, u16 vec);
u16 (*set_queue_irq) (vlib_main_t * vm, virtio_if_t * vif, u16 vec,
u16 (*set_config_irq) (vlib_main_t * vm, virtio_if_t * vif, u16 vec);
u16 (*set_queue_irq) (vlib_main_t * vm, virtio_if_t * vif, u16 vec,
vring_avail_t *avail;
u16 desc_in_use;
u16 desc_next;
vring_avail_t *avail;
u16 desc_in_use;
u16 desc_next;
- int kick_fd;
- int call_fd;
+ union
+ {
+ struct
+ {
+ int kick_fd;
+ int call_fd;
+ };
+ u16 queue_notify_offset;
+ };
u8 buffer_pool_index;
u16 size;
u16 queue_id;
u8 buffer_pool_index;
u16 size;
u16 queue_id;
extern void virtio_set_packet_coalesce (virtio_if_t * vif);
clib_error_t *virtio_set_packet_buffering (virtio_if_t * vif, u16 size);
extern void virtio_pci_legacy_notify_queue (vlib_main_t * vm,
extern void virtio_set_packet_coalesce (virtio_if_t * vif);
clib_error_t *virtio_set_packet_buffering (virtio_if_t * vif, u16 size);
extern void virtio_pci_legacy_notify_queue (vlib_main_t * vm,
- virtio_if_t * vif, u16 queue_id);
+ virtio_if_t * vif, u16 queue_id,
+ u16 queue_notify_offset);
extern void virtio_pci_modern_notify_queue (vlib_main_t * vm,
extern void virtio_pci_modern_notify_queue (vlib_main_t * vm,
- virtio_if_t * vif, u16 queue_id);
+ virtio_if_t * vif, u16 queue_id,
+ u16 queue_notify_offset);
format_function_t format_virtio_device_name;
format_function_t format_virtio_log_name;
format_function_t format_virtio_device_name;
format_function_t format_virtio_log_name;
if (vif->type == VIRTIO_IF_TYPE_PCI)
{
if (vif->is_modern)
if (vif->type == VIRTIO_IF_TYPE_PCI)
{
if (vif->is_modern)
- virtio_pci_modern_notify_queue (vm, vif, vring->queue_id);
+ virtio_pci_modern_notify_queue (vm, vif, vring->queue_id,
+ vring->queue_notify_offset);
- virtio_pci_legacy_notify_queue (vm, vif, vring->queue_id);
+ virtio_pci_legacy_notify_queue (vm, vif, vring->queue_id,
+ vring->queue_notify_offset);
vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, &src);
}
vlib_pci_write_io_u32 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_PFN, &src);
}
+static u16
+virtio_pci_legacy_get_queue_notify_off (vlib_main_t * vm, virtio_if_t * vif,
+ u16 queue_id)
+{
+ return 0;
+}
+
inline void
virtio_pci_legacy_notify_queue (vlib_main_t * vm, virtio_if_t * vif,
inline void
virtio_pci_legacy_notify_queue (vlib_main_t * vm, virtio_if_t * vif,
+ u16 queue_id, u16 queue_notify_off)
{
vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NOTIFY,
&queue_id);
{
vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NOTIFY,
&queue_id);
.set_queue_size = virtio_pci_legacy_set_queue_num,
.setup_queue = virtio_pci_legacy_setup_queue,
.del_queue = virtio_pci_legacy_del_queue,
.set_queue_size = virtio_pci_legacy_set_queue_num,
.setup_queue = virtio_pci_legacy_setup_queue,
.del_queue = virtio_pci_legacy_del_queue,
+ .get_queue_notify_off = virtio_pci_legacy_get_queue_notify_off,
.notify_queue = virtio_pci_legacy_notify_queue,
.set_config_irq = virtio_pci_legacy_set_config_irq,
.set_queue_irq = virtio_pci_legacy_set_queue_irq,
.notify_queue = virtio_pci_legacy_notify_queue,
.set_config_irq = virtio_pci_legacy_set_config_irq,
.set_queue_irq = virtio_pci_legacy_set_queue_irq,
-virtio_pci_modern_get_queue_notify_off (virtio_if_t * vif, u16 queue_id)
+virtio_pci_modern_get_queue_notify_off (vlib_main_t * vm, virtio_if_t * vif,
+ u16 queue_id)
{
u16 queue_notify_off = 0;
virtio_pci_modern_set_queue_select (vif, queue_id);
{
u16 queue_notify_off = 0;
virtio_pci_modern_set_queue_select (vif, queue_id);
inline void
virtio_pci_modern_notify_queue (vlib_main_t * vm, virtio_if_t * vif,
inline void
virtio_pci_modern_notify_queue (vlib_main_t * vm, virtio_if_t * vif,
+ u16 queue_id, u16 queue_notify_off)
- u16 queue_notify_off =
- virtio_pci_modern_get_queue_notify_off (vif, queue_id);
virtio_pci_reg_write_u16 (vif,
VIRTIO_NOTIFICATION_OFFSET (vif) +
virtio_pci_reg_write_u16 (vif,
VIRTIO_NOTIFICATION_OFFSET (vif) +
- vif->notify_off_multiplier * queue_notify_off,
- queue_id);
+ queue_notify_off, queue_id);
.set_queue_size = virtio_pci_modern_set_queue_size,
.setup_queue = virtio_pci_modern_setup_queue,
.del_queue = virtio_pci_modern_del_queue,
.set_queue_size = virtio_pci_modern_set_queue_size,
.setup_queue = virtio_pci_modern_setup_queue,
.del_queue = virtio_pci_modern_del_queue,
+ .get_queue_notify_off = virtio_pci_modern_get_queue_notify_off,
.notify_queue = virtio_pci_modern_notify_queue,
.set_config_irq = virtio_pci_modern_set_msix_config,
.set_queue_irq = virtio_pci_modern_set_queue_msix_vector,
.notify_queue = virtio_pci_modern_notify_queue,
.set_config_irq = virtio_pci_modern_set_msix_config,
.set_queue_irq = virtio_pci_modern_set_queue_msix_vector,