From 7eeb1d3acc175813ad3d5e824f26123e0992093a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 Jun 2025 13:37:01 +0100 Subject: [PATCH] hw/nvme/ctrl: skip automatic zero-init of large arrays MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The 'nvme_map_sgl' method has a 256 element array used for copying data from the device. Skip the automatic zero-init of this array to eliminate the performance overhead in the I/O hot path. The 'segment' array will be fully initialized when reading data from the device. The 'nme_changed_nslist' method has a 4k byte array that is manually initialized with memset(). The compiler ought to be intelligent enough to turn the memset() into a static initialization operation, and thus not duplicate the automatic zero-init. Replacing memset() with '{}' makes it unambiguous that the array is statically initialized. Signed-off-by: Daniel P. Berrangé Reviewed-by: Stefan Hajnoczi Reviewed-by: Klaus Jensen Message-id: 20250610123709.835102-24-berrange@redhat.com Signed-off-by: Stefan Hajnoczi --- hw/nvme/ctrl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index fd935507bc..220002830d 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -1057,7 +1057,8 @@ static uint16_t nvme_map_sgl(NvmeCtrl *n, NvmeSg *sg, NvmeSglDescriptor sgl, */ #define SEG_CHUNK_SIZE 256 - NvmeSglDescriptor segment[SEG_CHUNK_SIZE], *sgld, *last_sgld; + QEMU_UNINITIALIZED NvmeSglDescriptor segment[SEG_CHUNK_SIZE]; + NvmeSglDescriptor *sgld, *last_sgld; uint64_t nsgld; uint32_t seg_len; uint16_t status; @@ -5128,7 +5129,7 @@ static uint16_t nvme_error_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, static uint16_t nvme_changed_nslist(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, uint64_t off, NvmeRequest *req) { - uint32_t nslist[1024]; + uint32_t nslist[1024] = {}; uint32_t trans_len; int i = 0; uint32_t nsid; @@ -5138,7 +5139,6 @@ static uint16_t nvme_changed_nslist(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, return NVME_INVALID_FIELD | NVME_DNR; } - memset(nslist, 0x0, sizeof(nslist)); trans_len = MIN(sizeof(nslist) - off, buf_len); while ((nsid = find_first_bit(n->changed_nsids, NVME_CHANGED_NSID_SIZE)) != -- 2.39.5