From patchwork Thu Aug 29 07:59:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Coquelin X-Patchwork-Id: 58230 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 0E6981DFF0; Thu, 29 Aug 2019 10:01:02 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id B82491D17E; Thu, 29 Aug 2019 10:00:59 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 151E510F23E8; Thu, 29 Aug 2019 08:00:59 +0000 (UTC) Received: from localhost.localdomain (ovpn-112-52.ams2.redhat.com [10.36.112.52]) by smtp.corp.redhat.com (Postfix) with ESMTP id ABDD95D6B2; Thu, 29 Aug 2019 08:00:56 +0000 (UTC) From: Maxime Coquelin To: tiwei.bie@intel.com, zhihong.wang@intel.com, amorenoz@redhat.com, xiao.w.wang@intel.com, dev@dpdk.org, jfreimann@redhat.com Cc: stable@dpdk.org, Maxime Coquelin Date: Thu, 29 Aug 2019 09:59:57 +0200 Message-Id: <20190829080000.20806-13-maxime.coquelin@redhat.com> In-Reply-To: <20190829080000.20806-1-maxime.coquelin@redhat.com> References: <20190829080000.20806-1-maxime.coquelin@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.66]); Thu, 29 Aug 2019 08:00:59 +0000 (UTC) Subject: [dpdk-dev] [PATCH 12/15] net/virtio: add vDPA op to set features X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" On top of that, it allocates the control virtqueue if multiqueue has been negotiated. Signed-off-by: Maxime Coquelin --- drivers/net/virtio/virtio_vdpa.c | 155 +++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/drivers/net/virtio/virtio_vdpa.c b/drivers/net/virtio/virtio_vdpa.c index 691844906..9b61688a1 100644 --- a/drivers/net/virtio/virtio_vdpa.c +++ b/drivers/net/virtio/virtio_vdpa.c @@ -521,12 +521,167 @@ virtio_vdpa_dev_close(int vid) return 0; } + +static void +virtio_vdpa_free_ctrl_vq(struct virtio_vdpa_device *dev) +{ + if (!dev->cvq) + return; + + rte_memzone_free(dev->cvq->cq.virtio_net_hdr_mz); + rte_memzone_free(dev->cvq->cq.mz); + rte_free(dev->cvq); + + dev->hw.cvq = NULL; +} + +static int +virtio_vdpa_allocate_ctrl_vq(struct virtio_vdpa_device *dev) +{ + struct virtio_hw *hw = &dev->hw; + char vq_name[VIRTQUEUE_MAX_NAME_SZ]; + char vq_hdr_name[VIRTQUEUE_MAX_NAME_SZ]; + int numa_node = dev->pdev->device.numa_node; + const struct rte_memzone *mz = NULL, *hdr_mz = NULL; + uint16_t ctrl_queue_idx = dev->max_queue_pairs * 2; + uint16_t ctrl_queue_sz; + int size, ret; + + if (dev->cvq) + virtio_vdpa_free_ctrl_vq(dev); + + ctrl_queue_sz = VTPCI_OPS(hw)->get_queue_num(hw, ctrl_queue_idx); + if (ctrl_queue_sz == 0) { + DRV_LOG(ERR, "Ctrl VQ does not exist"); + return -EINVAL; + } + + dev->cvq = rte_zmalloc_socket(vq_name, sizeof(*dev->cvq), + RTE_CACHE_LINE_SIZE, numa_node); + if (!dev->cvq) + return -ENOMEM; + + dev->cvq->hw = &dev->hw; + dev->cvq->vq_queue_index = ctrl_queue_idx; + dev->cvq->vq_nentries = ctrl_queue_sz; + + if (vtpci_packed_queue(hw)) { + dev->cvq->vq_packed.used_wrap_counter = 1; + dev->cvq->vq_packed.cached_flags = VRING_PACKED_DESC_F_AVAIL; + dev->cvq->vq_packed.event_flags_shadow = 0; + } + + size = vring_size(hw, ctrl_queue_sz, VIRTIO_PCI_VRING_ALIGN); + dev->cvq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN); + + snprintf(vq_name, sizeof(vq_name), "vdpa_ctrlvq%d", + dev->did); + + mz = rte_memzone_reserve_aligned(vq_name, dev->cvq->vq_ring_size, + numa_node, RTE_MEMZONE_IOVA_CONTIG, + VIRTIO_PCI_VRING_ALIGN); + if (mz == NULL) { + if (rte_errno == EEXIST) + mz = rte_memzone_lookup(vq_name); + if (mz == NULL) { + ret = -ENOMEM; + goto out_free_cvq; + } + } + + memset(mz->addr, 0, mz->len); + dev->cvq->vq_ring_virt_mem = mz->addr; + + virtio_init_vring(dev->cvq); + + snprintf(vq_hdr_name, sizeof(vq_hdr_name), "vdpa_ctrlvq%d_hdr", + dev->did); + + hdr_mz = rte_memzone_reserve_aligned(vq_hdr_name, PAGE_SIZE * 2, + numa_node, RTE_MEMZONE_IOVA_CONTIG, + VIRTIO_PCI_VRING_ALIGN); + if (hdr_mz == NULL) { + if (rte_errno == EEXIST) + hdr_mz = rte_memzone_lookup(vq_hdr_name); + if (hdr_mz == NULL) { + ret = -ENOMEM; + goto out_free_mz; + } + } + + memset(hdr_mz->addr, 0, hdr_mz->len); + + dev->cvq->cq.vq = dev->cvq; + dev->cvq->cq.mz = mz; + dev->cvq->cq.virtio_net_hdr_mz = hdr_mz; + dev->hw.cvq = &dev->cvq->cq; + + return 0; + +out_free_mz: + rte_memzone_free(mz); +out_free_cvq: + rte_free(dev->cvq); + dev->cvq = NULL; + + return ret; +} + +static int +virtio_vdpa_set_features(int vid) +{ + uint64_t features; + int did, ret; + struct internal_list *list; + struct virtio_vdpa_device *dev; + struct virtio_hw *hw; + + did = rte_vhost_get_vdpa_device_id(vid); + list = find_internal_resource_by_did(did); + if (list == NULL) { + DRV_LOG(ERR, "Invalid device id: %d", did); + return -1; + } + + dev = list->dev; + hw = &dev->hw; + rte_vhost_get_negotiated_features(vid, &features); + + features |= (1ULL << VIRTIO_F_IOMMU_PLATFORM); + if (dev->has_ctrl_vq) + features |= (1ULL << VIRTIO_NET_F_CTRL_VQ); + + VTPCI_OPS(&dev->hw)->set_features(&dev->hw, features); + hw->guest_features = features; + + if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) { + if (vtpci_with_feature(hw, VIRTIO_NET_F_MQ)) { + vtpci_read_dev_config(hw, + offsetof(struct virtio_net_config, + max_virtqueue_pairs), + &dev->max_queue_pairs, + sizeof(dev->max_queue_pairs)); + } else { + dev->max_queue_pairs = 1; + } + + ret = virtio_vdpa_allocate_ctrl_vq(dev); + if (ret) { + DRV_LOG(ERR, "Failed to allocate ctrl vq"); + return ret; + } + } + + return 0; +} + static struct rte_vdpa_dev_ops virtio_vdpa_ops = { .get_queue_num = virtio_vdpa_get_queue_num, .get_features = virtio_vdpa_get_features, .get_protocol_features = virtio_vdpa_get_protocol_features, .dev_conf = virtio_vdpa_dev_config, .dev_close = virtio_vdpa_dev_close, + .set_features = virtio_vdpa_set_features, }; static inline int