From patchwork Wed Jun 24 12:26:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Coquelin X-Patchwork-Id: 72119 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 667C0A0350; Wed, 24 Jun 2020 14:27:46 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 098941D90F; Wed, 24 Jun 2020 14:27:46 +0200 (CEST) Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) by dpdk.org (Postfix) with ESMTP id D48EB1D8E6 for ; Wed, 24 Jun 2020 14:27:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1593001664; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=68QcTanHSzHP12mvXkrAg2vpOPs3CD1O7gu5Dc/GPOs=; b=AuSodxrKAiwYsdY14lvRlUg9aRgVMbwFNKXNVsIENDt1IKzaX52fN+TTU0psecsfiCB6xt 230T9xY2pO93UHzSMByTVx0KVWjRrP+TcH7m2MbHLu+P2ZnQmjCB49eQSSozNkgRu+GjPA jue4hZ7Drb3KxEUCQcDuCRkfE8H7m6g= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-204-xOxrAdySN7ivdONMlsEIsw-1; Wed, 24 Jun 2020 08:27:38 -0400 X-MC-Unique: xOxrAdySN7ivdONMlsEIsw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 264C4107B7C8; Wed, 24 Jun 2020 12:27:37 +0000 (UTC) Received: from localhost.localdomain (unknown [10.36.110.7]) by smtp.corp.redhat.com (Postfix) with ESMTP id 088ED1C4; Wed, 24 Jun 2020 12:27:31 +0000 (UTC) From: Maxime Coquelin To: matan@mellanox.com, xiao.w.wang@intel.com, zhihong.wang@intel.com, chenbo.xia@intel.com, david.marchand@redhat.com, amorenoz@redhat.com, viacheslavo@mellanox.com, hemant.agrawal@nxp.com, sachin.saxena@nxp.com, grive@u256.net, dev@dpdk.org Cc: Maxime Coquelin Date: Wed, 24 Jun 2020 14:26:47 +0200 Message-Id: <20200624122701.1369327-4-maxime.coquelin@redhat.com> In-Reply-To: <20200624122701.1369327-1-maxime.coquelin@redhat.com> References: <20200624122701.1369327-1-maxime.coquelin@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [dpdk-dev] [PATCH v2 03/14] vhost: introduce vDPA devices class 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" This patch introduces vDPA device class. It will enable application to iterate over the vDPA devices. Signed-off-by: Maxime Coquelin Acked-by: Adrián Moreno --- lib/librte_vhost/vdpa.c | 115 +++++++++++++++++++++++++++++++++------- 1 file changed, 97 insertions(+), 18 deletions(-) diff --git a/lib/librte_vhost/vdpa.c b/lib/librte_vhost/vdpa.c index 1f5cdcd64b..a429841691 100644 --- a/lib/librte_vhost/vdpa.c +++ b/lib/librte_vhost/vdpa.c @@ -10,11 +10,12 @@ #include +#include #include #include "rte_vdpa.h" #include "vhost.h" -static struct rte_vdpa_device *vdpa_devices[MAX_VHOST_DEVICE]; +static struct rte_vdpa_device vdpa_devices[MAX_VHOST_DEVICE]; static uint32_t vdpa_device_num; static bool @@ -46,35 +47,28 @@ rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr, struct rte_vdpa_dev_ops *ops) { struct rte_vdpa_device *dev; - char device_name[MAX_VDPA_NAME_LEN]; int i; if (vdpa_device_num >= MAX_VHOST_DEVICE || addr == NULL || ops == NULL) return -1; for (i = 0; i < MAX_VHOST_DEVICE; i++) { - dev = vdpa_devices[i]; - if (dev && is_same_vdpa_device(&dev->addr, addr)) + dev = &vdpa_devices[i]; + if (dev->ops && is_same_vdpa_device(&dev->addr, addr)) return -1; } for (i = 0; i < MAX_VHOST_DEVICE; i++) { - if (vdpa_devices[i] == NULL) + if (vdpa_devices[i].ops == NULL) break; } if (i == MAX_VHOST_DEVICE) return -1; - snprintf(device_name, sizeof(device_name), "vdpa-dev-%d", i); - dev = rte_zmalloc(device_name, sizeof(struct rte_vdpa_device), - RTE_CACHE_LINE_SIZE); - if (!dev) - return -1; - + dev = &vdpa_devices[i]; memcpy(&dev->addr, addr, sizeof(struct rte_vdpa_dev_addr)); dev->ops = ops; - vdpa_devices[i] = dev; vdpa_device_num++; return i; @@ -83,11 +77,10 @@ rte_vdpa_register_device(struct rte_vdpa_dev_addr *addr, int rte_vdpa_unregister_device(int did) { - if (did < 0 || did >= MAX_VHOST_DEVICE || vdpa_devices[did] == NULL) + if (did < 0 || did >= MAX_VHOST_DEVICE || vdpa_devices[did].ops == NULL) return -1; - rte_free(vdpa_devices[did]); - vdpa_devices[did] = NULL; + memset(&vdpa_devices[did], 0, sizeof(struct rte_vdpa_device)); vdpa_device_num--; return did; @@ -103,8 +96,11 @@ rte_vdpa_find_device_id(struct rte_vdpa_dev_addr *addr) return -1; for (i = 0; i < MAX_VHOST_DEVICE; ++i) { - dev = vdpa_devices[i]; - if (dev && is_same_vdpa_device(&dev->addr, addr)) + dev = &vdpa_devices[i]; + if (dev->ops == NULL) + continue; + + if (is_same_vdpa_device(&dev->addr, addr)) return i; } @@ -117,7 +113,7 @@ rte_vdpa_get_device(int did) if (did < 0 || did >= MAX_VHOST_DEVICE) return NULL; - return vdpa_devices[did]; + return &vdpa_devices[did]; } int @@ -274,3 +270,86 @@ rte_vdpa_reset_stats(int did, uint16_t qid) return vdpa_dev->ops->reset_stats(did, qid); } + +static uint16_t +vdpa_dev_to_id(const struct rte_vdpa_device *dev) +{ + if (dev == NULL) + return MAX_VHOST_DEVICE; + + if (dev < &vdpa_devices[0] || + dev >= &vdpa_devices[MAX_VHOST_DEVICE]) + return MAX_VHOST_DEVICE; + + return (uint16_t)(dev - vdpa_devices); +} + +static int +vdpa_dev_match(struct rte_vdpa_device *dev, + const struct rte_device *rte_dev) +{ + struct rte_vdpa_dev_addr addr; + + /* Only PCI bus supported for now */ + if (strcmp(rte_dev->bus->name, "pci") != 0) + return -1; + + addr.type = VDPA_ADDR_PCI; + + if (rte_pci_addr_parse(rte_dev->name, &addr.pci_addr) != 0) + return -1; + + if (!is_same_vdpa_device(&dev->addr, &addr)) + return -1; + + return 0; +} + +/* Generic rte_vdpa_dev comparison function. */ +typedef int (*rte_vdpa_cmp_t)(struct rte_vdpa_device *, + const struct rte_device *rte_dev); + +static struct rte_vdpa_device * +vdpa_find_device(const struct rte_vdpa_device *start, rte_vdpa_cmp_t cmp, + struct rte_device *rte_dev) +{ + struct rte_vdpa_device *dev; + uint16_t idx; + + if (start != NULL) + idx = vdpa_dev_to_id(start) + 1; + else + idx = 0; + for (; idx < MAX_VHOST_DEVICE; idx++) { + dev = &vdpa_devices[idx]; + /* + * ToDo: Certainly better to introduce a state field, + * but rely on ops being set for now. + */ + if (dev->ops == NULL) + continue; + if (cmp(dev, rte_dev) == 0) + return dev; + } + return NULL; +} + +static void * +vdpa_dev_iterate(const void *start, + const char *str, + const struct rte_dev_iterator *it) +{ + struct rte_vdpa_device *vdpa_dev = NULL; + + RTE_SET_USED(str); + + vdpa_dev = vdpa_find_device(start, vdpa_dev_match, it->device); + + return vdpa_dev; +} + +static struct rte_class rte_class_vdpa = { + .dev_iterate = vdpa_dev_iterate, +}; + +RTE_REGISTER_CLASS(vdpa, rte_class_vdpa);