[PATCH 23/31] hw/nvme/ctrl: skip automatic zero-init of large arrays

Daniel P. Berrangé posted 31 patches 5 months, 1 week ago
Maintainers: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Gerd Hoffmann <kraxel@redhat.com>, Halil Pasic <pasic@linux.ibm.com>, Christian Borntraeger <borntraeger@linux.ibm.com>, Thomas Huth <thuth@redhat.com>, Dmitry Fleytman <dmitry.fleytman@gmail.com>, Alistair Francis <alistair@alistair23.me>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Peter Maydell <peter.maydell@linaro.org>, "Cédric Le Goater" <clg@kaod.org>, Steven Lee <steven_lee@aspeedtech.com>, Troy Lee <leetroy@gmail.com>, Jamin Lin <jamin_lin@aspeedtech.com>, Andrew Jeffery <andrew@codeconstruct.com.au>, Joel Stanley <joel@jms.id.au>, Jason Wang <jasowang@redhat.com>, Sven Schnelle <svens@stackframe.org>, "Michael S. Tsirkin" <mst@redhat.com>, Rob Herring <robh@kernel.org>, Keith Busch <kbusch@kernel.org>, Klaus Jensen <its@irrelevant.dk>, Jesper Devantier <foss@defmacro.it>, Nicholas Piggin <npiggin@gmail.com>, "Frédéric Barrat" <fbarrat@linux.ibm.com>, Daniel Henrique Barboza <danielhb413@gmail.com>, Harsh Prateek Bora <harshpb@linux.ibm.com>, Fam Zheng <fam@euphon.net>, Hannes Reinecke <hare@suse.com>, Jeuk Kim <jeuk20.kim@samsung.com>
[PATCH 23/31] hw/nvme/ctrl: skip automatic zero-init of large arrays
Posted by Daniel P. Berrangé 5 months, 1 week ago
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é <berrange@redhat.com>
---
 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.49.0


Re: [PATCH 23/31] hw/nvme/ctrl: skip automatic zero-init of large arrays
Posted by Klaus Jensen 5 months, 1 week ago
On Jun 10 13:37, Daniel P. Berrangé wrote:
> 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é <berrange@redhat.com>
> ---
>  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.49.0
> 
> 

Reviewed-by: Klaus Jensen <k.jensen@samsung.com>