From nobody Mon Feb 9 09:15:50 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1628172976; cv=none; d=zohomail.com; s=zohoarc; b=jAdqEk+VB55pDPutEhdns6Bubx3kHB/dLvuIGgmHEZPY2ic3qyKbXCKawPQQZGuuHWKd4mM+xVK/1JaNnmaTOky1E8054LuZYauTSgDQaSjvJk/ZpvXW2d1ADTy4FOzffCuIIf5NgjZ5uUwvUKe3XpVvO7Sd98nCLkmsqnB/Rng= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1628172976; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=wYZfbeg8UEgwfCzRp4ftTOHDnmI2z3OTZyz0yH84jR8=; b=NQqmyI0o2N598/o490Pu+R/w88kOsVaNea0ZROLQW0R+ALroAA7kaCejlYvljnG4npRMZQyxe7YRslmDMB5YNmA5Q3sOSZC1I2ZJItvnTsMP2caf/a/RxGuJtk3U2Jnk5YkFx9ANjNnz4gQhCujvfhc7tKXN1OQV3Fn34ZV0SBk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1628172976845953.8056287979414; Thu, 5 Aug 2021 07:16:16 -0700 (PDT) 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-584-qJJ-RqgzMq69eh5wtBj4Og-1; Thu, 05 Aug 2021 10:16:13 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1B555881279; Thu, 5 Aug 2021 14:16:09 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id AAA095C25D; Thu, 5 Aug 2021 14:16:08 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 9DE34180BAB1; Thu, 5 Aug 2021 14:16:07 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 175EDIQ9016803 for ; Thu, 5 Aug 2021 10:13:18 -0400 Received: by smtp.corp.redhat.com (Postfix) id 845885C25D; Thu, 5 Aug 2021 14:13:18 +0000 (UTC) Received: from speedmetal.redhat.com (unknown [10.40.208.33]) by smtp.corp.redhat.com (Postfix) with ESMTP id CB9F65C1A1 for ; Thu, 5 Aug 2021 14:13:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1628172975; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=wYZfbeg8UEgwfCzRp4ftTOHDnmI2z3OTZyz0yH84jR8=; b=AjdGmLToGvSHWR5wqAzbocf1NYLtHjEGOzh/yVpMUG3DNlf+xn1+6ReZMtWlXVNYF8cLh9 t1BK/xrxhQofssTytnX8KBIgJ3lQ7drbHYWMi0euDZn1pnSjmh93IUqgVnkl5oOGouQA6q KWXQTrrepZIyk+67g2R/jTo52bMUudw= X-MC-Unique: qJJ-RqgzMq69eh5wtBj4Og-1 From: Peter Krempa To: libvir-list@redhat.com Subject: [PATCH 2/6] virPCIGetVirtualFunctions: Simplify cleanup of returned data Date: Thu, 5 Aug 2021 16:13:06 +0200 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1628172978998100001 Content-Type: text/plain; charset="utf-8" Introduce a struct for holding the list of VFs returned by virPCIGetVirtualFunctions so that we can employ automatic memory clearing and also allow querying more information at once. Signed-off-by: Peter Krempa --- src/conf/node_device_conf.c | 16 +++++--- src/libvirt_private.syms | 1 + src/util/virnetdev.c | 10 +++-- src/util/virpci.c | 79 ++++++++++++++++++------------------- src/util/virpci.h | 18 +++++++-- 5 files changed, 72 insertions(+), 52 deletions(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index d12d97f077..d363ddc22e 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -2623,6 +2623,7 @@ static int virNodeDeviceGetPCISRIOVCaps(const char *sysfsPath, virNodeDevCapPCIDev *pci_dev) { + g_autoptr(virPCIVirtualFunctionList) vfs =3D g_new0(virPCIVirtualFunct= ionList, 1); size_t i; int ret; @@ -2644,11 +2645,16 @@ virNodeDeviceGetPCISRIOVCaps(const char *sysfsPath, if (pci_dev->physical_function) pci_dev->flags |=3D VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION; - ret =3D virPCIGetVirtualFunctions(sysfsPath, &pci_dev->virtual_functio= ns, - &pci_dev->num_virtual_functions, - &pci_dev->max_virtual_functions); - if (ret < 0) - return ret; + if (virPCIGetVirtualFunctions(sysfsPath, &vfs) < 0) + return -1; + + pci_dev->virtual_functions =3D g_new0(virPCIDeviceAddress *, vfs->nfun= ctions); + + for (i =3D 0; i < vfs->nfunctions; i++) + pci_dev->virtual_functions[i] =3D g_steal_pointer(&vfs->functions[= i].addr); + + pci_dev->num_virtual_functions =3D vfs->nfunctions; + pci_dev->max_virtual_functions =3D vfs->maxfunctions; if (pci_dev->num_virtual_functions > 0 || pci_dev->max_virtual_functions > 0) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e4168a06b9..20e74dd5d5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3016,6 +3016,7 @@ virPCIHeaderTypeToString; virPCIIsVirtualFunction; virPCIStubDriverTypeFromString; virPCIStubDriverTypeToString; +virPCIVirtualFunctionListFree; virZPCIDeviceAddressIsIncomplete; virZPCIDeviceAddressIsPresent; diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index d578becb20..ea5aba7116 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -1231,7 +1231,7 @@ virNetDevGetVirtualFunctions(const char *pfname, size_t i; g_autofree char *pf_sysfs_device_link =3D NULL; g_autofree char *pfPhysPortID =3D NULL; - unsigned int max_vfs; + g_autoptr(virPCIVirtualFunctionList) vfs =3D NULL; *virt_fns =3D NULL; *n_vfname =3D 0; @@ -1242,14 +1242,18 @@ virNetDevGetVirtualFunctions(const char *pfname, if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0) goto cleanup; - if (virPCIGetVirtualFunctions(pf_sysfs_device_link, virt_fns, n_vfname= , &max_vfs) < 0) + if (virPCIGetVirtualFunctions(pf_sysfs_device_link, &vfs) < 0) goto cleanup; - *vfname =3D g_new0(char *, *n_vfname); + *vfname =3D g_new0(char *, vfs->nfunctions); + *virt_fns =3D g_new0(virPCIDeviceAddress *, vfs->nfunctions); + *n_vfname =3D vfs->nfunctions; for (i =3D 0; i < *n_vfname; i++) { g_autofree char *pci_sysfs_device_link =3D NULL; + virt_fns[i] =3D g_steal_pointer(&vfs->functions[i].addr); + if (virPCIDeviceAddressGetSysfsFile((*virt_fns)[i], &pci_sysfs_device_link) < 0) { virReportSystemError(ENOSYS, "%s", diff --git a/src/util/virpci.c b/src/util/virpci.c index 67c3896dd5..2afbf40af3 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -2247,6 +2247,22 @@ virZPCIDeviceAddressIsPresent(const virZPCIDeviceAdd= ress *addr) } +void +virPCIVirtualFunctionListFree(virPCIVirtualFunctionList *list) +{ + size_t i; + + if (!list) + return; + + for (i =3D 0; i < list->nfunctions; i++) { + g_free(list->functions[i].addr); + } + + g_free(list); +} + + #ifdef __linux__ virPCIDeviceAddress * @@ -2321,62 +2337,54 @@ virPCIGetPhysicalFunction(const char *vf_sysfs_path, */ int virPCIGetVirtualFunctions(const char *sysfs_path, - virPCIDeviceAddress ***virtual_functions, - size_t *num_virtual_functions, - unsigned int *max_virtual_functions) + virPCIVirtualFunctionList **vfs) { - size_t i; g_autofree char *totalvfs_file =3D NULL; g_autofree char *totalvfs_str =3D NULL; - g_autofree virPCIDeviceAddress *config_addr =3D NULL; + g_autoptr(virPCIVirtualFunctionList) list =3D g_new0(virPCIVirtualFunc= tionList, 1); - *virtual_functions =3D NULL; - *num_virtual_functions =3D 0; - *max_virtual_functions =3D 0; + *vfs =3D NULL; totalvfs_file =3D g_strdup_printf("%s/sriov_totalvfs", sysfs_path); if (virFileExists(totalvfs_file)) { char *end =3D NULL; /* so that terminating \n doesn't create error= */ + unsigned long long maxfunctions =3D 0; if (virFileReadAll(totalvfs_file, 16, &totalvfs_str) < 0) - goto error; - if (virStrToLong_ui(totalvfs_str, &end, 10, max_virtual_functions)= < 0) { + return -1; + if (virStrToLong_ull(totalvfs_str, &end, 10, &maxfunctions) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unrecognized value in %s: %s"), totalvfs_file, totalvfs_str); - goto error; + return -1; } + list->maxfunctions =3D maxfunctions; } do { g_autofree char *device_link =3D NULL; + struct virPCIVirtualFunction fnc =3D { NULL }; + /* look for virtfn%d links until one isn't found */ - device_link =3D g_strdup_printf("%s/virtfn%zu", sysfs_path, - *num_virtual_functions); + device_link =3D g_strdup_printf("%s/virtfn%zu", sysfs_path, list->= nfunctions); if (!virFileExists(device_link)) break; - if (!(config_addr =3D virPCIGetDeviceAddressFromSysfsLink(device_l= ink))) { + if (!(fnc.addr =3D virPCIGetDeviceAddressFromSysfsLink(device_link= ))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to get SRIOV function from device lin= k '%s'"), device_link); - goto error; + return -1; } - VIR_APPEND_ELEMENT(*virtual_functions, *num_virtual_functions, con= fig_addr); + VIR_APPEND_ELEMENT(list->functions, list->nfunctions, fnc); } while (1); - VIR_DEBUG("Found %zu virtual functions for %s", - *num_virtual_functions, sysfs_path); - return 0; + VIR_DEBUG("Found %zu virtual functions for %s", list->nfunctions, sysf= s_path); - error: - for (i =3D 0; i < *num_virtual_functions; i++) - VIR_FREE((*virtual_functions)[i]); - VIR_FREE(*virtual_functions); - *num_virtual_functions =3D 0; - return -1; + *vfs =3D g_steal_pointer(&list); + return 0; } @@ -2403,24 +2411,21 @@ virPCIGetVirtualFunctionIndex(const char *pf_sysfs_= device_link, { int ret =3D -1; size_t i; - size_t num_virt_fns =3D 0; - unsigned int max_virt_fns =3D 0; g_autofree virPCIDeviceAddress *vf_bdf =3D NULL; - virPCIDeviceAddress **virt_fns =3D NULL; + g_autoptr(virPCIVirtualFunctionList) virt_fns =3D NULL; if (!(vf_bdf =3D virPCIGetDeviceAddressFromSysfsLink(vf_sysfs_device_l= ink))) return ret; - if (virPCIGetVirtualFunctions(pf_sysfs_device_link, &virt_fns, - &num_virt_fns, &max_virt_fns) < 0) { + if (virPCIGetVirtualFunctions(pf_sysfs_device_link, &virt_fns) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Error getting physical function's '%s' " "virtual_functions"), pf_sysfs_device_link); goto out; } - for (i =3D 0; i < num_virt_fns; i++) { - if (virPCIDeviceAddressEqual(vf_bdf, virt_fns[i])) { + for (i =3D 0; i < virt_fns->nfunctions; i++) { + if (virPCIDeviceAddressEqual(vf_bdf, virt_fns->functions[i].addr))= { *vf_index =3D i; ret =3D 0; break; @@ -2428,12 +2433,6 @@ virPCIGetVirtualFunctionIndex(const char *pf_sysfs_d= evice_link, } out: - - /* free virtual functions */ - for (i =3D 0; i < num_virt_fns; i++) - VIR_FREE(virt_fns[i]); - - VIR_FREE(virt_fns); return ret; } @@ -2641,9 +2640,7 @@ virPCIGetPhysicalFunction(const char *vf_sysfs_path G= _GNUC_UNUSED, int virPCIGetVirtualFunctions(const char *sysfs_path G_GNUC_UNUSED, - virPCIDeviceAddress ***virtual_functions G_GNUC_= UNUSED, - size_t *num_virtual_functions G_GNUC_UNUSED, - unsigned int *max_virtual_functions G_GNUC_UNUSE= D) + virPCIVirtualFunctionList **vfs G_GNUC_UNUSED) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported)); return -1; diff --git a/src/util/virpci.h b/src/util/virpci.h index 1fa6c58d50..ce6a056c9c 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -212,10 +212,22 @@ virPCIGetDeviceAddressFromSysfsLink(const char *devic= e_link); int virPCIGetPhysicalFunction(const char *vf_sysfs_path, virPCIDeviceAddress **pf); +struct virPCIVirtualFunction { + virPCIDeviceAddress *addr; +}; + +struct _virPCIVirtualFunctionList { + struct virPCIVirtualFunction *functions; + size_t nfunctions; + size_t maxfunctions; +}; +typedef struct _virPCIVirtualFunctionList virPCIVirtualFunctionList; + +void virPCIVirtualFunctionListFree(virPCIVirtualFunctionList *list); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIVirtualFunctionList, virPCIVirtualFunc= tionListFree); + int virPCIGetVirtualFunctions(const char *sysfs_path, - virPCIDeviceAddress ***virtual_functions, - size_t *num_virtual_functions, - unsigned int *max_virtual_functions); + virPCIVirtualFunctionList **vfs); int virPCIIsVirtualFunction(const char *vf_sysfs_device_link); --=20 2.31.1