diff mbox series

[v1,4/4] selftests: arm64: Verify that all possible vector lengths are handled

Message ID 20210913123711.51274-5-broonie@kernel.org
State Superseded
Headers show
Series selftests: arm64: vec-syscfg updates | expand

Commit Message

Mark Brown Sept. 13, 2021, 12:37 p.m. UTC
As part of the enumeration interface for setting vector lengths it is valid
to set vector lengths not supported in the system, these will be rounded to
a supported vector length and returned from the prctl(). Add a test which
exercises this for every valid vector length and makes sure that the return
value is as expected and that this is reflected in the actual system state.

Signed-off-by: Mark Brown <broonie@kernel.org>

---
 tools/testing/selftests/arm64/fp/vec-syscfg.c | 76 +++++++++++++++++++
 1 file changed, 76 insertions(+)

-- 
2.20.1

Comments

Tomohiro Misono (Fujitsu) Sept. 17, 2021, 9:27 a.m. UTC | #1
> As part of the enumeration interface for setting vector lengths it is valid

> to set vector lengths not supported in the system, these will be rounded to

> a supported vector length and returned from the prctl(). Add a test which

> exercises this for every valid vector length and makes sure that the return

> value is as expected and that this is reflected in the actual system state.

> 

> Signed-off-by: Mark Brown <broonie@kernel.org>

> ---

>  tools/testing/selftests/arm64/fp/vec-syscfg.c | 76

> +++++++++++++++++++

>  1 file changed, 76 insertions(+)

> 

> diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c

> b/tools/testing/selftests/arm64/fp/vec-syscfg.c

> index 9d6ac843e651..61e9704e03fe 100644

> --- a/tools/testing/selftests/arm64/fp/vec-syscfg.c

> +++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c

> @@ -540,6 +540,81 @@ static void prctl_set_onexec(struct vec_data *data)

>  	file_write_integer(data->default_vl_file, data->default_vl);

>  }

> 

> +/* For each VQ verify that setting via prctl() does the right thing */

> +static void prctl_set_all_vqs(struct vec_data *data)

> +{

> +	int ret, vq, vl, new_vl;

> +	int errors = 0;

> +

> +	for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) {

> +		vl = sve_vl_from_vq(vq);

> +

> +		/* Attempt to set the VL */

> +		ret = prctl(data->prctl_set, vl);

> +		if (ret < 0) {

> +			errors++;

> +			ksft_print_msg("%s prctl set failed for %d: %d

> (%s)\n",

> +				       data->name, vl,

> +				       errno, strerror(errno));

> +			continue;

> +		}

> +

> +		new_vl = ret & PR_SVE_VL_LEN_MASK;

> +

> +		/* Check that we actually have the reported new VL */

> +		if (data->rdvl() != new_vl) {

> +			ksft_print_msg("Set %s VL %d but RDVL

> reports %d\n",

> +				       data->name, new_vl, data->rdvl());

> +			errors++;

> +		}

> +

> +		/* Was that the VL we asked for? */

> +		if (new_vl == vl)

> +			continue;

> +

> +		/* Should round up to the minimum VL if below it */

> +		if (vl < data->min_vl) {

> +			if (new_vl != data->min_vl) {

> +				ksft_print_msg("%s VL %d returned %d not

> minimum %d\n",

> +					       data->name, vl, new_vl,

> +					       data->min_vl);

> +				errors++;

> +			}

> +

> +			continue;

> +		}

> +

> +		/* Should round down to maximum VL if above it */

> +		if (vl > data->max_vl) {

> +			if (new_vl != data->max_vl) {

> +				ksft_print_msg("%s VL %d returned %d not

> maximum %d\n",

> +					       data->name, vl, new_vl,

> +					       data->max_vl);

> +				errors++;

> +			}

> +

> +			continue;

> +		}

> +


Hello,

Since (new_vl < vl) is expected here:
> +		/* Otherwise we should've rounded down */

> +		if (!(new_vl < vl)) {

> +			ksft_print_msg("%s VL %d returned %d, did not round

> down\n",

> +				       data->name, vl, new_vl);

> +			errors++;

> +

> +			continue;

> +		}


I think following two lines should be removed:
> +

> +		/* We should've hit one of the other cases... */

> +		ksft_print_msg("%s VL %d returned %d test logic failure\n",

> +			       data->name, vl, new_vl);

> +		errors++;


Actually I tried to run these sve tests update on A64FX and got the above error:

  # # SVE VL 48 returned 32 test logic failure

but returning 32 is expected behavior as A64FX's supported VL lens are 16, 32, 64.

Thanks,
Misono

> +	}

