diff mbox

[RFC,v3,03/19] translate-all: add DEBUG_LOCKING asserts

Message ID 1464986428-6739-4-git-send-email-alex.bennee@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Alex Bennée June 3, 2016, 8:40 p.m. UTC
This adds asserts to check the locking on the various translation
engines structures. There are two sets of structures that are protected
by locks.

The first the l1map and PageDesc structures used to track which
translation blocks are associated with which physical addresses. In
user-mode this is covered by the mmap_lock.

The second case are TB context related structures which are protected by
tb_lock which is also user-mode only.

Currently the asserts do nothing in SoftMMU mode but this will change
for MTTCG.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 bsd-user/mmap.c         |  5 +++++
 include/exec/exec-all.h |  1 +
 linux-user/mmap.c       |  5 +++++
 translate-all.c         | 41 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 52 insertions(+)

Comments

Sergey Fedorov June 23, 2016, 2:34 p.m. UTC | #1
On 03/06/16 23:40, Alex Bennée wrote:
> diff --git a/translate-all.c b/translate-all.c
> index ec6fdbb..e3f44d9 100644
> --- a/translate-all.c
> +++ b/translate-all.c
(snip)
> @@ -60,6 +61,7 @@
>  
>  /* #define DEBUG_TB_INVALIDATE */
>  /* #define DEBUG_TB_FLUSH */
> +/* #define DEBUG_LOCKING */

A bit of bikeshedding: have you considered naming it 'DEBUG_LOCKS'. How
does it sound for a native English speaker? :)

>  /* make various TB consistency checks */
>  /* #define DEBUG_TB_CHECK */
>  
> @@ -68,6 +70,28 @@
>  #undef DEBUG_TB_CHECK
>  #endif
>  
> +/* Access to the various translations structures need to be serialised via locks
> + * for consistency. This is automatic for SoftMMU based system
> + * emulation due to its single threaded nature. In user-mode emulation
> + * access to the memory related structures are protected with the
> + * mmap_lock.
> + */
> +#ifdef DEBUG_LOCKING
> +#define DEBUG_MEM_LOCKS 1
> +#else
> +#define DEBUG_MEM_LOCKS 0
> +#endif
> +
> +#ifdef CONFIG_SOFTMMU
> +#define assert_memory_lock() do { /* nothing */ } while (0)
> +#else
> +#define assert_memory_lock() do {               \
> +        if (DEBUG_MEM_LOCKS) {                  \
> +            g_assert(have_mmap_lock());         \
> +        }                                       \
> +    } while (0)
> +#endif
> +

Why not simply:

#if !defined(DEBUG_LOCKING) || defined(CONFIG_SOFTMMU)
#    define assert_memory_lock() do { /* nothing */ } while (0)
#else
#    define assert_memory_lock() g_assert(have_mmap_lock())
#endif

One more nit: maybe it would be a bit more clear to name it after the
lock name, i.e. assert_mmap_lock(), or check_mmap_lock(), or
debug_mmap_lock() etc?

Thanks,
Sergey
Alex Bennée June 23, 2016, 5:14 p.m. UTC | #2
Sergey Fedorov <serge.fdrv@gmail.com> writes:

