virtio: fix modern device queue notify
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>
This commit is contained in:

committed by
Beno�t Ganne

parent
d68faf8559
commit
162a296756
@@ -486,7 +486,11 @@ virtio_pci_control_vring_init (vlib_main_t * vm, virtio_if_t * vif,
|
||||
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->kick_fd = -1;
|
||||
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);
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -562,7 +566,11 @@ virtio_pci_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 queue_num)
|
||||
if (vif->virtio_pci_func->setup_queue (vm, vif, queue_num, ptr))
|
||||
return clib_error_return (0, "error in queue address setup");
|
||||
|
||||
vring->kick_fd = -1;
|
||||
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);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -775,6 +783,7 @@ virtio_pci_read_caps (vlib_main_t * vm, virtio_if_t * vif, void **bar)
|
||||
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;
|
||||
}
|
||||
@@ -783,9 +792,14 @@ virtio_pci_read_caps (vlib_main_t * vm, virtio_if_t * vif, void **bar)
|
||||
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");
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1244,8 +1258,6 @@ virtio_pci_delete_if (vlib_main_t * vm, virtio_if_t * vif)
|
||||
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);
|
||||
@@ -1257,8 +1269,6 @@ virtio_pci_delete_if (vlib_main_t * vm, virtio_if_t * vif)
|
||||
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);
|
||||
|
@@ -195,7 +195,10 @@ typedef struct _virtio_pci_func
|
||||
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,
|
||||
|
@@ -66,8 +66,15 @@ typedef struct
|
||||
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;
|
||||
@@ -208,9 +215,11 @@ extern void virtio_show (vlib_main_t * vm, u32 * hw_if_indices, u8 show_descr,
|
||||
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,
|
||||
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;
|
||||
|
||||
@@ -220,9 +229,11 @@ virtio_kick (vlib_main_t * vm, virtio_vring_t * vring, virtio_if_t * vif)
|
||||
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);
|
||||
else
|
||||
virtio_pci_legacy_notify_queue (vm, vif, vring->queue_id);
|
||||
virtio_pci_legacy_notify_queue (vm, vif, vring->queue_id,
|
||||
vring->queue_notify_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -203,9 +203,16 @@ virtio_pci_legacy_del_queue (vlib_main_t * vm, virtio_if_t * vif,
|
||||
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,
|
||||
u16 queue_id)
|
||||
u16 queue_id, u16 queue_notify_off)
|
||||
{
|
||||
vlib_pci_write_io_u16 (vm, vif->pci_dev_handle, VIRTIO_PCI_QUEUE_NOTIFY,
|
||||
&queue_id);
|
||||
@@ -364,6 +371,7 @@ const virtio_pci_func_t virtio_pci_legacy_func = {
|
||||
.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,
|
||||
|
@@ -208,7 +208,8 @@ virtio_pci_modern_set_queue_enable (virtio_if_t * vif, u16 queue_id,
|
||||
}
|
||||
|
||||
static u16
|
||||
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);
|
||||
@@ -387,14 +388,11 @@ virtio_pci_modern_get_isr (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_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) +
|
||||
vif->notify_off_multiplier * queue_notify_off,
|
||||
queue_id);
|
||||
queue_notify_off, queue_id);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -418,6 +416,7 @@ const virtio_pci_func_t virtio_pci_modern_func = {
|
||||
.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,
|
||||
|
Reference in New Issue
Block a user