net/virtio: make control queue thread-safe
authorXiao Wang <xiao.w.wang@intel.com>
Wed, 10 Jan 2018 01:23:52 +0000 (09:23 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 16 Jan 2018 17:47:49 +0000 (18:47 +0100)
The virtio_send_command function may be called from app's configuration
routine, but also from an interrupt handler called when live migration
is done on the backup side. So this patch makes control queue
thread-safe first.

Signed-off-by: Xiao Wang <xiao.w.wang@intel.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
drivers/net/virtio/virtio_ethdev.c
drivers/net/virtio/virtio_rxtx.c
drivers/net/virtio/virtio_rxtx.h

index 954989e..e6b537b 100644 (file)
@@ -151,6 +151,8 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
                PMD_INIT_LOG(ERR, "Control queue is not supported.");
                return -1;
        }
+
+       rte_spinlock_lock(&cvq->lock);
        vq = cvq->vq;
        head = vq->vq_desc_head_idx;
 
@@ -158,8 +160,10 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
                "vq->hw->cvq = %p vq = %p",
                vq->vq_desc_head_idx, status, vq->hw->cvq, vq);
 
-       if ((vq->vq_free_cnt < ((uint32_t)pkt_num + 2)) || (pkt_num < 1))
+       if (vq->vq_free_cnt < pkt_num + 2 || pkt_num < 1) {
+               rte_spinlock_unlock(&cvq->lock);
                return -1;
+       }
 
        memcpy(cvq->virtio_net_hdr_mz->addr, ctrl,
                sizeof(struct virtio_pmd_ctrl));
@@ -235,6 +239,7 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
 
        result = cvq->virtio_net_hdr_mz->addr;
 
+       rte_spinlock_unlock(&cvq->lock);
        return result->status;
 }
 
index 994458c..265debf 100644 (file)
@@ -378,6 +378,7 @@ virtio_dev_cq_start(struct rte_eth_dev *dev)
        struct virtio_hw *hw = dev->data->dev_private;
 
        if (hw->cvq && hw->cvq->vq) {
+               rte_spinlock_init(&hw->cvq->lock);
                VIRTQUEUE_DUMP((struct virtqueue *)hw->cvq->vq);
        }
 }
index ca546cc..49e9d98 100644 (file)
@@ -55,6 +55,7 @@ struct virtnet_ctl {
        rte_iova_t virtio_net_hdr_mem;  /**< hdr for each xmit packet */
        uint16_t port_id;               /**< Device port identifier. */
        const struct rte_memzone *mz;   /**< mem zone to populate CTL ring. */
+       rte_spinlock_t lock;              /**< spinlock for control queue. */
 };
 
 int virtio_rxq_vec_setup(struct virtnet_rx *rxvq);