> +

> +	ksft_test_result(errors == 0, "%s prctl() set all VLs, %d errors\n",

> +			 data->name, errors);

> +}

> +

>  typedef void (*test_type)(struct vec_data *);

> 

>  static const test_type tests[] = {

> @@ -557,6 +632,7 @@ static const test_type tests[] = {

>  	prctl_set_no_child,

>  	prctl_set_for_child,

>  	prctl_set_onexec,

> +	prctl_set_all_vqs,

>  };

> 

>  int main(void)

> --

> 2.20.1

> 

> 

> _______________________________________________

> linux-arm-kernel mailing list

> linux-arm-kernel@lists.infradead.org

> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Mark Brown Sept. 17, 2021, 12:01 p.m. UTC | #2
On Fri, Sep 17, 2021 at 09:27:04AM +0000, misono.tomohiro@fujitsu.com wrote:

> Actually I tried to run these sve tests update on A64FX and got the above error:


>   # # SVE VL 48 returned 32 test logic failure


> but returning 32 is expected behavior as A64FX's supported VL lens are 16, 32, 64.


Right, I see.  That's not triggering on the virtual platforms since they
just support all the VLs.  Your fix looks right, it was supposed to be
an assert in case of logic failures but that doesn't actually work out.
diff mbox series

Patch

diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c
index 9d6ac843e651..61e9704e03fe 100644
--- a/tools/testing/selftests/arm64/fp/vec-syscfg.c
+++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c
@@ -540,6 +540,81 @@  static void prctl_set_onexec(struct vec_data *data)
 	file_write_integer(data->default_vl_file, data->default_vl);
 }
 
+/* For each VQ verify that setting via prctl() does the right thing */
+static void prctl_set_all_vqs(struct vec_data *data)
+{
+	int ret, vq, vl, new_vl;
+	int errors = 0;
+
+	for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) {
+		vl = sve_vl_from_vq(vq);
+
+		/* Attempt to set the VL */
+		ret = prctl(data->prctl_set, vl);
+		if (ret < 0) {
+			errors++;
+			ksft_print_msg("%s prctl set failed for %d: %d (%s)\n",
+				       data->name, vl,
+				       errno, strerror(errno));
+			continue;
+		}
+
+		new_vl = ret & PR_SVE_VL_LEN_MASK;
+
+		/* Check that we actually have the reported new VL */
+		if (data->rdvl() != new_vl) {
+			ksft_print_msg("Set %s VL %d but RDVL reports %d\n",
+				       data->name, new_vl, data->rdvl());
+			errors++;
+		}
+
+		/* Was that the VL we asked for? */
+		if (new_vl == vl)
+			continue;
+
+		/* Should round up to the minimum VL if below it */
+		if (vl < data->min_vl) {
+			if (new_vl != data->min_vl) {
+				ksft_print_msg("%s VL %d returned %d not minimum %d\n",
+					       data->name, vl, new_vl,
+					       data->min_vl);
+				errors++;
+			}
+
+			continue;
+		}
+
+		/* Should round down to maximum VL if above it */
+		if (vl > data->max_vl) {
+			if (new_vl != data->max_vl) {
+				ksft_print_msg("%s VL %d returned %d not maximum %d\n",
+					       data->name, vl, new_vl,
+					       data->max_vl);
+				errors++;
+			}
+
+			continue;
+		}
+
+		/* Otherwise we should've rounded down */
+		if (!(new_vl < vl)) {
+			ksft_print_msg("%s VL %d returned %d, did not round down\n",
+				       data->name, vl, new_vl);
+			errors++;
+
+			continue;
+		}
+
+		/* We should've hit one of the other cases... */
+		ksft_print_msg("%s VL %d returned %d test logic failure\n",
+			       data->name, vl, new_vl);
+		errors++;
+	}
+
+	ksft_test_result(errors == 0, "%s prctl() set all VLs, %d errors\n",
+			 data->name, errors);
+}
+
 typedef void (*test_type)(struct vec_data *);
 
 static const test_type tests[] = {
@@ -557,6 +632,7 @@  static const test_type tests[] = {
 	prctl_set_no_child,
 	prctl_set_for_child,
 	prctl_set_onexec,
+	prctl_set_all_vqs,
 };
 
 int main(void)