> On 03/06/16 23:40, Alex Bennée wrote:
>> diff --git a/translate-all.c b/translate-all.c
>> index ec6fdbb..e3f44d9 100644
>> --- a/translate-all.c
>> +++ b/translate-all.c
> (snip)
>> @@ -60,6 +61,7 @@
>>
>>  /* #define DEBUG_TB_INVALIDATE */
>>  /* #define DEBUG_TB_FLUSH */
>> +/* #define DEBUG_LOCKING */
>
> A bit of bikeshedding: have you considered naming it 'DEBUG_LOCKS'. How
> does it sound for a native English speaker? :)
>
>>  /* make various TB consistency checks */
>>  /* #define DEBUG_TB_CHECK */
>>
>> @@ -68,6 +70,28 @@
>>  #undef DEBUG_TB_CHECK
>>  #endif
>>
>> +/* Access to the various translations structures need to be serialised via locks
>> + * for consistency. This is automatic for SoftMMU based system
>> + * emulation due to its single threaded nature. In user-mode emulation
>> + * access to the memory related structures are protected with the
>> + * mmap_lock.
>> + */
>> +#ifdef DEBUG_LOCKING
>> +#define DEBUG_MEM_LOCKS 1
>> +#else
>> +#define DEBUG_MEM_LOCKS 0
>> +#endif
>> +
>> +#ifdef CONFIG_SOFTMMU
>> +#define assert_memory_lock() do { /* nothing */ } while (0)
>> +#else
>> +#define assert_memory_lock() do {               \
>> +        if (DEBUG_MEM_LOCKS) {                  \
>> +            g_assert(have_mmap_lock());         \
>> +        }                                       \
>> +    } while (0)
>> +#endif
>> +
>
> Why not simply:
>
> #if !defined(DEBUG_LOCKING) || defined(CONFIG_SOFTMMU)
> #    define assert_memory_lock() do { /* nothing */ } while (0)
> #else
> #    define assert_memory_lock() g_assert(have_mmap_lock())
> #endif
>
> One more nit: maybe it would be a bit more clear to name it after the
> lock name, i.e. assert_mmap_lock(), or check_mmap_lock(), or
> debug_mmap_lock() etc?

Yes I can do it that way around. The if (FOO) form makes more sense for
debug output to ensure the compiler checks format strings etc. The
resulting code should be the same either way.

>
> Thanks,
> Sergey


--
Alex Bennée
Sergey Fedorov June 23, 2016, 6:43 p.m. UTC | #3
On 23/06/16 20:14, Alex Bennée wrote:
> Sergey Fedorov <serge.fdrv@gmail.com> writes:
>
>> On 03/06/16 23:40, Alex Bennée wrote:
>>> diff --git a/translate-all.c b/translate-all.c
>>> index ec6fdbb..e3f44d9 100644
>>> --- a/translate-all.c
>>> +++ b/translate-all.c
>> (snip)
>>> @@ -60,6 +61,7 @@
>>>
>>>  /* #define DEBUG_TB_INVALIDATE */
>>>  /* #define DEBUG_TB_FLUSH */
>>> +/* #define DEBUG_LOCKING */
>> A bit of bikeshedding: have you considered naming it 'DEBUG_LOCKS'. How
>> does it sound for a native English speaker? :)
>>
>>>  /* make various TB consistency checks */
>>>  /* #define DEBUG_TB_CHECK */
>>>
>>> @@ -68,6 +70,28 @@
>>>  #undef DEBUG_TB_CHECK
>>>  #endif
>>>
>>> +/* Access to the various translations structures need to be serialised via locks
>>> + * for consistency. This is automatic for SoftMMU based system
>>> + * emulation due to its single threaded nature. In user-mode emulation
>>> + * access to the memory related structures are protected with the
>>> + * mmap_lock.
>>> + */
>>> +#ifdef DEBUG_LOCKING
>>> +#define DEBUG_MEM_LOCKS 1
>>> +#else
>>> +#define DEBUG_MEM_LOCKS 0
>>> +#endif
>>> +
>>> +#ifdef CONFIG_SOFTMMU
>>> +#define assert_memory_lock() do { /* nothing */ } while (0)
>>> +#else
>>> +#define assert_memory_lock() do {               \
>>> +        if (DEBUG_MEM_LOCKS) {                  \
>>> +            g_assert(have_mmap_lock());         \
>>> +        }                                       \
>>> +    } while (0)
>>> +#endif
>>> +
>> Why not simply:
>>
>> #if !defined(DEBUG_LOCKING) || defined(CONFIG_SOFTMMU)
>> #    define assert_memory_lock() do { /* nothing */ } while (0)
>> #else
>> #    define assert_memory_lock() g_assert(have_mmap_lock())
>> #endif
>>
>> One more nit: maybe it would be a bit more clear to name it after the
>> lock name, i.e. assert_mmap_lock(), or check_mmap_lock(), or
>> debug_mmap_lock() etc?
> Yes I can do it that way around. The if (FOO) form makes more sense for
> debug output to ensure the compiler checks format strings etc. The
> resulting code should be the same either way.

You are right, this is a good thing, I just missed it.

