Re: [PATCH v4 03/10] KVM: selftests: Read binary stats desc in lib

From: Ben Gardon
Date: Tue Apr 12 2022 - 14:57:03 EST


On Mon, Apr 11, 2022 at 5:55 PM Mingwei Zhang <mizhang@xxxxxxxxxx> wrote:
>
> On Mon, Apr 11, 2022, Ben Gardon wrote:
> > Move the code to read the binary stats descriptors to the KVM selftests
> > library. It will be re-used by other tests to check KVM behavior.
> >
> > No functional change intended.
> >
> > Signed-off-by: Ben Gardon <bgardon@xxxxxxxxxx>
> > ---
> > .../selftests/kvm/include/kvm_util_base.h | 4 +++
> > .../selftests/kvm/kvm_binary_stats_test.c | 9 ++----
> > tools/testing/selftests/kvm/lib/kvm_util.c | 29 +++++++++++++++++++
> > 3 files changed, 35 insertions(+), 7 deletions(-)
> >
> > diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
> > index 5ba3132f3110..c5f34551ff76 100644
> > --- a/tools/testing/selftests/kvm/include/kvm_util_base.h
> > +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
> > @@ -401,6 +401,10 @@ void assert_on_unhandled_exception(struct kvm_vm *vm, uint32_t vcpuid);
> > int vm_get_stats_fd(struct kvm_vm *vm);
> > int vcpu_get_stats_fd(struct kvm_vm *vm, uint32_t vcpuid);
> > void read_vm_stats_header(int stats_fd, struct kvm_stats_header *header);
> > +struct kvm_stats_desc *alloc_vm_stats_desc(int stats_fd,
> > + struct kvm_stats_header *header);
> > +void read_vm_stats_desc(int stats_fd, struct kvm_stats_header *header,
> > + struct kvm_stats_desc *stats_desc);
> >
> > uint32_t guest_get_vcpuid(void);
> >
> > diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/testing/selftests/kvm/kvm_binary_stats_test.c
> > index 22c22a90f15a..e4795bad7db6 100644
> > --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c
> > +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c
> > @@ -62,14 +62,9 @@ static void stats_test(int stats_fd)
> > header.data_offset),
> > "Descriptor block is overlapped with data block");
> >
> > - /* Allocate memory for stats descriptors */
> > - stats_desc = calloc(header.num_desc, size_desc);
> > - TEST_ASSERT(stats_desc, "Allocate memory for stats descriptors");
> > /* Read kvm stats descriptors */
> > - ret = pread(stats_fd, stats_desc,
> > - size_desc * header.num_desc, header.desc_offset);
> > - TEST_ASSERT(ret == size_desc * header.num_desc,
> > - "Read KVM stats descriptors");
> > + stats_desc = alloc_vm_stats_desc(stats_fd, &header);
> > + read_vm_stats_desc(stats_fd, &header, stats_desc);
> >
> > /* Sanity check for fields in descriptors */
> > for (i = 0; i < header.num_desc; ++i) {
> > diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
> > index 0caf28e324ed..e3ae26fbef03 100644
> > --- a/tools/testing/selftests/kvm/lib/kvm_util.c
> > +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
> > @@ -2564,3 +2564,32 @@ void read_vm_stats_header(int stats_fd, struct kvm_stats_header *header)
> > ret = read(stats_fd, header, sizeof(*header));
> > TEST_ASSERT(ret == sizeof(*header), "Read stats header");
> > }
> > +
> > +static ssize_t stats_descs_size(struct kvm_stats_header *header)
> > +{
> > + return header->num_desc *
> > + (sizeof(struct kvm_stats_desc) + header->name_size);
> > +}
> I was very confused on header->name_size. So this field means the
> maximum string size of a stats name, right? Can we update the comments
> in the kvm.h to specify that? By reading the comments, I don't really
> feel this is how we should use this field.

I believe that's right. I agree the documentation on that was a little
confusing.

>
> hmm, if that is true, isn't this field a compile time value? Why do we
> have to get it at runtime?

It's compile time for the kernel but not for the userspace binaries
which ultimately consume the stats.
We could cheat in this selftest perhaps, but then it wouldn't be as
good of a test.

>
> > +
> > +/* Caller is responsible for freeing the returned kvm_stats_desc. */
> > +struct kvm_stats_desc *alloc_vm_stats_desc(int stats_fd,
> > + struct kvm_stats_header *header)
> > +{
> > + struct kvm_stats_desc *stats_desc;
> > +
> > + stats_desc = malloc(stats_descs_size(header));
> > + TEST_ASSERT(stats_desc, "Allocate memory for stats descriptors");
> > +
> > + return stats_desc;
> > +}
> > +
> > +void read_vm_stats_desc(int stats_fd, struct kvm_stats_header *header,
> > + struct kvm_stats_desc *stats_desc)
> > +{
> > + ssize_t ret;
> > +
> > + ret = pread(stats_fd, stats_desc, stats_descs_size(header),
> > + header->desc_offset);
> > + TEST_ASSERT(ret == stats_descs_size(header),
> > + "Read KVM stats descriptors");
> > +}
> > --
> > 2.35.1.1178.g4f1659d476-goog
> >