From patchwork Mon Sep 27 13:42:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srikanth Kaka X-Patchwork-Id: 99819 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C06A2A0C46; Mon, 27 Sep 2021 17:00:41 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 91FDA4118B; Mon, 27 Sep 2021 16:58:32 +0200 (CEST) Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) by mails.dpdk.org (Postfix) with ESMTP id 0A3DF40E3C for ; Mon, 27 Sep 2021 15:43:05 +0200 (CEST) Received: by mail-pl1-f172.google.com with SMTP id j15so10382771plh.7 for ; Mon, 27 Sep 2021 06:43:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oneconvergence.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=g+TV0cKT7Na0B4z9tOAoOFjxNzWuMF94m/xPrFGaCYU=; b=EB0bq80CTOIniufFJkdu+l/BeoZ8/esTkS9iQ87jySj/MUtWKA96Ue5oXMoBhIBcbE wKr2iWwgLjS0gkal5o1fORDJ9vP16WrDvurJ2WaR1yTgaP7OE6OaHQT+mrjZGqdX9hyE o7iIKCa4kB2wPft24J9yH+xaY6itEEqP9i0fc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=g+TV0cKT7Na0B4z9tOAoOFjxNzWuMF94m/xPrFGaCYU=; b=JQCX3hX7jA55uD6y2+F9kpJYMsp2MfI2uLAzkn6KOqwU2T09VSTBYneB/qNSwhLtAr Pi4K2fuQ5xbsF1V/WSg6AVexo9xZOVN+X0LrY+IPus5Lu3SOHpoecGuCjqKdJKCrSrOX bAjihKzuQc3GGMNkdK5Ehd4aeSTZmNwOwDm17Xrf0JQAwsoY4Z7mx6znf5cTymbBqiW0 NNYDBB7n29SBgH5fDaMNLWydZfuyOgo72myozeROcY9dTTQkUHq0LZDjYhMleqXY1ggs WuiYIQgN7f2aFq0iqagcjuxD7CEQs7axIXFm/F3lYjgOSdNfamzCM/VNCaRca6+tO37b A+8A== X-Gm-Message-State: AOAM530WLN6aWdIYDPJLcAauqmmqXmOaPESM2NZ3KKh1OFfNWTJjQJqk x9C19bRHphsv8sNioY7F6EFF/Q== X-Google-Smtp-Source: ABdhPJyICNyi+C5LSHtpxTK+Vy14tEVeZT1s17hVzqGYp7DOslkKGGQ4TuaybgcGZ9qkalzDToQJLw== X-Received: by 2002:a17:902:8509:b0:13d:cef8:2735 with SMTP id bj9-20020a170902850900b0013dcef82735mr22770772plb.22.1632750184124; Mon, 27 Sep 2021 06:43:04 -0700 (PDT) Received: from srikanth-ThinkPad-T450.domain.name ([223.178.22.200]) by smtp.gmail.com with ESMTPSA id b3sm16960665pfo.23.2021.09.27.06.43.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 06:43:03 -0700 (PDT) From: Srikanth Kaka To: Stephen Hemminger , Long Li Cc: dev@dpdk.org, Vag Singh , Anand Thulasiram , Srikanth Kaka Date: Mon, 27 Sep 2021 19:12:22 +0530 Message-Id: <20210927134231.11177-3-srikanth.k@oneconvergence.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210927134231.11177-1-srikanth.k@oneconvergence.com> References: <20210927134231.11177-1-srikanth.k@oneconvergence.com> MIME-Version: 1.0 X-Mailman-Approved-At: Mon, 27 Sep 2021 16:58:07 +0200 Subject: [dpdk-dev] [PATCH 02/11] bus/vmbus: scan and get the network device X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Using sysctl, all the devices on the VMBUS are identified by the PMD. On finding the Network device's device id, it is added to VMBUS dev list. Signed-off-by: Srikanth Kaka Signed-off-by: Vag Singh Signed-off-by: Anand Thulasiram --- drivers/bus/vmbus/freebsd/vmbus_bus.c | 241 +++++++++++++++----------- 1 file changed, 144 insertions(+), 97 deletions(-) diff --git a/drivers/bus/vmbus/freebsd/vmbus_bus.c b/drivers/bus/vmbus/freebsd/vmbus_bus.c index 3c924eee14..8eb428a154 100644 --- a/drivers/bus/vmbus/freebsd/vmbus_bus.c +++ b/drivers/bus/vmbus/freebsd/vmbus_bus.c @@ -22,8 +22,9 @@ #include "eal_filesystem.h" #include "private.h" -/** Pathname of VMBUS devices directory. */ -#define SYSFS_VMBUS_DEVICES "/sys/bus/vmbus/devices" +#include +#include +#include /* * GUID associated with network devices @@ -39,44 +40,15 @@ static const rte_uuid_t vmbus_nic_uuid = { extern struct rte_vmbus_bus rte_vmbus_bus; -/* Read sysfs file to get UUID */ +/* Parse UUID */ static int parse_sysfs_uuid(const char *filename, rte_uuid_t uu) { - char buf[BUFSIZ]; - char *cp, *in = buf; - FILE *f; - - f = fopen(filename, "r"); - if (f == NULL) { - VMBUS_LOG(ERR, "cannot open sysfs value %s: %s", - filename, strerror(errno)); - return -1; - } - - if (fgets(buf, sizeof(buf), f) == NULL) { - VMBUS_LOG(ERR, "cannot read sysfs value %s", - filename); - fclose(f); - return -1; - } - fclose(f); - - cp = strchr(buf, '\n'); - if (cp) - *cp = '\0'; - - /* strip { } notation */ - if (buf[0] == '{') { - in = buf + 1; - cp = strchr(in, '}'); - if (cp) - *cp = '\0'; - } + char in[BUFSIZ]; + strncpy(in, filename, BUFSIZ); if (rte_uuid_parse(in, uu) < 0) { - VMBUS_LOG(ERR, "%s %s not a valid UUID", - filename, buf); + VMBUS_LOG(ERR, "%s not a valid UUID", in); return -1; } @@ -228,35 +200,33 @@ rte_vmbus_unmap_device(struct rte_vmbus_device *dev) vmbus_uio_unmap_resource(dev); } -/* Scan one vmbus sysfs entry, and fill the devices list from it. */ +/* Scan one vmbus entry, and fill the devices list from it. */ static int -vmbus_scan_one(const char *name) +vmbus_scan_one(const char *name, unsigned int unit_num) { struct rte_vmbus_device *dev, *dev2; - char filename[PATH_MAX]; - char dirname[PATH_MAX]; - unsigned long tmp; + char sysctlBuffer[PATH_MAX], sysctlVar[PATH_MAX]; + size_t guid_len = 36, len = PATH_MAX; + char classid[guid_len], deviceid[guid_len]; dev = calloc(1, sizeof(*dev)); if (dev == NULL) return -1; - dev->device.bus = &rte_vmbus_bus.bus; - dev->device.name = strdup(name); - if (!dev->device.name) + /* get class id and device id */ + snprintf(sysctlVar, len, "dev.%s.%u.%%pnpinfo", name, unit_num); + if (sysctlbyname(sysctlVar, &sysctlBuffer, &len, NULL, 0) < 0) goto error; - /* sysfs base directory - * /sys/bus/vmbus/devices/7a08391f-f5a0-4ac0-9802-d13fd964f8df - * or on older kernel - * /sys/bus/vmbus/devices/vmbus_1 + /* pnpinfo: classid=f912ad6d-2b17-48ea-bd65-f927a61c7684 + * deviceid=d34b2567-b9b6-42b9-8778-0a4ec0b955bf */ - snprintf(dirname, sizeof(dirname), "%s/%s", - SYSFS_VMBUS_DEVICES, name); - - /* get device class */ - snprintf(filename, sizeof(filename), "%s/class_id", dirname); - if (parse_sysfs_uuid(filename, dev->class_id) < 0) + if (sysctlBuffer[0] == 'c' && sysctlBuffer[1] == 'l' && + sysctlBuffer[7] == '=') { + strncpy(classid, &sysctlBuffer[8], guid_len); + classid[guid_len] = '\0'; + } + if (parse_sysfs_uuid(classid, dev->class_id) < 0) goto error; /* skip non-network devices */ @@ -265,35 +235,23 @@ vmbus_scan_one(const char *name) return 0; } - /* get device id */ - snprintf(filename, sizeof(filename), "%s/device_id", dirname); - if (parse_sysfs_uuid(filename, dev->device_id) < 0) - goto error; - - /* get relid */ - snprintf(filename, sizeof(filename), "%s/id", dirname); - if (eal_parse_sysfs_value(filename, &tmp) < 0) + if (sysctlBuffer[45] == 'd' && sysctlBuffer[46] == 'e' && + sysctlBuffer[47] == 'v' && sysctlBuffer[53] == '=') { + strncpy(deviceid, &sysctlBuffer[54], guid_len); + deviceid[guid_len] = '\0'; + } + if (parse_sysfs_uuid(deviceid, dev->device_id) < 0) goto error; - dev->relid = tmp; - /* get monitor id */ - snprintf(filename, sizeof(filename), "%s/monitor_id", dirname); - if (eal_parse_sysfs_value(filename, &tmp) < 0) + if (!strcmp(name, "hv_uio")) + dev->uio_num = unit_num; + else + dev->uio_num = -1; + dev->device.bus = &rte_vmbus_bus.bus; + dev->device.numa_node = 0; + dev->device.name = strdup(deviceid); + if (!dev->device.name) goto error; - dev->monitor_id = tmp; - - /* get numa node (if present) */ - snprintf(filename, sizeof(filename), "%s/numa_node", - dirname); - - if (access(filename, R_OK) == 0) { - if (eal_parse_sysfs_value(filename, &tmp) < 0) - goto error; - dev->device.numa_node = tmp; - } else { - /* if no NUMA support, set default to 0 */ - dev->device.numa_node = SOCKET_ID_ANY; - } dev->device.devargs = vmbus_devargs_lookup(dev); @@ -332,31 +290,120 @@ vmbus_scan_one(const char *name) int rte_vmbus_scan(void) { - struct dirent *e; - DIR *dir; - - dir = opendir(SYSFS_VMBUS_DEVICES); - if (dir == NULL) { - if (errno == ENOENT) - return 0; + struct u_device udev; + struct u_businfo ubus; + int dev_idx, dev_ptr, name2oid[2], oid[CTL_MAXNAME + 12], error; + size_t oidlen, rlen, ub_size; + uintptr_t vmbus_handle = 0; + char *walker, *ep; + char name[16] = "hw.bus.devices"; + char *dd_name, *dd_desc, *dd_drivername, *dd_pnpinfo, *dd_location; + + /* + * devinfo FreeBSD APP logic to fetch all the VMBus devices + * using SYSCTLs + */ + name2oid[0] = 0; + name2oid[1] = 3; + oidlen = sizeof(oid); + error = sysctl(name2oid, 2, oid, &oidlen, name, strlen(name)); + if (error < 0) { + VMBUS_LOG(DEBUG, "can't find hw.bus.devices sysctl node"); + return -ENOENT; + } + oidlen /= sizeof(int); + if (oidlen > CTL_MAXNAME) { + VMBUS_LOG(DEBUG, "hw.bus.devices oid is too large"); + return -EINVAL; + } - VMBUS_LOG(ERR, "opendir %s failed: %s", - SYSFS_VMBUS_DEVICES, strerror(errno)); - return -1; + ub_size = sizeof(ubus); + if (sysctlbyname("hw.bus.info", &ubus, &ub_size, NULL, 0) != 0) { + VMBUS_LOG(DEBUG, "sysctlbyname(\"hw.bus.info\", ...) failed"); + return -EINVAL; + } + if ((ub_size != sizeof(ubus)) || + (ubus.ub_version != BUS_USER_VERSION)) { + VMBUS_LOG(DEBUG, + "kernel bus interface version mismatch: kernel %d expected %d", + ubus.ub_version, BUS_USER_VERSION); + return -EINVAL; } - while ((e = readdir(dir)) != NULL) { - if (e->d_name[0] == '.') - continue; + oid[oidlen++] = ubus.ub_generation; + dev_ptr = oidlen++; + + /* + * Scan devices. + * + * Stop after a fairly insane number to avoid death in the case + * of kernel corruption. + */ + + for (dev_idx = 0; dev_idx < 10000; dev_idx++) { + /* + * Get the device information. + */ + oid[dev_ptr] = dev_idx; + rlen = sizeof(udev); + error = sysctl(oid, oidlen, &udev, &rlen, NULL, 0); + if (error < 0) { + if (errno == ENOENT) /* end of list */ + break; + if (errno != EINVAL) /* gen count skip, restart */ + VMBUS_LOG(DEBUG, "sysctl hw.bus.devices.%d", + dev_idx); + return errno; + } + if (rlen != sizeof(udev)) { + VMBUS_LOG(DEBUG, + "sysctl returned wrong data %zd bytes instead of %zd", + rlen, sizeof(udev)); + return -EINVAL; + } - if (vmbus_scan_one(e->d_name) < 0) - goto error; + walker = udev.dv_fields; + ep = walker + sizeof(udev.dv_fields); + dd_name = NULL; + dd_desc = NULL; + dd_drivername = NULL; + dd_pnpinfo = NULL; + dd_location = NULL; +#define UNPACK(x) \ + do { \ + x = strdup(walker); \ + if (x == NULL) \ + return -ENOMEM; \ + if (walker + strnlen(walker, ep - walker) >= ep) \ + return -EINVAL; \ + walker += strlen(walker) + 1; \ + } while (0) + + UNPACK(dd_name); + UNPACK(dd_desc); + UNPACK(dd_drivername); + UNPACK(dd_pnpinfo); + UNPACK(dd_location); +#undef UNPACK + if (*dd_drivername && !(strcmp(dd_drivername, "vmbus"))) + vmbus_handle = udev.dv_handle; + + if (vmbus_handle && (vmbus_handle == udev.dv_parent) + && *dd_pnpinfo && *dd_name) { + unsigned int driver_len = 0, unit_num = 0; + char *endptr; + + driver_len = strlen(dd_drivername); + unit_num = strtoull(&dd_name[driver_len], &endptr, 10); + VMBUS_LOG(DEBUG, "Device name:%s, pnpinfo:%s", + dd_name, dd_pnpinfo); + + if (vmbus_scan_one(dd_drivername, unit_num) < 0) + goto error; + } } - closedir(dir); return 0; - error: - closedir(dir); return -1; }