]> git.droids-corp.org - dpdk.git/commitdiff
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 954989efc03ea9ad581ec59eeb30d1b4ee6176d9..e6b537b17f80e05168a29d02c677ebf33f97c7ff 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 994458ced2e6bb43efb04ca068da5851ef347c96..265debf203eea73778683d1be529e625c4087886 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 ca546ccaa9cbe1d3ba5c0988c94f1a9b5ab3dcdb..49e9d98eeca81ccc9ce93d00c62cc2283953fb63 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);