[Qemu-devel] [PATCH] target/alpha: Take BQL around clock manipulations

Richard Henderson posted 1 patch 7 years, 1 month ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20170306205609.6525-1-rth@twiddle.net
Test checkpatch passed
Test docker passed
target/alpha/sys_helper.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
[Qemu-devel] [PATCH] target/alpha: Take BQL around clock manipulations
Posted by Richard Henderson 7 years, 1 month ago
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
This is similar to the patch that I saw go by for MIPS.

I hadn't noticed any problems caused by this lack of locking.  This may
be because interrupts cannot be delivered while in PALmode while these
registers are being manipulated.  However, it's always better to obey
the rules, right?


r~
---
 target/alpha/sys_helper.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/target/alpha/sys_helper.c b/target/alpha/sys_helper.c
index 652195d..6feb30b 100644
--- a/target/alpha/sys_helper.c
+++ b/target/alpha/sys_helper.c
@@ -28,11 +28,14 @@
 uint64_t helper_load_pcc(CPUAlphaState *env)
 {
 #ifndef CONFIG_USER_ONLY
+    uint64_t pcc;
     /* In system mode we have access to a decent high-resolution clock.
        In order to make OS-level time accounting work with the RPCC,
        present it with a well-timed clock fixed at 250MHz.  */
-    return (((uint64_t)env->pcc_ofs << 32)
-            | (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 2));
+    qemu_mutex_lock_iothread();
+    pcc = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 2;
+    qemu_mutex_unlock_iothread();
+    return deposit64(pcc, 32, 32, env->pcc_ofs);
 #else
     /* In user-mode, QEMU_CLOCK_VIRTUAL doesn't exist.  Just pass through the host cpu
        clock ticks.  Also, don't bother taking PCC_OFS into account.  */
@@ -68,24 +71,34 @@ void helper_halt(uint64_t restart)
 
 uint64_t helper_get_vmtime(void)
 {
-    return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    uint64_t ret;
+    qemu_mutex_lock_iothread();
+    ret = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    qemu_mutex_unlock_iothread();
+    return ret;
 }
 
 uint64_t helper_get_walltime(void)
 {
-    return qemu_clock_get_ns(rtc_clock);
+    uint64_t ret;
+    qemu_mutex_lock_iothread();
+    ret = qemu_clock_get_ns(rtc_clock);
+    qemu_mutex_unlock_iothread();
+    return ret;
 }
 
 void helper_set_alarm(CPUAlphaState *env, uint64_t expire)
 {
     AlphaCPU *cpu = alpha_env_get_cpu(env);
 
+    qemu_mutex_lock_iothread();
     if (expire) {
         env->alarm_expire = expire;
         timer_mod(cpu->alarm_timer, expire);
     } else {
         timer_del(cpu->alarm_timer);
     }
+    qemu_mutex_unlock_iothread();
 }
 
 #endif /* CONFIG_USER_ONLY */
-- 
2.9.3


Re: [Qemu-devel] [PATCH] target/alpha: Take BQL around clock manipulations
Posted by Paolo Bonzini 7 years, 1 month ago
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
> This is similar to the patch that I saw go by for MIPS.
> 
> I hadn't noticed any problems caused by this lack of locking.  This may
> be because interrupts cannot be delivered while in PALmode while these
> registers are being manipulated.  However, it's always better to obey
> the rules, right?

This should not be necessary, clocks and timers are thread-safe.  Time
to make a list of the few things that are, I guess.

There are issues if data is accessed by device models and CPU out of
the lock, but everything seems fine for typhoon_alarm_timer.

Paolo

> 
> r~
> ---
>  target/alpha/sys_helper.c | 21 +++++++++++++++++----
>  1 file changed, 17 insertions(+), 4 deletions(-)
> 
> diff --git a/target/alpha/sys_helper.c b/target/alpha/sys_helper.c
> index 652195d..6feb30b 100644
> --- a/target/alpha/sys_helper.c
> +++ b/target/alpha/sys_helper.c
> @@ -28,11 +28,14 @@
>  uint64_t helper_load_pcc(CPUAlphaState *env)
>  {
>  #ifndef CONFIG_USER_ONLY
> +    uint64_t pcc;
>      /* In system mode we have access to a decent high-resolution clock.
>         In order to make OS-level time accounting work with the RPCC,
>         present it with a well-timed clock fixed at 250MHz.  */
> -    return (((uint64_t)env->pcc_ofs << 32)
> -            | (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 2));
> +    qemu_mutex_lock_iothread();
> +    pcc = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 2;
> +    qemu_mutex_unlock_iothread();
> +    return deposit64(pcc, 32, 32, env->pcc_ofs);
>  #else
>      /* In user-mode, QEMU_CLOCK_VIRTUAL doesn't exist.  Just pass through
>      the host cpu
>         clock ticks.  Also, don't bother taking PCC_OFS into account.  */
> @@ -68,24 +71,34 @@ void helper_halt(uint64_t restart)
>  
>  uint64_t helper_get_vmtime(void)
>  {
> -    return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> +    uint64_t ret;
> +    qemu_mutex_lock_iothread();
> +    ret = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> +    qemu_mutex_unlock_iothread();
> +    return ret;
>  }
>  
>  uint64_t helper_get_walltime(void)
>  {
> -    return qemu_clock_get_ns(rtc_clock);
> +    uint64_t ret;
> +    qemu_mutex_lock_iothread();
> +    ret = qemu_clock_get_ns(rtc_clock);
> +    qemu_mutex_unlock_iothread();
> +    return ret;
>  }
>  
>  void helper_set_alarm(CPUAlphaState *env, uint64_t expire)
>  {
>      AlphaCPU *cpu = alpha_env_get_cpu(env);
>  
> +    qemu_mutex_lock_iothread();
>      if (expire) {
>          env->alarm_expire = expire;
>          timer_mod(cpu->alarm_timer, expire);
>      } else {
>          timer_del(cpu->alarm_timer);
>      }
> +    qemu_mutex_unlock_iothread();
>  }
>  
>  #endif /* CONFIG_USER_ONLY */
> --
> 2.9.3
> 
> 

Re: [Qemu-devel] [PATCH] target/alpha: Take BQL around clock manipulations
Posted by Richard Henderson 7 years, 1 month ago
On 03/07/2017 08:00 AM, Paolo Bonzini wrote:
>> Signed-off-by: Richard Henderson <rth@twiddle.net>
>> ---
>> This is similar to the patch that I saw go by for MIPS.
>>
>> I hadn't noticed any problems caused by this lack of locking.  This may
>> be because interrupts cannot be delivered while in PALmode while these
>> registers are being manipulated.  However, it's always better to obey
>> the rules, right?
>
> This should not be necessary, clocks and timers are thread-safe.  Time
> to make a list of the few things that are, I guess.
>
> There are issues if data is accessed by device models and CPU out of
> the lock, but everything seems fine for typhoon_alarm_timer.

This isn't typhoon_alarm_timer, but the move-to-special-register instruction on 
the cpu side.

But I guess I misunderstood the problem that was happening for MIPS.
If nothing needs changing for Alpha, that's great.


r~

Re: [Qemu-devel] [PATCH] target/alpha: Take BQL around clock manipulations
Posted by Alex Bennée 7 years, 1 month ago
Richard Henderson <rth@twiddle.net> writes:

> On 03/07/2017 08:00 AM, Paolo Bonzini wrote:
>>> Signed-off-by: Richard Henderson <rth@twiddle.net>
>>> ---
>>> This is similar to the patch that I saw go by for MIPS.
>>>
>>> I hadn't noticed any problems caused by this lack of locking.  This may
>>> be because interrupts cannot be delivered while in PALmode while these
>>> registers are being manipulated.  However, it's always better to obey
>>> the rules, right?
>>
>> This should not be necessary, clocks and timers are thread-safe.  Time
>> to make a list of the few things that are, I guess.
>>
>> There are issues if data is accessed by device models and CPU out of
>> the lock, but everything seems fine for typhoon_alarm_timer.
>
> This isn't typhoon_alarm_timer, but the move-to-special-register
> instruction on the cpu side.
>
> But I guess I misunderstood the problem that was happening for MIPS.
> If nothing needs changing for Alpha, that's great.

Fundamentally the MIPS instructions ended up calling into hw/mips/ which
could then end up triggering an IRQ (at which point the BQL assertion
kicks in).

Basically crossing from target/foo/helper to hw/foo/emulation is the
warning sign that you need to ensure you have appropriate device
emulation locking going on.

Helpers just messing with their own env should be able to continue just
fine.

>
>
> r~


--
Alex Bennée