On 8/4/23 11:16, Richard W.M. Jones wrote:
> On Wed, Aug 02, 2023 at 08:50:25PM -0500, Eric Blake wrote:
>> Commit 6725fa0e12 changed copy_uint32_array() to utilize a Go hack for
>> accessing a C array as a Go slice in order to potentially benefit from
>> any optimizations in Go's copy() for bulk transfer of memory over
>> naive one-at-a-time iteration.  But that commit also acknowledged that
>> no benchmark timings were performed, which would have been useful to
>> demonstrat an actual benefit for using hack in the first place.  And
> 
> "demonstrate"
> 
>> since we are copying data anyways (rather than using the slice to
>> avoid a copy), and network transmission costs have a higher impact to
>> performance than in-memory copying speed, it's hard to justify keeping
>> the hack without hard data.
>>
>> What's more, while using Go's copy() on an array of C uint32_t makes
>> sense for 32-bit extents, our corresponding 64-bit code uses a struct
>> which does not map as nicely to Go's copy().  Using a common style
>> between both list copying helpers is beneficial to mainenance.
>>
>> Additionally, at face value, converting C.size_t to int may truncate;
>> we could avoid that risk if we were to uniformly use uint64 instead of
>> int.  But we can equally just panic if the count is oversized: our
>> state machine guarantees that the server's response fits within 64M
>> bytes (count will be smaller than that, since it is multiple bytes per
>> extent entry).
>>
>> Suggested-by: Laszlo Ersek <ler...@redhat.com>
>> CC: Nir Soffer <nsof...@redhat.com>
>> Signed-off-by: Eric Blake <ebl...@redhat.com>
>> ---
>>
>> v4: new patch to the series, but previously posted as part of the
>> golang cleanups.  Since then: rework the commit message as it is no
>> longer a true revert, and add a panic() if count exceeds expected
>> bounds.
>> ---
>>  generator/GoLang.ml | 13 +++++++++----
>>  1 file changed, 9 insertions(+), 4 deletions(-)
>>
>> diff --git a/generator/GoLang.ml b/generator/GoLang.ml
>> index 73df5254..cc7d78b6 100644
>> --- a/generator/GoLang.ml
>> +++ b/generator/GoLang.ml
>> @@ -516,11 +516,16 @@ let
>>  /* Closures. */
>>
>>  func copy_uint32_array(entries *C.uint32_t, count C.size_t) []uint32 {
>> +    if (uint64(count) > 64*1024*1024) {
>> +        panic(\"violation of state machine guarantee\")
>> +    }
> 
> Not sure if golang includes the line number when it panics, but a
> brief bit of explanation might help here.  Something like:
> 
>   panic(\"internal error: state machine should guarantee <= 64M of data \
>           in the extents reply, but this was exceeded unexpectedly\")

Sounds helpful!

> 
>>      ret := make([]uint32, int(count))
>> -    // See 
>> https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices
>> -    // TODO: Use unsafe.Slice() when we require Go 1.17.
>> -    s := (*[1 << 30]uint32)(unsafe.Pointer(entries))[:count:count]
> 
> The whole magical 1 << 30 was another thing to dislike about golang,
> so glad to see it gone here.
> 
>> -    copy(ret, s)
>> +    addr := uintptr(unsafe.Pointer(entries))
>> +    for i := 0; i < int(count); i++ {
>> +        ptr := (*C.uint32_t)(unsafe.Pointer(addr))
>> +        ret[i] = uint32(*ptr)
>> +        addr += unsafe.Sizeof(*ptr)
>> +    }
>>      return ret
>>  }
> 
> Reviewed-by: Richard W.M. Jones <rjo...@redhat.com>

Reviewed-by: Laszlo Ersek <ler...@redhat.com>


_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to