Thanks,
Sergey
Richard Henderson July 1, 2016, 11:21 p.m. UTC | #4
On 06/03/2016 01:40 PM, Alex Bennée wrote:
> This adds asserts to check the locking on the various translation
> engines structures. There are two sets of structures that are protected
> by locks.
>
> The first the l1map and PageDesc structures used to track which
> translation blocks are associated with which physical addresses. In
> user-mode this is covered by the mmap_lock.
>
> The second case are TB context related structures which are protected by
> tb_lock which is also user-mode only.
>
> Currently the asserts do nothing in SoftMMU mode but this will change
> for MTTCG.
>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> ---
>  bsd-user/mmap.c         |  5 +++++
>  include/exec/exec-all.h |  1 +
>  linux-user/mmap.c       |  5 +++++
>  translate-all.c         | 41 +++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 52 insertions(+)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~
diff mbox

Patch

diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 6ab5334..4a61ad0 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -43,6 +43,11 @@  void mmap_unlock(void)
     }
 }
 
+bool have_mmap_lock(void)
+{
+    return mmap_lock_count > 0 ? true : false;
+}
+
 /* Grab lock to make sure things are in a consistent state after fork().  */
 void mmap_fork_start(void)
 {
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 70ab361..ea1c925 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -369,6 +369,7 @@  void tlb_fill(CPUState *cpu, target_ulong addr, int is_write, int mmu_idx,
 #if defined(CONFIG_USER_ONLY)
 void mmap_lock(void);
 void mmap_unlock(void);
+bool have_mmap_lock(void);
 
 static inline tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
 {
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 3519147..fd68249 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -44,6 +44,11 @@  void mmap_unlock(void)
     }
 }
 
+bool have_mmap_lock(void)
+{
+    return mmap_lock_count > 0 ? true : false;
+}
+
 /* Grab lock to make sure things are in a consistent state after fork().  */
 void mmap_fork_start(void)
 {
diff --git a/translate-all.c b/translate-all.c
index ec6fdbb..e3f44d9 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -33,6 +33,7 @@ 
 #include "tcg.h"
 #if defined(CONFIG_USER_ONLY)
 #include "qemu.h"
+#include "exec/exec-all.h"
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 #include <sys/param.h>
 #if __FreeBSD_version >= 700104
@@ -60,6 +61,7 @@ 
 
 /* #define DEBUG_TB_INVALIDATE */
 /* #define DEBUG_TB_FLUSH */
+/* #define DEBUG_LOCKING */
 /* make various TB consistency checks */
 /* #define DEBUG_TB_CHECK */
 
@@ -68,6 +70,28 @@ 
 #undef DEBUG_TB_CHECK
 #endif
 
+/* Access to the various translations structures need to be serialised via locks
+ * for consistency. This is automatic for SoftMMU based system
+ * emulation due to its single threaded nature. In user-mode emulation
+ * access to the memory related structures are protected with the
+ * mmap_lock.
+ */
+#ifdef DEBUG_LOCKING
+#define DEBUG_MEM_LOCKS 1
+#else
+#define DEBUG_MEM_LOCKS 0
+#endif
+
+#ifdef CONFIG_SOFTMMU
+#define assert_memory_lock() do { /* nothing */ } while (0)
+#else
+#define assert_memory_lock() do {               \
+        if (DEBUG_MEM_LOCKS) {                  \
+            g_assert(have_mmap_lock());         \
+        }                                       \
+    } while (0)
+#endif
+
 #define SMC_BITMAP_USE_THRESHOLD 10
 
 typedef struct PageDesc {
@@ -155,6 +179,23 @@  void tb_lock_reset(void)
 #endif
 }
 
+#ifdef DEBUG_LOCKING
+#define DEBUG_TB_LOCKS 1
+#else
+#define DEBUG_TB_LOCKS 0
+#endif
+
+#ifdef CONFIG_SOFTMMU
+#define assert_tb_lock() do { /* nothing */ } while (0)
+#else
+#define assert_tb_lock() do {               \
+        if (DEBUG_TB_LOCKS) {               \
+            g_assert(have_tb_lock);         \
+        }                                   \
+    } while (0)
+#endif
+
+
 static TranslationBlock *tb_find_pc(uintptr_t tc_ptr);
 
 void cpu_gen_init(void)