From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 14A19A00BE; Thu, 11 Jun 2020 23:38:31 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 558F01150; Thu, 11 Jun 2020 23:38:20 +0200 (CEST) Received: from us-smtp-delivery-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) by dpdk.org (Postfix) with ESMTP id BECAC2BAB for ; Thu, 11 Jun 2020 23:38:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1591911498; 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=jOnNThCjz6d7NBUm2WkjXkRUcEcNnMlUprmypFIi68E=; b=B6xZIxq17uMU4QfiaKWxxU6ONKy4SN9MM7iNRw7k/fkoMTO1+y79ndtRc7TezNxrcr7HU3 ve0Q5LYlZgbMDUfdEKP5yh3e4RzoI4GJ9vBlsQ+r/+sGMwIljFCJw+g6JPpgyLQGLv/wuu PsrOw0vcvDnVjsVZpsMQI5eDs0NK5N4= 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-442-JKT1wA7JPQColIvlGFIMQA-1; Thu, 11 Jun 2020 17:38:14 -0400 X-MC-Unique: JKT1wA7JPQColIvlGFIMQA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9A083461; Thu, 11 Jun 2020 21:38:12 +0000 (UTC) Received: from localhost.localdomain (unknown [10.36.110.37]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9D4EA1001B0B; Thu, 11 Jun 2020 21:38:09 +0000 (UTC) From: Maxime Coquelin To: dev@dpdk.org, matan@mellanox.com, xiao.w.wang@intel.com, zhihong.wang@intel.com, xiaolong.ye@intel.com, chenbo.xia@intel.com, david.marchand@redhat.com, amorenoz@redhat.com, shreyansh.jain@nxp.com, viacheslavo@mellanox.com, hemant.agrawal@nxp.com, sachin.saxena@nxp.com Cc: Maxime Coquelin Date: Thu, 11 Jun 2020 23:37:37 +0200 Message-Id: <20200611213748.1967029-4-maxime.coquelin@redhat.com> In-Reply-To: <20200611213748.1967029-1-maxime.coquelin@redhat.com> References: <20200611213748.1967029-1-maxime.coquelin@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH 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 --- lib/librte_vhost/vdpa.c | 116 +++++++++++++++++++++++++++++++++------- 1 file changed, 98 insertions(+), 18 deletions(-) diff --git a/lib/librte_vhost/vdpa.c b/lib/librte_vhost/vdpa.c index b2b2a105f1..61ab9aadb4 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 @@ -227,3 +223,87 @@ rte_vdpa_relay_vring_used(int vid, uint16_t qid, void *vring_m) free_ind_table(idesc); return -1; } + +static uint16_t +vdpa_dev_to_id(const struct rte_vdpa_device *dev) +{ + if (dev == NULL) + return MAX_VHOST_DEVICE; + return 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; + ptrdiff_t idx; + + /* Avoid Undefined Behaviour */ + if (start != NULL && + (start < &vdpa_devices[0] || + start >= &vdpa_devices[MAX_VHOST_DEVICE])) + return NULL; + + 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); -- 2.26.2