From 738943bfef56f3a94bcd44bedf95207182fcdfe50bedc2d51b14fd70c1a81c2c Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 11 Jul 2012 14:55:34 +0000 Subject: [PATCH] - linux-user: improve locking even across tb flushes OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=93 --- ...-linux-user-lock-tb-flushing-too.pat.patch | 125 ++++++++++++++++++ qemu.changes | 5 + qemu.spec | 2 + 3 files changed, 132 insertions(+) create mode 100644 0027-linux-user-lock-tb-flushing-too.pat.patch diff --git a/0027-linux-user-lock-tb-flushing-too.pat.patch b/0027-linux-user-lock-tb-flushing-too.pat.patch new file mode 100644 index 00000000..854791a9 --- /dev/null +++ b/0027-linux-user-lock-tb-flushing-too.pat.patch @@ -0,0 +1,125 @@ +From 777d50057b576a0d829481a0cea9cd399e7a5f65 Mon Sep 17 00:00:00 2001 +From: Alexander Graf +Date: Wed, 11 Jul 2012 16:47:42 +0200 +Subject: [PATCH] linux-user: lock tb flushing too + +Signed-off-by: Alexander Graf +--- + exec.c | 33 ++++++++++++++++++++++++++------- + 1 files changed, 26 insertions(+), 7 deletions(-) + +diff --git a/exec.c b/exec.c +index 9ba4409..6da4b38 100644 +--- a/exec.c ++++ b/exec.c +@@ -732,17 +732,22 @@ static TranslationBlock *tb_alloc(target_ulong pc) + { + TranslationBlock *tb; + ++ tcg_lock(); + if (nb_tbs >= code_gen_max_blocks || +- (code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size) ++ (code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size) { ++ tcg_unlock(); + return NULL; ++ } + tb = &tbs[nb_tbs++]; + tb->pc = pc; + tb->cflags = 0; ++ tcg_unlock(); + return tb; + } + + void tb_free(TranslationBlock *tb) + { ++ tcg_lock(); + /* In practice this is mostly used for single use temporary TB + Ignore the hard cases and just back up if this TB happens to + be the last one generated. */ +@@ -750,6 +755,7 @@ void tb_free(TranslationBlock *tb) + code_gen_ptr = tb->tc_ptr; + nb_tbs--; + } ++ tcg_unlock(); + } + + static inline void invalidate_page_bitmap(PageDesc *p) +@@ -803,6 +809,7 @@ void tb_flush(CPUArchState *env1) + nb_tbs, nb_tbs > 0 ? + ((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0); + #endif ++ tcg_lock(); + if ((unsigned long)(code_gen_ptr - code_gen_buffer) > code_gen_buffer_size) + cpu_abort(env1, "Internal error: code buffer overflow\n"); + +@@ -819,6 +826,7 @@ void tb_flush(CPUArchState *env1) + /* XXX: flush processor icache at this point if cache flush is + expensive */ + tb_flush_count++; ++ tcg_unlock(); + } + + #ifdef DEBUG_TB_CHECK +@@ -1116,9 +1124,12 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, + int current_flags = 0; + #endif /* TARGET_HAS_PRECISE_SMC */ + ++ tcg_lock(); + p = page_find(start >> TARGET_PAGE_BITS); +- if (!p) ++ if (!p) { ++ tcg_unlock(); + return; ++ } + if (!p->code_bitmap && + ++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD && + is_cpu_write_access) { +@@ -1202,6 +1213,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, + cpu_resume_from_signal(env, NULL); + } + #endif ++ tcg_unlock(); + } + + /* len must be <= 8 and start must be a multiple of len */ +@@ -1397,12 +1409,16 @@ TranslationBlock *tb_find_pc(uintptr_t tc_ptr) + { + int m_min, m_max, m; + uintptr_t v; +- TranslationBlock *tb; ++ TranslationBlock *tb, *r; + +- if (nb_tbs <= 0) ++ tcg_lock(); ++ if (nb_tbs <= 0) { ++ tcg_unlock(); + return NULL; ++ } + if (tc_ptr < (uintptr_t)code_gen_buffer || + tc_ptr >= (uintptr_t)code_gen_ptr) { ++ tcg_unlock(); + return NULL; + } + /* binary search (cf Knuth) */ +@@ -1412,15 +1428,18 @@ TranslationBlock *tb_find_pc(uintptr_t tc_ptr) + m = (m_min + m_max) >> 1; + tb = &tbs[m]; + v = (uintptr_t)tb->tc_ptr; +- if (v == tc_ptr) ++ if (v == tc_ptr) { ++ tcg_unlock(); + return tb; +- else if (tc_ptr < v) { ++ } else if (tc_ptr < v) { + m_max = m - 1; + } else { + m_min = m + 1; + } + } +- return &tbs[m_max]; ++ r = &tbs[m_max]; ++ tcg_unlock(); ++ return r; + } + + static void tb_reset_jump_recursive(TranslationBlock *tb); diff --git a/qemu.changes b/qemu.changes index d2968a5b..868994fe 100644 --- a/qemu.changes +++ b/qemu.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Wed Jul 11 14:52:02 UTC 2012 - agraf@suse.com + +- linux-user: improve locking even across tb flushes + ------------------------------------------------------------------- Tue Jul 10 18:43:31 UTC 2012 - agraf@suse.com diff --git a/qemu.spec b/qemu.spec index de01fe0c..00e95454 100644 --- a/qemu.spec +++ b/qemu.spec @@ -50,6 +50,7 @@ Patch0023: 0023-linux-user-Ignore-broken-loop-ioctl.patch Patch0024: 0024-linux-user-fix-segmentation-fault-p.patch Patch0025: 0025-linux-user-lock-tcg.patch.patch Patch0026: 0026-linux-user-Run-multi-threaded-code-.patch +Patch0027: 0027-linux-user-lock-tb-flushing-too.pat.patch # this is to make lint happy Source300: rpmlintrc Source302: bridge.conf @@ -183,6 +184,7 @@ run cross-architecture builds. %patch0024 -p1 %patch0025 -p1 %patch0026 -p1 +%patch0027 -p1 %build # build QEMU