Hi Peter,

This is in regard to your comment on the use of g_usleep() in waiting for
an event-bit update from the device under test.

The TRNG device model presented in patch #1 does not have any asynchronous 
behavior.

So, do you mean that, although the qtest process and the qemu-system-* process
are running as 2 separate processes, qtest infrastructure already has the 
necessary
mechanism to ensure that:

1. After qtest test sets a register that has the correct deterministic behavior 
to update an event bit,

2. The same qtest test subsequently issuing a register read will be guaranteed 
to observe the updated bit?

If that is the case, then there would be no need for any timeout. Instead,
a qtest test can declare fail when the expected bit update is not observed by 
the test.

I would like to know.

Thanks,
Tong Ho

________________________________
From: Peter Maydell <peter.mayd...@linaro.org>
Sent: Friday, October 27, 2023 6:03 AM
To: Ho, Tong <tong...@amd.com>
Cc: qemu-...@nongnu.org <qemu-...@nongnu.org>; qemu-devel@nongnu.org 
<qemu-devel@nongnu.org>; alist...@alistair23.me <alist...@alistair23.me>; 
edgar.igles...@gmail.com <edgar.igles...@gmail.com>; 
richard.hender...@linaro.org <richard.hender...@linaro.org>; 
frasse.igles...@gmail.com <frasse.igles...@gmail.com>
Subject: Re: [PATCH v4 3/3] tests/qtest: Introduce tests for AMD/Xilinx Versal 
TRNG device

On Tue, 17 Oct 2023 at 20:32, Tong Ho <tong...@amd.com> wrote:
>
> Signed-off-by: Tong Ho <tong...@amd.com>
> ---
>  tests/qtest/meson.build             |   2 +-
>  tests/qtest/xlnx-versal-trng-test.c | 486 ++++++++++++++++++++++++++++
>  2 files changed, 487 insertions(+), 1 deletion(-)
>  create mode 100644 tests/qtest/xlnx-versal-trng-test.c


> +static void trng_wait(uint32_t wait_mask, bool on, const char *act)
> +{
> +    time_t tmo = time(NULL) + 2; /* at most 2 seconds */

Don't put timeouts this short into tests, please; ideally,
avoid them entirely. Sometimes the CI machines are heavily
loaded and the test might not be able to complete in a
short time like this. If you must have a timeout, it should
be at least a minute. (And see below on whether we need one.)

> +    uint32_t event_mask = 0;
> +    uint32_t clear_mask = 0;
> +
> +    /*
> +     * Only selected bits are events in R_TRNG_STATUS, and
> +     * clear them needs to go through R_INT_CTRL.
> +     */
> +    if (wait_mask & TRNG_STATUS_CERTF_MASK) {
> +        event_mask |= TRNG_STATUS_CERTF_MASK;
> +        clear_mask |= TRNG_INT_CTRL_CERTF_RST_MASK;
> +    }
> +    if (wait_mask & TRNG_STATUS_DTF_MASK) {
> +        event_mask |= TRNG_STATUS_DTF_MASK;
> +        clear_mask |= TRNG_INT_CTRL_DTF_RST_MASK;
> +    }
> +    if (wait_mask & TRNG_STATUS_DONE_MASK) {
> +        event_mask |= TRNG_STATUS_DONE_MASK;
> +        clear_mask |= TRNG_INT_CTRL_DONE_RST_MASK;
> +    }
> +
> +    for (;;) {
> +        bool sta = !!(trng_status() & event_mask);
> +
> +        if ((on ^ sta) == 0) {
> +            break;
> +        }
> +
> +        if (time(NULL) >= tmo) {
> +            FAILED("%s: Timed out waiting for event 0x%x to be %d%s",
> +                   act, event_mask, (int)on, trng_info());
> +        }
> +
> +        g_usleep(10000);

Why does this test need to use sleeps and timeouts?
A qtest test controls the guest 'clock' directly, so
usually they're completely deterministic. Is there some
behaviour in the TRNG device which is asynchronous (in
a way not driven from the QEMU guest clock) that I've missed ?

> +    }
> +
> +    /* Remove event */
> +    trng_bit_set(R_TRNG_INT_CTRL, clear_mask);
> +
> +    if (!!(trng_read(R_TRNG_STATUS) & event_mask)) {
> +        FAILED("%s: Event 0x%0x stuck at 1 after clear: %s",
> +               act, event_mask, trng_info());
> +    }
> +}

thanks
-- PMM

Reply via email to