From nobody Tue Oct 28 17:33:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1760024088; cv=none; d=zohomail.com; s=zohoarc; b=JFSSJQXJXRCEuzRM0IvRuJnCiSzSZlfgssh/BpfFklbJG3k7IflIJWIIKEOiVck4S+cO2aMftmu88yT/v+aI9Q/exoHZPw72bECdqzs1fIgfacG1pP3xfB03rgwECqyT2Z3yGaPaLTg4mNu5xdTRrSunallthTDz+CSuAPxNUWE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1760024088; h=Content-Type:Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id:Cc; bh=gVyd7VfdrHTOngF6kl7kXZ2olHFk/EY2tasO8z4nqUw=; b=jkrPbLUp909/herNpN002q2OgJzhUoc/NXqkcg25okWafrffkiG94WfIzjdwR+MT+1lgc/L7Hkc7UPqUa8orDdrqopuDNmfQRdlMFtpxVM6oChsPcvPVfIGYJfXj2bBuGT2Em1lx3nwmQcQsRaqZKjIUXzpD5O4npqDMrrjDoW0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1760024088150488.821612298166; Thu, 9 Oct 2025 08:34:48 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 4DA01440ED; Thu, 9 Oct 2025 11:34:47 -0400 (EDT) Received: from [172.19.199.20] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id C055043ECB; Thu, 9 Oct 2025 11:17:34 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id C3A68444CD; Thu, 9 Oct 2025 11:17:07 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id DB2D34404C for ; Thu, 9 Oct 2025 11:16:35 -0400 (EDT) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-427-kjxSy2amNhif5ti85QULWw-1; Thu, 09 Oct 2025 11:16:32 -0400 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2F22B1800292 for ; Thu, 9 Oct 2025 15:16:32 +0000 (UTC) Received: from speedmetal.lan (unknown [10.44.22.12]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 479601954128 for ; Thu, 9 Oct 2025 15:16:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1760022995; h=from:from: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; bh=gVyd7VfdrHTOngF6kl7kXZ2olHFk/EY2tasO8z4nqUw=; b=Muniz7uP4VsBGjCv+rcbjdmaDBdmtbVf8FNpdgv4G/2KEeFpe3qYRHTbL0AA1hTK6wzsLv vP4ZBGVAWXfgao/HMw1IrkFf3mwU347ezDkqcKVlTLqxDBQOjwlU264MGTLI70w5bSghiG zHV2llBaoAK4axDCDceGNgZDG1bxUFY= X-MC-Unique: kjxSy2amNhif5ti85QULWw-1 X-Mimecast-MFC-AGG-ID: kjxSy2amNhif5ti85QULWw_1760022992 To: devel@lists.libvirt.org Subject: [RFC PATCH 10/16] Expose qemu storage request limits via bulk stats API Date: Thu, 9 Oct 2025 17:16:10 +0200 Message-ID: <30eaba5683b20ddc0b77ab3ff7002ca2f79df563.1760022633.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: oVC-z_n8uylZUF-JEvXb9UlFpze__qOYmgc1XwDHwsc_1760022992 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: JCCIU75ORCRC5V3VEUDMPKOHF3QRZYHS X-Message-ID-Hash: JCCIU75ORCRC5V3VEUDMPKOHF3QRZYHS X-MailFrom: pkrempa@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Peter Krempa via Devel Reply-To: Peter Krempa X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1760024090625154100 Content-Type: text/plain; charset="utf-8" From: Peter Krempa Management applications can use the detected limits to cross reference with configuration within the VM to ensure optimal performance. Signed-off-by: Peter Krempa --- docs/manpages/virsh.rst | 21 +++++ include/libvirt/libvirt-domain.h | 148 +++++++++++++++++++++++++++++++ src/qemu/qemu_driver.c | 61 +++++++++++++ 3 files changed, 230 insertions(+) diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index bcb5495ed9..5b4eb236a4 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -2751,6 +2751,27 @@ Information listed includes: * ``block..physical`` - physical size of source file in bytes * ``block..threshold`` - threshold (in bytes) for delivering the VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD event. See domblkthreshold. +* ``block..limits.request_alignment`` - Alignment requirement for req= uests + in bytes +* ``block..limits.discard_max`` - Maximum number of bytes that can be + discarded at once +* ``block..limits.discard_alignment`` - Optimal alignment for discard + requests in bytes +* ``block..limits.write_zeroes_max`` - Maximum number of bytes that c= an be + zeroed out at once +* ``block..limits.write_zeroes_alignment`` - Optimal alignment for + write_zeroes requests in bytes +* ``block..limits.transfer_optimal`` - Optimal transfer length in byt= es +* ``block..limits.transfer_max`` - Maximal transfer length in bytes +* ``block..limits.transfer_hw_max`` - Maximal hardware transfer lengt= h of + requests bypassing kernel IO scheduler in bytes +* ``block..limits.iov_max`` - Maximum number of scatter/gather elemen= ts +* ``block..limits.iov_hw_max`` - Maximal number of scatter/gather ele= ments + of requests bypassing kernel IO scheduler +* ``block..limits.memory_alignment_minimal`` - memory alignment in by= tes so + that no bounce buffer is needed +* ``block..limits.memory_alignment_optimal`` - memory alignment in by= tes + that is used for bounce buffers *--iothread* returns information about IOThreads on the running guest diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-dom= ain.h index 71bb49fe6c..90c37a575c 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -3488,6 +3488,154 @@ struct _virDomainStatsRecord { */ # define VIR_DOMAIN_STATS_BLOCK_SUFFIX_THRESHOLD ".threshold" +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_REQUEST_ALIGNMENT: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * Alignment requirement, in bytes, for offset/length of I/O requests, as + * unsigned long long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_REQUEST_ALIGNMENT ".limits.r= equest_alignment" + +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_MAX: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * Maximum number of bytes that can be discarded at once, as unsigned long= long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_MAX ".limits.discard= _max" + +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_ALIGNMENT: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * Optimal alignment for discard requests in bytes, as unsigned long long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_ALIGNMENT ".limits.d= iscard_alignment" + +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_MAX: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * Maximum number of bytes that can be zeroed out at once, as unsigned lon= g long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_MAX ".limits.wr= ite_zeroes_max" + +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_ALIGNMENT: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * Optimal alignment for write_zeroes requests in bytes, as unsigned long = long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_ALIGNMENT ".lim= its.write_zeroes_alignment" + +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_OPTIMAL: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * Optimal transfer length in bytes, as unsigned long long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_OPTIMAL ".limits.tr= ansfer_optimal" + +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_MAX: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * Maximal transfer length in bytes, as unsigned long long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_MAX ".limits.transf= er_max" + +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_HW_MAX: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * Maximal hardware transfer length of requests bypassing kernel IO schedu= ler + * in bytes, as unsigned long long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_HW_MAX ".limits.tra= nsfer_hw_max" + +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_MAX: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * Maximum number of scatter/gather elements, as unsigned long long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_MAX ".limits.iov_max" + +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_HW_MAX: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * Maximal number of scatter/gather elements of requests bypassing kernel = IO + * scheduler, as unsigned long long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_HW_MAX ".limits.iov_hw_m= ax" + +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_MINIMAL: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * memory alignment in bytes so that no bounce buffer is needed, as + * unsigned long long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_MINIMAL ".l= imits.memory_alignment_minimal" + +/** + * VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_OPTIMAL: + * + * limits represent constraints on individual operations as imposed by the + * backing file storage technology. + * + * memory alignment in bytes that is used for bounce buffers, as + * unsigned long long. + * + * Since: 11.9.0 + */ +# define VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_OPTIMAL ".l= imits.memory_alignment_optimal" /** * VIR_DOMAIN_STATS_PERF_CMT: diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 806408115f..4e5e2fed0f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -17510,6 +17510,67 @@ qemuDomainGetStatsBlockExportBackendStorage(const = char *entryname, if (entry->write_threshold) virTypedParamListAddULLong(params, entry->write_threshold, VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu" VIR= _DOMAIN_STATS_BLOCK_SUFFIX_THRESHOLD, recordnr); + + if (entry->limits) { + if (entry->limits->request_alignment > 0) + virTypedParamListAddULLong(params, entry->limits->request_alig= nment, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_REQUEST_ALIGNMENT, + recordnr); + + if (entry->limits->discard_max > 0) + virTypedParamListAddULLong(params, entry->limits->discard_max, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_MAX, + recordnr); + + if (entry->limits->discard_alignment > 0) + virTypedParamListAddULLong(params, entry->limits->discard_alig= nment, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_DISCARD_ALIGNMENT, + recordnr); + + if (entry->limits->write_zeroes_max > 0) + virTypedParamListAddULLong(params, entry->limits->write_zeroes= _max, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_MAX, + recordnr); + if (entry->limits->write_zeroes_alignment > 0) + virTypedParamListAddULLong(params, entry->limits->write_zeroes= _alignment, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_WRITE_ZEROES_ALIGNMENT, + recordnr); + + if (entry->limits->transfer_optimal > 0) + virTypedParamListAddULLong(params, entry->limits->transfer_opt= imal, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_OPTIMAL, + recordnr); + + if (entry->limits->transfer_max > 0) + virTypedParamListAddULLong(params, entry->limits->transfer_max, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_MAX, + recordnr); + + if (entry->limits->transfer_hw_max > 0) + virTypedParamListAddULLong(params, entry->limits->transfer_hw_= max, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_TRANSFER_HW_MAX, + recordnr); + + if (entry->limits->iov_max > 0) + virTypedParamListAddULLong(params, entry->limits->iov_max, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_MAX, + recordnr); + + if (entry->limits->iov_hw_max > 0) + virTypedParamListAddULLong(params, entry->limits->iov_hw_max, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_IOV_HW_MAX, + recordnr); + + if (entry->limits->memory_alignment_minimal > 0) + virTypedParamListAddULLong(params, entry->limits->memory_align= ment_minimal, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_MINIMAL, + recordnr); + + if (entry->limits->memory_alignment_optimal > 0) + virTypedParamListAddULLong(params, entry->limits->memory_align= ment_optimal, + VIR_DOMAIN_STATS_BLOCK_PREFIX "%zu"= VIR_DOMAIN_STATS_BLOCK_SUFFIX_LIMITS_MEMORY_ALIGNMENT_OPTIMAL, + recordnr); + } } --=20 2.51.0