All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18
@ 2016-07-18  9:27 Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 01/23] use g_path_get_dirname instead of dirname Paolo Bonzini
                   ` (23 more replies)
  0 siblings, 24 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel

The following changes since commit 6b92bbfe812746fe7841a24c24e6460f5359ce72:

  Merge remote-tracking branch 'remotes/mcayland/tags/qemu-openbios-signed' into staging (2016-07-15 16:56:08 +0100)

are available in the git repository at:

  git://github.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to 6e5532eb16b1fcc7b6d5a15bc5fc0089c1f776f0:

  block/iscsi: allow caching of the allocation map (2016-07-18 11:19:47 +0200)

----------------------------------------------------------------
* tb_lock-less
* two old patches from prospective GSoC students
* i386 -kernel device tree support
* Coverity fix
* memory usage improvement from Peter
* checkpatch fix
* g_path_get_dirname cleanup
* caching of block status for iSCSI

----------------------------------------------------------------
Alex Bennée (2):
      tcg: set up tb->page_addr before insertion
      tcg: cpu-exec: remove tb_lock from the hot-path

Antonio Borneo (1):
      hw/i386: add device tree support

Md Haris Iqbal (1):
      Changed malloc to g_malloc, free to g_free in bsd-user/qemu.h

Paolo Bonzini (3):
      compiler: never omit assertions if using a static analysis tool
      megasas: remove useless check for cmd->frame
      util/qht: Document memory ordering assumptions

Peter Lieven (3):
      exec: avoid realloc in phys_map_node_reserve
      block/iscsi: fix rounding in iscsi_allocationmap_set
      block/iscsi: allow caching of the allocation map

Pranith Kumar (1):
      Move README to markdown

Sergey Fedorov (10):
      cpu-exec: Move down some declarations in cpu_exec()
      tcg: Pass last_tb by value to tb_find_fast()
      tcg: Prepare safe tb_jmp_cache lookup out of tb_lock
      tcg: Prepare safe access to tb_flushed out of tb_lock
      target-i386: Remove redundant HF_SOFTMMU_MASK
      tcg: Introduce tb_mark_invalid() and tb_is_invalid()
      tcg: Prepare TB invalidation for lockless TB lookup
      tcg: Avoid bouncing tb_lock between tb_gen_code() and tb_add_jump()
      tcg: Merge tb_find_slow() and tb_find_fast()
      tcg: rename tb_find_physical()

Stefan Hajnoczi (1):
      checkpatch: consider git extended headers valid patches

Wei Jiangang (1):
      use g_path_get_dirname instead of dirname

 README => README.md      |  41 ++++----
 block/iscsi.c            | 248 ++++++++++++++++++++++++++++++++++++-----------
 bsd-user/qemu.h          |   4 +-
 cpu-exec.c               | 124 +++++++++++-------------
 exec.c                   |   4 +-
 hw/i386/pc.c             |  46 +++++++++
 hw/scsi/megasas.c        |   6 +-
 include/exec/exec-all.h  |  16 +++
 include/qemu/compiler.h  |   3 +
 include/qemu/qht.h       |   5 +
 os-posix.c               |   3 +-
 scripts/checkpatch.pl    |   5 +
 target-alpha/cpu.h       |  14 +++
 target-arm/cpu.h         |  14 +++
 target-cris/cpu.h        |  14 +++
 target-i386/cpu.c        |   3 -
 target-i386/cpu.h        |  20 +++-
 target-i386/translate.c  |  12 +--
 target-lm32/cpu.h        |  14 +++
 target-m68k/cpu.h        |  14 +++
 target-microblaze/cpu.h  |  14 +++
 target-mips/cpu.h        |  14 +++
 target-moxie/cpu.h       |  14 +++
 target-openrisc/cpu.h    |  14 +++
 target-ppc/cpu.h         |  14 +++
 target-s390x/cpu.h       |  14 +++
 target-sh4/cpu.h         |  14 +++
 target-sparc/cpu.h       |  14 +++
 target-sparc/translate.c |   1 +
 target-tilegx/cpu.h      |  14 +++
 target-tricore/cpu.h     |  14 +++
 target-unicore32/cpu.h   |  14 +++
 target-xtensa/cpu.h      |  14 +++
 tcg/tcg.h                |   2 +-
 translate-all.c          |  29 +++---
 util/oslib-posix.c       |   4 +-
 util/qht.c               |   7 +-
 37 files changed, 633 insertions(+), 188 deletions(-)
 rename README => README.md (85%)
-- 
2.7.4

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 01/23] use g_path_get_dirname instead of dirname
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 02/23] Changed malloc to g_malloc, free to g_free in bsd-user/qemu.h Paolo Bonzini
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Wei Jiangang

From: Wei Jiangang <weijg.fnst@cn.fujitsu.com>

Use g_path_get_basename to get the directory components of
a file name, and free its return when no longer needed.

Signed-off-by: Wei Jiangang <weijg.fnst@cn.fujitsu.com>
Message-Id: <1459997185-15669-3-git-send-email-weijg.fnst@cn.fujitsu.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 os-posix.c         | 3 ++-
 util/oslib-posix.c | 4 +++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/os-posix.c b/os-posix.c
index 3755265..c6ddb7d 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -89,7 +89,7 @@ char *os_find_datadir(void)
     if (exec_dir == NULL) {
         return NULL;
     }
-    dir = dirname(exec_dir);
+    dir = g_path_get_dirname(exec_dir);
 
     max_len = strlen(dir) +
         MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
@@ -103,6 +103,7 @@ char *os_find_datadir(void)
         }
     }
 
+    g_free(dir);
     g_free(exec_dir);
     return res;
 }
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index d8e5dcf..6d70d9a 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -299,9 +299,11 @@ void qemu_init_exec_dir(const char *argv0)
             return;
         }
     }
-    dir = dirname(p);
+    dir = g_path_get_dirname(p);
 
     pstrcpy(exec_dir, sizeof(exec_dir), dir);
+
+    g_free(dir);
 }
 
 char *qemu_get_exec_dir(void)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 02/23] Changed malloc to g_malloc, free to g_free in bsd-user/qemu.h
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 01/23] use g_path_get_dirname instead of dirname Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 03/23] hw/i386: add device tree support Paolo Bonzini
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Md Haris Iqbal

From: Md Haris Iqbal <haris.phnx@gmail.com>

Signed-off-by: Md Haris Iqbal <haris.phnx@gmail.com>
Message-Id: <1459861743-4514-1-git-send-email-haris.phnx@gmail.com>
Reviewed-by: Sean Bruno <sbruno@freebsd.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 bsd-user/qemu.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 53163b8..6ccc544 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -358,7 +358,7 @@ static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy
 #ifdef DEBUG_REMAP
     {
         void *addr;
-        addr = malloc(len);
+        addr = g_malloc(len);
         if (copy)
             memcpy(addr, g2h(guest_addr), len);
         else
@@ -384,7 +384,7 @@ static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
         return;
     if (len > 0)
         memcpy(g2h(guest_addr), host_ptr, len);
-    free(host_ptr);
+    g_free(host_ptr);
 #endif
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 03/23] hw/i386: add device tree support
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 01/23] use g_path_get_dirname instead of dirname Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 02/23] Changed malloc to g_malloc, free to g_free in bsd-user/qemu.h Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 04/23] compiler: never omit assertions if using a static analysis tool Paolo Bonzini
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Antonio Borneo, Sebastian Andrzej Siewior

From: Antonio Borneo <borneo.antonio@gmail.com>

With "-dtb" on command-line:
- append the device tree blob to the kernel image;
- pass the blob's pointer to the kernel through setup_data, as
  requested by upstream kernel commit da6b737b9ab7 ("x86: Add
  device tree support").

The device tree blob is passed as-is to the guest; none of its
fields is modified nor updated. This is not an issue; the kernel
commit above uses the device tree only as an extension to the
traditional kernel configuration.

To: "Michael S. Tsirkin" <mst@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
To: Richard Henderson <rth@twiddle.net>
To: Eduardo Habkost <ehabkost@redhat.com>
Cc: qemu-devel@nongnu.org
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Message-Id: <1459973054-2777-1-git-send-email-borneo.antonio@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/pc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 1b8baa8..719884f 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -812,11 +812,26 @@ static long get_file_size(FILE *f)
     return size;
 }
 
+/* setup_data types */
+#define SETUP_NONE     0
+#define SETUP_E820_EXT 1
+#define SETUP_DTB      2
+#define SETUP_PCI      3
+#define SETUP_EFI      4
+
+struct setup_data {
+    uint64_t next;
+    uint32_t type;
+    uint32_t len;
+    uint8_t data[0];
+} __attribute__((packed));
+
 static void load_linux(PCMachineState *pcms,
                        FWCfgState *fw_cfg)
 {
     uint16_t protocol;
     int setup_size, kernel_size, initrd_size = 0, cmdline_size;
+    int dtb_size, setup_data_offset;
     uint32_t initrd_max;
     uint8_t header[8192], *setup, *kernel, *initrd_data;
     hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0;
@@ -824,8 +839,10 @@ static void load_linux(PCMachineState *pcms,
     char *vmode;
     MachineState *machine = MACHINE(pcms);
     PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
+    struct setup_data *setup_data;
     const char *kernel_filename = machine->kernel_filename;
     const char *initrd_filename = machine->initrd_filename;
+    const char *dtb_filename = machine->dtb;
     const char *kernel_cmdline = machine->kernel_cmdline;
 
     /* Align to 16 bytes as a paranoia measure */
@@ -988,6 +1005,35 @@ static void load_linux(PCMachineState *pcms,
         exit(1);
     }
     fclose(f);
+
+    /* append dtb to kernel */
+    if (dtb_filename) {
+        if (protocol < 0x209) {
+            fprintf(stderr, "qemu: Linux kernel too old to load a dtb\n");
+            exit(1);
+        }
+
+        dtb_size = get_image_size(dtb_filename);
+        if (dtb_size <= 0) {
+            fprintf(stderr, "qemu: error reading dtb %s: %s\n",
+                    dtb_filename, strerror(errno));
+            exit(1);
+        }
+
+        setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
+        kernel_size = setup_data_offset + sizeof(struct setup_data) + dtb_size;
+        kernel = g_realloc(kernel, kernel_size);
+
+        stq_p(header+0x250, prot_addr + setup_data_offset);
+
+        setup_data = (struct setup_data *)(kernel + setup_data_offset);
+        setup_data->next = 0;
+        setup_data->type = cpu_to_le32(SETUP_DTB);
+        setup_data->len = cpu_to_le32(dtb_size);
+
+        load_image_size(dtb_filename, setup_data->data, dtb_size);
+    }
+
     memcpy(setup, header, MIN(sizeof(header), setup_size));
 
     fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 04/23] compiler: never omit assertions if using a static analysis tool
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (2 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 03/23] hw/i386: add device tree support Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 05/23] megasas: remove useless check for cmd->frame Paolo Bonzini
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel

Assertions help both Coverity and the clang static analyzer avoid
false positives, but on the other hand both are confused when
the condition is compiled as (void)(x != FOO).  Always expand
assertion macros when using Coverity or clang, through a new
QEMU_STATIC_ANALYSIS preprocessor symbol.

This fixes a couple false positives in TCG.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/compiler.h | 3 +++
 tcg/tcg.h               | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
index b64f899..338d3a6 100644
--- a/include/qemu/compiler.h
+++ b/include/qemu/compiler.h
@@ -3,6 +3,9 @@
 #ifndef COMPILER_H
 #define COMPILER_H
 
+#if defined __clang_analyzer__ || defined __COVERITY__
+#define QEMU_STATIC_ANALYSIS 1
+#endif
 
 /*----------------------------------------------------------------------------
 | The macro QEMU_GNUC_PREREQ tests for minimum version of the GNU C compiler.
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 66ae0c7..6046dcd 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -191,7 +191,7 @@ typedef uint64_t tcg_insn_unit;
 #endif
 
 
-#ifdef CONFIG_DEBUG_TCG
+#if defined CONFIG_DEBUG_TCG || defined QEMU_STATIC_ANALYSIS
 # define tcg_debug_assert(X) do { assert(X); } while (0)
 #elif QEMU_GNUC_PREREQ(4, 5)
 # define tcg_debug_assert(X) \
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 05/23] megasas: remove useless check for cmd->frame
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (3 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 04/23] compiler: never omit assertions if using a static analysis tool Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 06/23] checkpatch: consider git extended headers valid patches Paolo Bonzini
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel

megasas_enqueue_frame always returns with non-NULL cmd->frame.
Remove the "else" part as it is dead code.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/megasas.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 52a4123..e968302 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -1981,11 +1981,7 @@ static void megasas_handle_frame(MegasasState *s, uint64_t frame_addr,
         break;
     }
     if (frame_status != MFI_STAT_INVALID_STATUS) {
-        if (cmd->frame) {
-            cmd->frame->header.cmd_status = frame_status;
-        } else {
-            megasas_frame_set_cmd_status(s, frame_addr, frame_status);
-        }
+        cmd->frame->header.cmd_status = frame_status;
         megasas_unmap_frame(s, cmd);
         megasas_complete_frame(s, cmd->context);
     }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 06/23] checkpatch: consider git extended headers valid patches
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (4 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 05/23] megasas: remove useless check for cmd->frame Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 07/23] exec: avoid realloc in phys_map_node_reserve Paolo Bonzini
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Stefan Hajnoczi

From: Stefan Hajnoczi <stefanha@redhat.com>

Renames look like this with git-diff(1) when diff.renames = true is set:

  diff --git a/a b/b
  similarity index 100%
  rename from a
  rename to b

This raises the "Does not appear to be a unified-diff format patch"
error because checkpatch.pl only considers a diff valid if it contains
at least one "@@" hunk.

This patch accepts renames and copies too so that checkpatch.pl exits
successfully when a diff only renames/copies files.  The git diff
extended header format is described on the git-diff(1) man page.

Reported-by: Colin Lord <clord@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <1468576014-28788-1-git-send-email-stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 scripts/checkpatch.pl | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index cf32c8f..afa7f79 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1279,6 +1279,11 @@ sub process {
 			}
 		}
 
+# Accept git diff extended headers as valid patches
+		if ($line =~ /^(?:rename|copy) (?:from|to) [\w\/\.\-]+\s*$/) {
+			$is_patch = 1;
+		}
+
 #check the patch for a signoff:
 		if ($line =~ /^\s*signed-off-by:/i) {
 			# This is a signoff, if ugly, so do not double report.
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 07/23] exec: avoid realloc in phys_map_node_reserve
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (5 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 06/23] checkpatch: consider git extended headers valid patches Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 08/23] cpu-exec: Move down some declarations in cpu_exec() Paolo Bonzini
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Lieven

From: Peter Lieven <pl@kamp.de>

this is the first step in reducing the brk heap fragmentation
created by the map->nodes memory allocation. Since the introduction
of RCU the freeing of the PhysPageMaps is delayed so that sometimes
several hundred are allocated at the same time.

Even worse the memory for map->nodes is allocated and shortly
afterwards reallocated. Since the number of nodes it grows
to in the end is the same for all PhysPageMaps remember this value
and at least avoid the reallocation.

The large number of simultaneous allocations (about 450 x 70kB in
my configuration) has to be addressed later.

Signed-off-by: Peter Lieven <pl@kamp.de>
Message-Id: <1468577030-21097-1-git-send-email-pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 exec.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/exec.c b/exec.c
index 011babd..60cf46a 100644
--- a/exec.c
+++ b/exec.c
@@ -187,10 +187,12 @@ struct CPUAddressSpace {
 
 static void phys_map_node_reserve(PhysPageMap *map, unsigned nodes)
 {
+    static unsigned alloc_hint = 16;
     if (map->nodes_nb + nodes > map->nodes_nb_alloc) {
-        map->nodes_nb_alloc = MAX(map->nodes_nb_alloc * 2, 16);
+        map->nodes_nb_alloc = MAX(map->nodes_nb_alloc, alloc_hint);
         map->nodes_nb_alloc = MAX(map->nodes_nb_alloc, map->nodes_nb + nodes);
         map->nodes = g_renew(Node, map->nodes, map->nodes_nb_alloc);
+        alloc_hint = map->nodes_nb_alloc;
     }
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 08/23] cpu-exec: Move down some declarations in cpu_exec()
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (6 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 07/23] exec: avoid realloc in phys_map_node_reserve Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 09/23] util/qht: Document memory ordering assumptions Paolo Bonzini
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Fedorov, Sergey Fedorov

From: Sergey Fedorov <serge.fdrv@gmail.com>

This will fix a compiler warning with -Wclobbered:

http://lists.nongnu.org/archive/html/qemu-devel/2016-07/msg03347.html

Reported-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Message-Id: <20160715193123.28113-1-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpu-exec.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index b840e1d..5d9710a 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -608,17 +608,16 @@ int cpu_exec(CPUState *cpu)
     init_delay_params(&sc, cpu);
 
     for(;;) {
-        TranslationBlock *tb, *last_tb;
-        int tb_exit = 0;
-
         /* prepare setjmp context for exception handling */
         if (sigsetjmp(cpu->jmp_env, 0) == 0) {
+            TranslationBlock *tb, *last_tb = NULL;
+            int tb_exit = 0;
+
             /* if an exception is pending, we execute it here */
             if (cpu_handle_exception(cpu, &ret)) {
                 break;
             }
 
-            last_tb = NULL; /* forget the last executed TB after exception */
             cpu->tb_flushed = false; /* reset before first TB lookup */
             for(;;) {
                 cpu_handle_interrupt(cpu, &last_tb);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 09/23] util/qht: Document memory ordering assumptions
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (7 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 08/23] cpu-exec: Move down some declarations in cpu_exec() Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 10/23] tcg: Pass last_tb by value to tb_find_fast() Paolo Bonzini
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Fedorov

It is naturally expected that some memory ordering should be provided
around qht_insert() and qht_lookup(). Document these assumptions in the
header file and put some comments in the source to denote how that
memory ordering requirements are fulfilled.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[Sergey Fedorov: commit title and message provided;
comment on qht_remove() elided]
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Message-Id: <20160715175852.30749-2-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/qht.h | 5 +++++
 util/qht.c         | 7 ++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/include/qemu/qht.h b/include/qemu/qht.h
index 70bfc68..311139b 100644
--- a/include/qemu/qht.h
+++ b/include/qemu/qht.h
@@ -69,6 +69,9 @@ void qht_destroy(struct qht *ht);
  * Attempting to insert a NULL @p is a bug.
  * Inserting the same pointer @p with different @hash values is a bug.
  *
+ * In case of successful operation, smp_wmb() is implied before the pointer is
+ * inserted into the hash table.
+ *
  * Returns true on sucess.
  * Returns false if the @p-@hash pair already exists in the hash table.
  */
@@ -83,6 +86,8 @@ bool qht_insert(struct qht *ht, void *p, uint32_t hash);
  *
  * Needs to be called under an RCU read-critical section.
  *
+ * smp_read_barrier_depends() is implied before the call to @func.
+ *
  * The user-provided @func compares pointers in QHT against @userp.
  * If the function returns true, a match has been found.
  *
diff --git a/util/qht.c b/util/qht.c
index 40d6e21..28ce289 100644
--- a/util/qht.c
+++ b/util/qht.c
@@ -445,7 +445,11 @@ void *qht_do_lookup(struct qht_bucket *head, qht_lookup_func_t func,
     do {
         for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
             if (b->hashes[i] == hash) {
-                void *p = atomic_read(&b->pointers[i]);
+                /* The pointer is dereferenced before seqlock_read_retry,
+                 * so (unlike qht_insert__locked) we need to use
+                 * atomic_rcu_read here.
+                 */
+                void *p = atomic_rcu_read(&b->pointers[i]);
 
                 if (likely(p) && likely(func(p, userp))) {
                     return p;
@@ -535,6 +539,7 @@ static bool qht_insert__locked(struct qht *ht, struct qht_map *map,
         atomic_rcu_set(&prev->next, b);
     }
     b->hashes[i] = hash;
+    /* smp_wmb() implicit in seqlock_write_begin.  */
     atomic_set(&b->pointers[i], p);
     seqlock_write_end(&head->sequence);
     return true;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 10/23] tcg: Pass last_tb by value to tb_find_fast()
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (8 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 09/23] util/qht: Document memory ordering assumptions Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 11/23] tcg: Prepare safe tb_jmp_cache lookup out of tb_lock Paolo Bonzini
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Fedorov, Sergey Fedorov

From: Sergey Fedorov <serge.fdrv@gmail.com>

This is a small clean up. tb_find_fast() is a final consumer of this
variable so no need to pass it by reference. 'last_tb' is always updated
by subsequent cpu_loop_exec_tb() in cpu_exec().

This change also simplifies calling cpu_exec_nocache() in
cpu_handle_exception().

Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Message-Id: <20160715175852.30749-3-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpu-exec.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 5d9710a..cf511f1 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -320,7 +320,7 @@ found:
 }
 
 static inline TranslationBlock *tb_find_fast(CPUState *cpu,
-                                             TranslationBlock **last_tb,
+                                             TranslationBlock *last_tb,
                                              int tb_exit)
 {
     CPUArchState *env = (CPUArchState *)cpu->env_ptr;
@@ -342,7 +342,7 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
         /* Ensure that no TB jump will be modified as the
          * translation buffer has been flushed.
          */
-        *last_tb = NULL;
+        last_tb = NULL;
         cpu->tb_flushed = false;
     }
 #ifndef CONFIG_USER_ONLY
@@ -351,12 +351,12 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
      * spanning two pages because the mapping for the second page can change.
      */
     if (tb->page_addr[1] != -1) {
-        *last_tb = NULL;
+        last_tb = NULL;
     }
 #endif
     /* See if we can patch the calling TB. */
-    if (*last_tb && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
-        tb_add_jump(*last_tb, tb_exit, tb);
+    if (last_tb && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
+        tb_add_jump(last_tb, tb_exit, tb);
     }
     tb_unlock();
     return tb;
@@ -437,8 +437,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
     } else if (replay_has_exception()
                && cpu->icount_decr.u16.low + cpu->icount_extra == 0) {
         /* try to cause an exception pending in the log */
-        TranslationBlock *last_tb = NULL; /* Avoid chaining TBs */
-        cpu_exec_nocache(cpu, 1, tb_find_fast(cpu, &last_tb, 0), true);
+        cpu_exec_nocache(cpu, 1, tb_find_fast(cpu, NULL, 0), true);
         *ret = -1;
         return true;
 #endif
@@ -621,7 +620,7 @@ int cpu_exec(CPUState *cpu)
             cpu->tb_flushed = false; /* reset before first TB lookup */
             for(;;) {
                 cpu_handle_interrupt(cpu, &last_tb);
-                tb = tb_find_fast(cpu, &last_tb, tb_exit);
+                tb = tb_find_fast(cpu, last_tb, tb_exit);
                 cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit, &sc);
                 /* Try to align the host and virtual clocks
                    if the guest is in advance */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 11/23] tcg: Prepare safe tb_jmp_cache lookup out of tb_lock
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (9 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 10/23] tcg: Pass last_tb by value to tb_find_fast() Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 12/23] tcg: Prepare safe access to tb_flushed " Paolo Bonzini
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Fedorov, Alex Bennée, Sergey Fedorov

From: Sergey Fedorov <serge.fdrv@gmail.com>

Ensure atomicity of CPU's 'tb_jmp_cache' access for future translation
block lookup out of 'tb_lock'.

Note that this patch does *not* make CPU's TLB invalidation safe if it
is done from some other thread while the CPU is in its execution loop.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20160715175852.30749-4-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpu-exec.c      |  4 ++--
 translate-all.c | 10 +++++++---
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index cf511f1..d48ef5e 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -315,7 +315,7 @@ static TranslationBlock *tb_find_slow(CPUState *cpu,
 
 found:
     /* we add the TB in the virtual pc hash table */
-    cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
+    atomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb);
     return tb;
 }
 
@@ -333,7 +333,7 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
        is executed. */
     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
     tb_lock();
-    tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
+    tb = atomic_read(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]);
     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
                  tb->flags != flags)) {
         tb = tb_find_slow(cpu, pc, cs_base, flags);
diff --git a/translate-all.c b/translate-all.c
index 0d47c1c..fdf520a 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -848,7 +848,11 @@ void tb_flush(CPUState *cpu)
     tcg_ctx.tb_ctx.nb_tbs = 0;
 
     CPU_FOREACH(cpu) {
-        memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
+        int i;
+
+        for (i = 0; i < TB_JMP_CACHE_SIZE; ++i) {
+            atomic_set(&cpu->tb_jmp_cache[i], NULL);
+        }
         cpu->tb_flushed = true;
     }
 
@@ -1007,8 +1011,8 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
     /* remove the TB from the hash list */
     h = tb_jmp_cache_hash_func(tb->pc);
     CPU_FOREACH(cpu) {
-        if (cpu->tb_jmp_cache[h] == tb) {
-            cpu->tb_jmp_cache[h] = NULL;
+        if (atomic_read(&cpu->tb_jmp_cache[h]) == tb) {
+            atomic_set(&cpu->tb_jmp_cache[h], NULL);
         }
     }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 12/23] tcg: Prepare safe access to tb_flushed out of tb_lock
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (10 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 11/23] tcg: Prepare safe tb_jmp_cache lookup out of tb_lock Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 13/23] target-i386: Remove redundant HF_SOFTMMU_MASK Paolo Bonzini
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Fedorov, Sergey Fedorov

From: Sergey Fedorov <serge.fdrv@gmail.com>

Ensure atomicity and ordering of CPU's 'tb_flushed' access for future
translation block lookup out of 'tb_lock'.

This field can only be touched from another thread by tb_flush() in user
mode emulation. So the only access to be sequential atomic is:
 * a single write in tb_flush();
 * reads/writes out of 'tb_lock'.

In future, before enabling MTTCG in system mode, tb_flush() must be safe
and this field becomes unnecessary.

Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20160715175852.30749-5-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpu-exec.c      | 16 +++++++---------
 translate-all.c |  4 ++--
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index d48ef5e..9cf1390 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -338,13 +338,6 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
                  tb->flags != flags)) {
         tb = tb_find_slow(cpu, pc, cs_base, flags);
     }
-    if (cpu->tb_flushed) {
-        /* Ensure that no TB jump will be modified as the
-         * translation buffer has been flushed.
-         */
-        last_tb = NULL;
-        cpu->tb_flushed = false;
-    }
 #ifndef CONFIG_USER_ONLY
     /* We don't take care of direct jumps when address mapping changes in
      * system emulation. So it's not safe to make a direct jump to a TB
@@ -356,7 +349,12 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
 #endif
     /* See if we can patch the calling TB. */
     if (last_tb && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
-        tb_add_jump(last_tb, tb_exit, tb);
+        /* Check if translation buffer has been flushed */
+        if (cpu->tb_flushed) {
+            cpu->tb_flushed = false;
+        } else {
+            tb_add_jump(last_tb, tb_exit, tb);
+        }
     }
     tb_unlock();
     return tb;
@@ -617,7 +615,7 @@ int cpu_exec(CPUState *cpu)
                 break;
             }
 
-            cpu->tb_flushed = false; /* reset before first TB lookup */
+            atomic_mb_set(&cpu->tb_flushed, false); /* reset before first TB lookup */
             for(;;) {
                 cpu_handle_interrupt(cpu, &last_tb);
                 tb = tb_find_fast(cpu, last_tb, tb_exit);
diff --git a/translate-all.c b/translate-all.c
index fdf520a..788fed1 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -845,7 +845,6 @@ void tb_flush(CPUState *cpu)
         > tcg_ctx.code_gen_buffer_size) {
         cpu_abort(cpu, "Internal error: code buffer overflow\n");
     }
-    tcg_ctx.tb_ctx.nb_tbs = 0;
 
     CPU_FOREACH(cpu) {
         int i;
@@ -853,9 +852,10 @@ void tb_flush(CPUState *cpu)
         for (i = 0; i < TB_JMP_CACHE_SIZE; ++i) {
             atomic_set(&cpu->tb_jmp_cache[i], NULL);
         }
-        cpu->tb_flushed = true;
+        atomic_mb_set(&cpu->tb_flushed, true);
     }
 
+    tcg_ctx.tb_ctx.nb_tbs = 0;
     qht_reset_size(&tcg_ctx.tb_ctx.htable, CODE_GEN_HTABLE_SIZE);
     page_flush_tb();
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 13/23] target-i386: Remove redundant HF_SOFTMMU_MASK
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (11 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 12/23] tcg: Prepare safe access to tb_flushed " Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 14/23] tcg: Introduce tb_mark_invalid() and tb_is_invalid() Paolo Bonzini
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Fedorov, Sergey Fedorov

From: Sergey Fedorov <serge.fdrv@gmail.com>

'HF_SOFTMMU_MASK' is only set when 'CONFIG_SOFTMMU' is defined. So
there's no need in this flag: test 'CONFIG_SOFTMMU' instead.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20160715175852.30749-6-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-i386/cpu.c       |  3 ---
 target-i386/cpu.h       |  3 ---
 target-i386/translate.c | 12 ++++--------
 3 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index fc209ee..6e49e4c 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2725,9 +2725,6 @@ static void x86_cpu_reset(CPUState *s)
 
     /* init to reset state */
 
-#ifdef CONFIG_SOFTMMU
-    env->hflags |= HF_SOFTMMU_MASK;
-#endif
     env->hflags2 |= HF2_GIF_MASK;
 
     cpu_x86_update_cr0(env, 0x60000010);
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 776efe6..5b14a72 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -130,8 +130,6 @@
    positions to ease oring with eflags. */
 /* current cpl */
 #define HF_CPL_SHIFT         0
-/* true if soft mmu is being used */
-#define HF_SOFTMMU_SHIFT     2
 /* true if hardware interrupts must be disabled for next instruction */
 #define HF_INHIBIT_IRQ_SHIFT 3
 /* 16 or 32 segments */
@@ -161,7 +159,6 @@
 #define HF_MPX_IU_SHIFT     26 /* BND registers in-use */
 
 #define HF_CPL_MASK          (3 << HF_CPL_SHIFT)
-#define HF_SOFTMMU_MASK      (1 << HF_SOFTMMU_SHIFT)
 #define HF_INHIBIT_IRQ_MASK  (1 << HF_INHIBIT_IRQ_SHIFT)
 #define HF_CS32_MASK         (1 << HF_CS32_SHIFT)
 #define HF_SS32_MASK         (1 << HF_SS32_SHIFT)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 7dea18b..e81fce7 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8224,9 +8224,9 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
     dc->popl_esp_hack = 0;
     /* select memory access functions */
     dc->mem_index = 0;
-    if (flags & HF_SOFTMMU_MASK) {
-	dc->mem_index = cpu_mmu_index(env, false);
-    }
+#ifdef CONFIG_SOFTMMU
+    dc->mem_index = cpu_mmu_index(env, false);
+#endif
     dc->cpuid_features = env->features[FEAT_1_EDX];
     dc->cpuid_ext_features = env->features[FEAT_1_ECX];
     dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
@@ -8239,11 +8239,7 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
 #endif
     dc->flags = flags;
     dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
-                    (flags & HF_INHIBIT_IRQ_MASK)
-#ifndef CONFIG_SOFTMMU
-                    || (flags & HF_SOFTMMU_MASK)
-#endif
-                    );
+                    (flags & HF_INHIBIT_IRQ_MASK));
     /* Do not optimize repz jumps at all in icount mode, because
        rep movsS instructions are execured with different paths
        in !repz_opt and repz_opt modes. The first one was used
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 14/23] tcg: Introduce tb_mark_invalid() and tb_is_invalid()
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (12 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 13/23] target-i386: Remove redundant HF_SOFTMMU_MASK Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 15/23] tcg: Prepare TB invalidation for lockless TB lookup Paolo Bonzini
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Fedorov, Sergey Fedorov

From: Sergey Fedorov <serge.fdrv@gmail.com>

These functions will be used to make translation block invalidation safe
with concurrent lockless lookup in the global hash table.

Most targets don't use 'cs_base'; so marking TB as invalid is as simple
as assigning -1 to 'cs_base'. SPARC target stores the next program
counter into 'cs_base', and -1 is a fine invalid value since PC must be
a multiple of 4 in SPARC. The only odd target is i386, for which a
special flag is introduced in place of removed 'HF_SOFTMMU_MASK'.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20160715175852.30749-7-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/exec/exec-all.h  | 10 ++++++++++
 target-alpha/cpu.h       | 14 ++++++++++++++
 target-arm/cpu.h         | 14 ++++++++++++++
 target-cris/cpu.h        | 14 ++++++++++++++
 target-i386/cpu.h        | 17 +++++++++++++++++
 target-lm32/cpu.h        | 14 ++++++++++++++
 target-m68k/cpu.h        | 14 ++++++++++++++
 target-microblaze/cpu.h  | 14 ++++++++++++++
 target-mips/cpu.h        | 14 ++++++++++++++
 target-moxie/cpu.h       | 14 ++++++++++++++
 target-openrisc/cpu.h    | 14 ++++++++++++++
 target-ppc/cpu.h         | 14 ++++++++++++++
 target-s390x/cpu.h       | 14 ++++++++++++++
 target-sh4/cpu.h         | 14 ++++++++++++++
 target-sparc/cpu.h       | 14 ++++++++++++++
 target-sparc/translate.c |  1 +
 target-tilegx/cpu.h      | 14 ++++++++++++++
 target-tricore/cpu.h     | 14 ++++++++++++++
 target-unicore32/cpu.h   | 14 ++++++++++++++
 target-xtensa/cpu.h      | 14 ++++++++++++++
 20 files changed, 266 insertions(+)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index acda7b6..a499c7c 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -256,6 +256,16 @@ void tb_free(TranslationBlock *tb);
 void tb_flush(CPUState *cpu);
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
 
+static inline void tb_mark_invalid(TranslationBlock *tb)
+{
+    cpu_get_invalid_tb_cpu_state(&tb->pc, &tb->cs_base, &tb->flags);
+}
+
+static inline bool tb_is_invalid(TranslationBlock *tb)
+{
+    return cpu_tb_cpu_state_is_invalidated(tb->pc, tb->cs_base, tb->flags);
+}
+
 #if defined(USE_DIRECT_JUMP)
 
 #if defined(CONFIG_TCG_INTERPRETER)
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index ac5e801..f4ecabe 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -524,4 +524,18 @@ static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc,
     *pflags = flags;
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 #endif /* ALPHA_CPU_H */
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 76d824d..068f58d 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -2371,6 +2371,20 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
     *cs_base = 0;
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 enum {
     QEMU_PSCI_CONDUIT_DISABLED = 0,
     QEMU_PSCI_CONDUIT_SMC = 1,
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 7d7fe6e..a20154e 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -296,6 +296,20 @@ static inline void cpu_get_tb_cpu_state(CPUCRISState *env, target_ulong *pc,
 				     | X_FLAG | PFIX_FLAG));
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 #define cpu_list cris_cpu_list
 void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 5b14a72..1e430ae 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -130,6 +130,8 @@
    positions to ease oring with eflags. */
 /* current cpl */
 #define HF_CPL_SHIFT         0
+/* used to mark invalidated translation blocks */
+#define HF_INVALID_SHIFT     2
 /* true if hardware interrupts must be disabled for next instruction */
 #define HF_INHIBIT_IRQ_SHIFT 3
 /* 16 or 32 segments */
@@ -159,6 +161,7 @@
 #define HF_MPX_IU_SHIFT     26 /* BND registers in-use */
 
 #define HF_CPL_MASK          (3 << HF_CPL_SHIFT)
+#define HF_INVALID_MASK      (1 << HF_INVALID_SHIFT)
 #define HF_INHIBIT_IRQ_MASK  (1 << HF_INHIBIT_IRQ_SHIFT)
 #define HF_CS32_MASK         (1 << HF_CS32_SHIFT)
 #define HF_SS32_MASK         (1 << HF_SS32_SHIFT)
@@ -1490,6 +1493,20 @@ static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc,
         (env->eflags & (IOPL_MASK | TF_MASK | RF_MASK | VM_MASK | AC_MASK));
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *flags = HF_INVALID_MASK;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return flags == HF_INVALID_MASK;
+}
+
 void do_cpu_init(X86CPU *cpu);
 void do_cpu_sipi(X86CPU *cpu);
 
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index d8a3515..a94c6bd 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -271,4 +271,18 @@ static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc,
     *flags = 0;
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 #endif
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index b2faa6b..549b0eb 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -270,4 +270,18 @@ static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc,
             | ((env->macsr >> 4) & 0xf);        /* Bits 0-3 */
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 #endif
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index beb75ff..2228e74 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -372,6 +372,20 @@ static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
                  (env->sregs[SR_MSR] & (MSR_UM | MSR_VM | MSR_EE));
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
                               bool is_write, bool is_exec, int is_asi,
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 5182dc7..e47e2e3 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -901,6 +901,20 @@ static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
                             MIPS_HFLAG_HWRENA_ULR);
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 static inline int mips_vpe_active(CPUMIPSState *env)
 {
     int active = 1;
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index 3e880fa..fba7276 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -137,6 +137,20 @@ static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
     *flags = 0;
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 int moxie_cpu_handle_mmu_fault(CPUState *cpu, vaddr address,
                                int rw, int mmu_idx);
 
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index aaf1535..b6069a3 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -398,6 +398,20 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
     *flags = (env->flags & D_FLAG);
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
 {
     if (!(env->sr & SR_IME)) {
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 5fce1ff..f944836 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -2295,6 +2295,20 @@ static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
     *flags = env->hflags;
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static inline int booke206_tlbm_id(CPUPPCState *env, ppcmas_tlb_t *tlbm)
 {
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index c216bda..113490e 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -394,6 +394,20 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
              ((env->psw.mask & PSW_MASK_32) ? FLAG_MASK_32 : 0);
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 /* While the PoO talks about ILC (a number between 1-3) what is actually
    stored in LowCore is shifted left one bit (an even between 2-6).  As
    this is the actual length of the insn and therefore more useful, that
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 478ab55..6128d38 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -388,4 +388,18 @@ static inline void cpu_get_tb_cpu_state(CPUSH4State *env, target_ulong *pc,
             | (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 4 */
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 #endif /* SH4_CPU_H */
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index a3d64a4..e327a35 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -749,6 +749,20 @@ static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc,
     *pflags = flags;
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1; /* npc must be a multible of 4 */
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 static inline bool tb_fpu_enabled(int tb_flags)
 {
 #if defined(CONFIG_USER_ONLY)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index e7691e4..81442ef 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -39,6 +39,7 @@
 #define DYNAMIC_PC  1 /* dynamic pc value */
 #define JUMP_PC     2 /* dynamic pc value which takes only two values
                          according to jump_pc[T2] */
+/* NOTE: -1 is reserved for cpu_get_invalid_tb_cpu_state() */
 
 /* global register indexes */
 static TCGv_env cpu_env;
diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h
index 1735427..863c061 100644
--- a/target-tilegx/cpu.h
+++ b/target-tilegx/cpu.h
@@ -175,4 +175,18 @@ static inline void cpu_get_tb_cpu_state(CPUTLGState *env, target_ulong *pc,
     *flags = 0;
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 #endif
diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h
index a3493a1..980b821 100644
--- a/target-tricore/cpu.h
+++ b/target-tricore/cpu.h
@@ -411,6 +411,20 @@ static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, target_ulong *pc,
     *flags = 0;
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 TriCoreCPU *cpu_tricore_init(const char *cpu_model);
 
 #define cpu_init(cpu_model) CPU(cpu_tricore_init(cpu_model))
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 7b5b405..01bf1e8 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -180,6 +180,20 @@ static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc
     }
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 int uc32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                               int mmu_idx);
 void uc32_translate_init(void);
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 7fe82a3..2395887 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -582,6 +582,20 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
     }
 }
 
+static inline void cpu_get_invalid_tb_cpu_state(target_ulong *pc,
+                                                target_ulong *cs_base,
+                                                uint32_t *flags)
+{
+    *cs_base = -1;
+}
+
+static inline bool cpu_tb_cpu_state_is_invalidated(target_ulong pc,
+                                                   target_ulong cs_base,
+                                                   uint32_t flags)
+{
+    return cs_base == -1;
+}
+
 #include "exec/cpu-all.h"
 
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 15/23] tcg: Prepare TB invalidation for lockless TB lookup
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (13 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 14/23] tcg: Introduce tb_mark_invalid() and tb_is_invalid() Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 16/23] tcg: set up tb->page_addr before insertion Paolo Bonzini
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Fedorov, Sergey Fedorov

From: Sergey Fedorov <serge.fdrv@gmail.com>

When invalidating a translation block, set an invalid CPU state into the
TranslationBlock structure first.

As soon as the TB is marked with an invalid CPU state, there is no need
to remove it from CPU's 'tb_jmp_cache'. However it will be necessary to
recheck whether the target TB is still valid after acquiring 'tb_lock'
but before calling tb_add_jump() since TB lookup is to be performed out
of 'tb_lock' in future. Note that we don't have to check 'last_tb' since
it is safe to patch an already invalidated TB since it will not be
executed anyway.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20160715175852.30749-8-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpu-exec.c              |  7 ++++---
 include/exec/exec-all.h |  8 +++++++-
 translate-all.c         | 11 ++---------
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 9cf1390..6c40839 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -334,8 +334,9 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
     tb_lock();
     tb = atomic_read(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]);
-    if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
-                 tb->flags != flags)) {
+    if (unlikely(!tb || atomic_read(&tb->pc) != pc ||
+                 atomic_read(&tb->cs_base) != cs_base ||
+                 atomic_read(&b->flags) != flags)) {
         tb = tb_find_slow(cpu, pc, cs_base, flags);
     }
 #ifndef CONFIG_USER_ONLY
@@ -352,7 +353,7 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
         /* Check if translation buffer has been flushed */
         if (cpu->tb_flushed) {
             cpu->tb_flushed = false;
-        } else {
+        } else if (!tb_is_invalid(tb)) {
             tb_add_jump(last_tb, tb_exit, tb);
         }
     }
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index a499c7c..8f0afcd 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -258,7 +258,13 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
 
 static inline void tb_mark_invalid(TranslationBlock *tb)
 {
-    cpu_get_invalid_tb_cpu_state(&tb->pc, &tb->cs_base, &tb->flags);
+    target_ulong pc = 0, cs_base = 0;
+    uint32_t flags = 0;
+
+    cpu_get_invalid_tb_cpu_state(&pc, &cs_base, &flags);
+    atomic_set(&tb->pc, pc);
+    atomic_set(&tb->cs_base, cs_base);
+    atomic_set(&tb->flags, flags);
 }
 
 static inline bool tb_is_invalid(TranslationBlock *tb)
diff --git a/translate-all.c b/translate-all.c
index 788fed1..9db72e8 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -986,11 +986,12 @@ static inline void tb_jmp_unlink(TranslationBlock *tb)
 /* invalidate one TB */
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
 {
-    CPUState *cpu;
     PageDesc *p;
     uint32_t h;
     tb_page_addr_t phys_pc;
 
+    tb_mark_invalid(tb);
+
     /* remove the TB from the hash list */
     phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
     h = tb_hash_func(phys_pc, tb->pc, tb->flags);
@@ -1008,14 +1009,6 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
         invalidate_page_bitmap(p);
     }
 
-    /* remove the TB from the hash list */
-    h = tb_jmp_cache_hash_func(tb->pc);
-    CPU_FOREACH(cpu) {
-        if (atomic_read(&cpu->tb_jmp_cache[h]) == tb) {
-            atomic_set(&cpu->tb_jmp_cache[h], NULL);
-        }
-    }
-
     /* suppress this TB from the two jump lists */
     tb_remove_from_jmp_list(tb, 0);
     tb_remove_from_jmp_list(tb, 1);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 16/23] tcg: set up tb->page_addr before insertion
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (14 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 15/23] tcg: Prepare TB invalidation for lockless TB lookup Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 17/23] tcg: cpu-exec: remove tb_lock from the hot-path Paolo Bonzini
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Sergey Fedorov

From: Alex Bennée <alex.bennee@linaro.org>

This ensures that if we find the TB on the slow path that tb->page_addr
is correctly set before being tested.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Message-Id: <20160715175852.30749-9-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 translate-all.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/translate-all.c b/translate-all.c
index 9db72e8..6156bdc 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1118,10 +1118,6 @@ static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
 {
     uint32_t h;
 
-    /* add in the hash table */
-    h = tb_hash_func(phys_pc, tb->pc, tb->flags);
-    qht_insert(&tcg_ctx.tb_ctx.htable, tb, h);
-
     /* add in the page list */
     tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
     if (phys_page2 != -1) {
@@ -1130,6 +1126,10 @@ static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
         tb->page_addr[1] = -1;
     }
 
+    /* add in the hash table */
+    h = tb_hash_func(phys_pc, tb->pc, tb->flags);
+    qht_insert(&tcg_ctx.tb_ctx.htable, tb, h);
+
 #ifdef DEBUG_TB_CHECK
     tb_page_check();
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 17/23] tcg: cpu-exec: remove tb_lock from the hot-path
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (15 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 16/23] tcg: set up tb->page_addr before insertion Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 18/23] tcg: Avoid bouncing tb_lock between tb_gen_code() and tb_add_jump() Paolo Bonzini
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Sergey Fedorov

From: Alex Bennée <alex.bennee@linaro.org>

Lock contention in the hot path of moving between existing patched
TranslationBlocks is the main drag in multithreaded performance. This
patch pushes the tb_lock() usage down to the two places that really need
it:

  - code generation (tb_gen_code)
  - jump patching (tb_add_jump)

The rest of the code doesn't really need to hold a lock as it is either
using per-CPU structures, atomically updated or designed to be used in
concurrent read situations (qht_lookup).

To keep things simple I removed the #ifdef CONFIG_USER_ONLY stuff as the
locks become NOPs anyway until the MTTCG work is completed.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>

Message-Id: <20160715175852.30749-10-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpu-exec.c | 48 +++++++++++++++++++++---------------------------
 1 file changed, 21 insertions(+), 27 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 6c40839..97e18f7 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -286,35 +286,29 @@ static TranslationBlock *tb_find_slow(CPUState *cpu,
     TranslationBlock *tb;
 
     tb = tb_find_physical(cpu, pc, cs_base, flags);
-    if (tb) {
-        goto found;
-    }
+    if (!tb) {
 
-#ifdef CONFIG_USER_ONLY
-    /* mmap_lock is needed by tb_gen_code, and mmap_lock must be
-     * taken outside tb_lock.  Since we're momentarily dropping
-     * tb_lock, there's a chance that our desired tb has been
-     * translated.
-     */
-    tb_unlock();
-    mmap_lock();
-    tb_lock();
-    tb = tb_find_physical(cpu, pc, cs_base, flags);
-    if (tb) {
-        mmap_unlock();
-        goto found;
-    }
-#endif
+        /* mmap_lock is needed by tb_gen_code, and mmap_lock must be
+         * taken outside tb_lock. As system emulation is currently
+         * single threaded the locks are NOPs.
+         */
+        mmap_lock();
+        tb_lock();
 
-    /* if no translated code available, then translate it now */
-    tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
+        /* There's a chance that our desired tb has been translated while
+         * taking the locks so we check again inside the lock.
+         */
+        tb = tb_find_physical(cpu, pc, cs_base, flags);
+        if (!tb) {
+            /* if no translated code available, then translate it now */
+            tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
+        }
 
-#ifdef CONFIG_USER_ONLY
-    mmap_unlock();
-#endif
+        tb_unlock();
+        mmap_unlock();
+    }
 
-found:
-    /* we add the TB in the virtual pc hash table */
+    /* We add the TB in the virtual pc hash table for the fast lookup */
     atomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb);
     return tb;
 }
@@ -332,7 +326,6 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
        always be the same before a given translated block
        is executed. */
     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
-    tb_lock();
     tb = atomic_read(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]);
     if (unlikely(!tb || atomic_read(&tb->pc) != pc ||
                  atomic_read(&tb->cs_base) != cs_base ||
@@ -350,14 +343,15 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
 #endif
     /* See if we can patch the calling TB. */
     if (last_tb && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
+        tb_lock();
         /* Check if translation buffer has been flushed */
         if (cpu->tb_flushed) {
             cpu->tb_flushed = false;
         } else if (!tb_is_invalid(tb)) {
             tb_add_jump(last_tb, tb_exit, tb);
         }
+        tb_unlock();
     }
-    tb_unlock();
     return tb;
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 18/23] tcg: Avoid bouncing tb_lock between tb_gen_code() and tb_add_jump()
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (16 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 17/23] tcg: cpu-exec: remove tb_lock from the hot-path Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 19/23] tcg: Merge tb_find_slow() and tb_find_fast() Paolo Bonzini
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Fedorov, Sergey Fedorov

From: Sergey Fedorov <serge.fdrv@gmail.com>

Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20160715175852.30749-11-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpu-exec.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 97e18f7..b1279d2 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -281,7 +281,8 @@ static TranslationBlock *tb_find_physical(CPUState *cpu,
 static TranslationBlock *tb_find_slow(CPUState *cpu,
                                       target_ulong pc,
                                       target_ulong cs_base,
-                                      uint32_t flags)
+                                      uint32_t flags,
+                                      bool *have_tb_lock)
 {
     TranslationBlock *tb;
 
@@ -294,6 +295,7 @@ static TranslationBlock *tb_find_slow(CPUState *cpu,
          */
         mmap_lock();
         tb_lock();
+        *have_tb_lock = true;
 
         /* There's a chance that our desired tb has been translated while
          * taking the locks so we check again inside the lock.
@@ -304,7 +306,6 @@ static TranslationBlock *tb_find_slow(CPUState *cpu,
             tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
         }
 
-        tb_unlock();
         mmap_unlock();
     }
 
@@ -321,6 +322,7 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
     TranslationBlock *tb;
     target_ulong cs_base, pc;
     uint32_t flags;
+    bool have_tb_lock = false;
 
     /* we record a subset of the CPU state. It will
        always be the same before a given translated block
@@ -329,8 +331,8 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
     tb = atomic_read(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]);
     if (unlikely(!tb || atomic_read(&tb->pc) != pc ||
                  atomic_read(&tb->cs_base) != cs_base ||
-                 atomic_read(&b->flags) != flags)) {
-        tb = tb_find_slow(cpu, pc, cs_base, flags);
+                 atomic_read(&tb->flags) != flags)) {
+        tb = tb_find_slow(cpu, pc, cs_base, flags, &have_tb_lock);
     }
 #ifndef CONFIG_USER_ONLY
     /* We don't take care of direct jumps when address mapping changes in
@@ -343,13 +345,18 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
 #endif
     /* See if we can patch the calling TB. */
     if (last_tb && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
-        tb_lock();
+        if (!have_tb_lock) {
+            tb_lock();
+            have_tb_lock = true;
+        }
         /* Check if translation buffer has been flushed */
         if (cpu->tb_flushed) {
             cpu->tb_flushed = false;
         } else if (!tb_is_invalid(tb)) {
             tb_add_jump(last_tb, tb_exit, tb);
         }
+    }
+    if (have_tb_lock) {
         tb_unlock();
     }
     return tb;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 19/23] tcg: Merge tb_find_slow() and tb_find_fast()
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (17 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 18/23] tcg: Avoid bouncing tb_lock between tb_gen_code() and tb_add_jump() Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 20/23] tcg: rename tb_find_physical() Paolo Bonzini
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Fedorov, Sergey Fedorov

From: Sergey Fedorov <serge.fdrv@gmail.com>

These functions are not too big and can be merged together. This makes
locking scheme more clear and easier to follow.

Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20160715175852.30749-12-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpu-exec.c | 72 ++++++++++++++++++++++++++------------------------------------
 1 file changed, 30 insertions(+), 42 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index b1279d2..be7e8df 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -278,45 +278,9 @@ static TranslationBlock *tb_find_physical(CPUState *cpu,
     return qht_lookup(&tcg_ctx.tb_ctx.htable, tb_cmp, &desc, h);
 }
 
-static TranslationBlock *tb_find_slow(CPUState *cpu,
-                                      target_ulong pc,
-                                      target_ulong cs_base,
-                                      uint32_t flags,
-                                      bool *have_tb_lock)
-{
-    TranslationBlock *tb;
-
-    tb = tb_find_physical(cpu, pc, cs_base, flags);
-    if (!tb) {
-
-        /* mmap_lock is needed by tb_gen_code, and mmap_lock must be
-         * taken outside tb_lock. As system emulation is currently
-         * single threaded the locks are NOPs.
-         */
-        mmap_lock();
-        tb_lock();
-        *have_tb_lock = true;
-
-        /* There's a chance that our desired tb has been translated while
-         * taking the locks so we check again inside the lock.
-         */
-        tb = tb_find_physical(cpu, pc, cs_base, flags);
-        if (!tb) {
-            /* if no translated code available, then translate it now */
-            tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
-        }
-
-        mmap_unlock();
-    }
-
-    /* We add the TB in the virtual pc hash table for the fast lookup */
-    atomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb);
-    return tb;
-}
-
-static inline TranslationBlock *tb_find_fast(CPUState *cpu,
-                                             TranslationBlock *last_tb,
-                                             int tb_exit)
+static inline TranslationBlock *tb_find(CPUState *cpu,
+                                        TranslationBlock *last_tb,
+                                        int tb_exit)
 {
     CPUArchState *env = (CPUArchState *)cpu->env_ptr;
     TranslationBlock *tb;
@@ -332,7 +296,31 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
     if (unlikely(!tb || atomic_read(&tb->pc) != pc ||
                  atomic_read(&tb->cs_base) != cs_base ||
                  atomic_read(&tb->flags) != flags)) {
-        tb = tb_find_slow(cpu, pc, cs_base, flags, &have_tb_lock);
+        tb = tb_find_physical(cpu, pc, cs_base, flags);
+        if (!tb) {
+
+            /* mmap_lock is needed by tb_gen_code, and mmap_lock must be
+             * taken outside tb_lock. As system emulation is currently
+             * single threaded the locks are NOPs.
+             */
+            mmap_lock();
+            tb_lock();
+            have_tb_lock = true;
+
+            /* There's a chance that our desired tb has been translated while
+             * taking the locks so we check again inside the lock.
+             */
+            tb = tb_find_physical(cpu, pc, cs_base, flags);
+            if (!tb) {
+                /* if no translated code available, then translate it now */
+                tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
+            }
+
+            mmap_unlock();
+        }
+
+        /* We add the TB in the virtual pc hash table for the fast lookup */
+        atomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb);
     }
 #ifndef CONFIG_USER_ONLY
     /* We don't take care of direct jumps when address mapping changes in
@@ -437,7 +425,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
     } else if (replay_has_exception()
                && cpu->icount_decr.u16.low + cpu->icount_extra == 0) {
         /* try to cause an exception pending in the log */
-        cpu_exec_nocache(cpu, 1, tb_find_fast(cpu, NULL, 0), true);
+        cpu_exec_nocache(cpu, 1, tb_find(cpu, NULL, 0), true);
         *ret = -1;
         return true;
 #endif
@@ -620,7 +608,7 @@ int cpu_exec(CPUState *cpu)
             atomic_mb_set(&cpu->tb_flushed, false); /* reset before first TB lookup */
             for(;;) {
                 cpu_handle_interrupt(cpu, &last_tb);
-                tb = tb_find_fast(cpu, last_tb, tb_exit);
+                tb = tb_find(cpu, last_tb, tb_exit);
                 cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit, &sc);
                 /* Try to align the host and virtual clocks
                    if the guest is in advance */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 20/23] tcg: rename tb_find_physical()
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (18 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 19/23] tcg: Merge tb_find_slow() and tb_find_fast() Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 21/23] Move README to markdown Paolo Bonzini
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Fedorov, Sergey Fedorov

From: Sergey Fedorov <serge.fdrv@gmail.com>

In fact, this function does not exactly perform a lookup by physical
address as it is descibed for comment on get_page_addr_code(). Thus
it may be a bit confusing to have "physical" in it's name. So rename it
to tb_htable_lookup() to better reflect its actual functionality.

Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Sergey Fedorov <sergey.fedorov@linaro.org>
Message-Id: <20160715175852.30749-13-sergey.fedorov@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpu-exec.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index be7e8df..fd43de8 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -259,7 +259,7 @@ static bool tb_cmp(const void *p, const void *d)
     return false;
 }
 
-static TranslationBlock *tb_find_physical(CPUState *cpu,
+static TranslationBlock *tb_htable_lookup(CPUState *cpu,
                                           target_ulong pc,
                                           target_ulong cs_base,
                                           uint32_t flags)
@@ -296,7 +296,7 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
     if (unlikely(!tb || atomic_read(&tb->pc) != pc ||
                  atomic_read(&tb->cs_base) != cs_base ||
                  atomic_read(&tb->flags) != flags)) {
-        tb = tb_find_physical(cpu, pc, cs_base, flags);
+        tb = tb_htable_lookup(cpu, pc, cs_base, flags);
         if (!tb) {
 
             /* mmap_lock is needed by tb_gen_code, and mmap_lock must be
@@ -310,7 +310,7 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
             /* There's a chance that our desired tb has been translated while
              * taking the locks so we check again inside the lock.
              */
-            tb = tb_find_physical(cpu, pc, cs_base, flags);
+            tb = tb_htable_lookup(cpu, pc, cs_base, flags);
             if (!tb) {
                 /* if no translated code available, then translate it now */
                 tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 21/23] Move README to markdown
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (19 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 20/23] tcg: rename tb_find_physical() Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 22/23] block/iscsi: fix rounding in iscsi_allocationmap_set Paolo Bonzini
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Pranith Kumar

From: Pranith Kumar <bobby.prani@gmail.com>

Move the README file to markdown so that it makes the github page look
prettier. I know that github repo is a mirror and not the official
repo, but I think it doesn't hurt to have it in markdown format.

Signed-off-by: Pranith Kumar <bobby.prani@gmail.com>
Message-Id: <20160715043111.29007-1-bobby.prani@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 README => README.md | 41 ++++++++++++++++++++---------------------
 1 file changed, 20 insertions(+), 21 deletions(-)
 rename README => README.md (85%)

diff --git a/README b/README.md
similarity index 85%
rename from README
rename to README.md
index f38193f..99da481 100644
--- a/README
+++ b/README.md
@@ -1,5 +1,5 @@
-         QEMU README
-         ===========
+QEMU
+---
 
 QEMU is a generic and open source machine & userspace emulator and
 virtualizer.
@@ -31,31 +31,31 @@ version 2. For full licensing details, consult the LICENSE file.
 
 
 Building
-========
+---
 
 QEMU is multi-platform software intended to be buildable on all modern
 Linux platforms, OS-X, Win32 (via the Mingw64 toolchain) and a variety
 of other UNIX targets. The simple steps to build QEMU are:
 
-  mkdir build
-  cd build
-  ../configure
-  make
+	mkdir build
+	cd build
+	../configure
+	make
 
 Complete details of the process for building and configuring QEMU for
 all supported host platforms can be found in the qemu-tech.html file.
 Additional information can also be found online via the QEMU website:
 
-  http://qemu-project.org/Hosts/Linux
-  http://qemu-project.org/Hosts/W32
+	http://qemu-project.org/Hosts/Linux
+	http://qemu-project.org/Hosts/W32
 
 
 Submitting patches
-==================
+---
 
 The QEMU source code is maintained under the GIT version control system.
 
-   git clone git://git.qemu-project.org/qemu.git
+	git clone git://git.qemu-project.org/qemu.git
 
 When submitting patches, the preferred approach is to use 'git
 format-patch' and/or 'git send-email' to format & send the mail to the
@@ -66,18 +66,18 @@ guidelines set out in the HACKING and CODING_STYLE files.
 Additional information on submitting patches can be found online via
 the QEMU website
 
-  http://qemu-project.org/Contribute/SubmitAPatch
-  http://qemu-project.org/Contribute/TrivialPatches
+	http://qemu-project.org/Contribute/SubmitAPatch
+	http://qemu-project.org/Contribute/TrivialPatches
 
 
 Bug reporting
-=============
+---
 
 The QEMU project uses Launchpad as its primary upstream bug tracker. Bugs
 found when running code built from QEMU git or upstream released sources
 should be reported via:
 
-  https://bugs.launchpad.net/qemu/
+	https://bugs.launchpad.net/qemu/
 
 If using QEMU via an operating system vendor pre-built binary package, it
 is preferable to report bugs to the vendor's own bug tracker first. If
@@ -86,22 +86,21 @@ reported via launchpad.
 
 For additional information on bug reporting consult:
 
-  http://qemu-project.org/Contribute/ReportABug
+	http://qemu-project.org/Contribute/ReportABug
 
 
 Contact
-=======
+---
 
 The QEMU community can be contacted in a number of ways, with the two
 main methods being email and IRC
 
- - qemu-devel@nongnu.org
-   http://lists.nongnu.org/mailman/listinfo/qemu-devel
- - #qemu on irc.oftc.net
+ - Mailing List: qemu-devel@nongnu.org
+ - Archives: http://lists.nongnu.org/mailman/listinfo/qemu-devel
+ - IRC: #qemu on irc.oftc.net
 
 Information on additional methods of contacting the community can be
 found online via the QEMU website:
 
   http://qemu-project.org/Contribute/StartHere
 
--- End
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 22/23] block/iscsi: fix rounding in iscsi_allocationmap_set
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (20 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 21/23] Move README to markdown Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18  9:27 ` [Qemu-devel] [PULL 23/23] block/iscsi: allow caching of the allocation map Paolo Bonzini
  2016-07-18 11:51 ` [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Peter Maydell
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Lieven, qemu-stable

From: Peter Lieven <pl@kamp.de>

when setting clusters as alloacted the boundaries have
to be expanded. As Paolo pointed out the calculation of
the number of clusters is wrong:

Suppose cluster_sectors is 2, sector_num = 1, nb_sectors = 6:

In the "mark allocated" case, you want to set 0..8, i.e.
cluster_num=0, nb_clusters=4.

   0--.--2--.--4--.--6--.--8
   <--|_________________|-->  (<--> = expanded)

Instead you are setting nb_clusters=3, so that 6..8 is not marked.

   0--.--2--.--4--.--6--.--8
   <--|______________|!!!     (! = wrong)

Cc: qemu-stable@nongnu.org
Reported-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-Id: <1468831940-15556-2-git-send-email-pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/iscsi.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/block/iscsi.c b/block/iscsi.c
index cf1e9e7..22330e1 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -432,12 +432,14 @@ static unsigned long *iscsi_allocationmap_init(IscsiLun *iscsilun)
 static void iscsi_allocationmap_set(IscsiLun *iscsilun, int64_t sector_num,
                                     int nb_sectors)
 {
+    int64_t cluster_num, nb_clusters;
     if (iscsilun->allocationmap == NULL) {
         return;
     }
-    bitmap_set(iscsilun->allocationmap,
-               sector_num / iscsilun->cluster_sectors,
-               DIV_ROUND_UP(nb_sectors, iscsilun->cluster_sectors));
+    cluster_num = sector_num / iscsilun->cluster_sectors;
+    nb_clusters = DIV_ROUND_UP(sector_num + nb_sectors,
+                               iscsilun->cluster_sectors) - cluster_num;
+    bitmap_set(iscsilun->allocationmap, cluster_num, nb_clusters);
 }
 
 static void iscsi_allocationmap_clear(IscsiLun *iscsilun, int64_t sector_num,
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [Qemu-devel] [PULL 23/23] block/iscsi: allow caching of the allocation map
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (21 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 22/23] block/iscsi: fix rounding in iscsi_allocationmap_set Paolo Bonzini
@ 2016-07-18  9:27 ` Paolo Bonzini
  2016-07-18 11:51 ` [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Peter Maydell
  23 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18  9:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Lieven

From: Peter Lieven <pl@kamp.de>

until now the allocation map was used only as a hint if a cluster
is allocated or not. If a block was not allocated (or Qemu had
no info about the allocation status) a get_block_status call was
issued to check the allocation status and possibly avoid
a subsequent read of unallocated sectors. If a block known to be
allocated the get_block_status call was omitted. In the other case
a get_block_status call was issued before every read to avoid
the necessity for a consistent allocation map. To avoid the
potential overhead of calling get_block_status for each and
every read request this took only place for the bigger requests.

This patch enhances this mechanism to cache the allocation
status and avoid calling get_block_status for blocks where
the allocation status has been queried before. This allows
for bypassing the read request even for smaller requests and
additionally omits calling get_block_status for known to be
unallocated blocks.

Signed-off-by: Peter Lieven <pl@kamp.de>
Message-Id: <1468831940-15556-3-git-send-email-pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/iscsi.c | 250 ++++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 192 insertions(+), 58 deletions(-)

diff --git a/block/iscsi.c b/block/iscsi.c
index 22330e1..129c3af 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -2,7 +2,7 @@
  * QEMU Block driver for iSCSI images
  *
  * Copyright (c) 2010-2011 Ronnie Sahlberg <ronniesahlberg@gmail.com>
- * Copyright (c) 2012-2015 Peter Lieven <pl@kamp.de>
+ * Copyright (c) 2012-2016 Peter Lieven <pl@kamp.de>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -61,7 +61,23 @@ typedef struct IscsiLun {
     struct scsi_inquiry_logical_block_provisioning lbp;
     struct scsi_inquiry_block_limits bl;
     unsigned char *zeroblock;
-    unsigned long *allocationmap;
+    /* The allocmap tracks which clusters (pages) on the iSCSI target are
+     * allocated and which are not. In case a target returns zeros for
+     * unallocated pages (iscsilun->lprz) we can directly return zeros instead
+     * of reading zeros over the wire if a read request falls within an
+     * unallocated block. As there are 3 possible states we need 2 bitmaps to
+     * track. allocmap_valid keeps track if QEMU's information about a page is
+     * valid. allocmap tracks if a page is allocated or not. In case QEMU has no
+     * valid information about a page the corresponding allocmap entry should be
+     * switched to unallocated as well to force a new lookup of the allocation
+     * status as lookups are generally skipped if a page is suspect to be
+     * allocated. If a iSCSI target is opened with cache.direct = on the
+     * allocmap_valid does not exist turning all cached information invalid so
+     * that a fresh lookup is made for any page even if allocmap entry returns
+     * it's unallocated. */
+    unsigned long *allocmap;
+    unsigned long *allocmap_valid;
+    long allocmap_size;
     int cluster_sectors;
     bool use_16_for_rw;
     bool write_protected;
@@ -422,39 +438,135 @@ static bool is_sector_request_lun_aligned(int64_t sector_num, int nb_sectors,
                                        iscsilun);
 }
 
-static unsigned long *iscsi_allocationmap_init(IscsiLun *iscsilun)
+static void iscsi_allocmap_free(IscsiLun *iscsilun)
 {
-    return bitmap_try_new(DIV_ROUND_UP(sector_lun2qemu(iscsilun->num_blocks,
-                                                       iscsilun),
-                                       iscsilun->cluster_sectors));
+    g_free(iscsilun->allocmap);
+    g_free(iscsilun->allocmap_valid);
+    iscsilun->allocmap = NULL;
+    iscsilun->allocmap_valid = NULL;
 }
 
-static void iscsi_allocationmap_set(IscsiLun *iscsilun, int64_t sector_num,
-                                    int nb_sectors)
+
+static int iscsi_allocmap_init(IscsiLun *iscsilun, int open_flags)
 {
-    int64_t cluster_num, nb_clusters;
-    if (iscsilun->allocationmap == NULL) {
-        return;
+    iscsi_allocmap_free(iscsilun);
+
+    iscsilun->allocmap_size =
+        DIV_ROUND_UP(sector_lun2qemu(iscsilun->num_blocks, iscsilun),
+                     iscsilun->cluster_sectors);
+
+    iscsilun->allocmap = bitmap_try_new(iscsilun->allocmap_size);
+    if (!iscsilun->allocmap) {
+        return -ENOMEM;
     }
-    cluster_num = sector_num / iscsilun->cluster_sectors;
-    nb_clusters = DIV_ROUND_UP(sector_num + nb_sectors,
-                               iscsilun->cluster_sectors) - cluster_num;
-    bitmap_set(iscsilun->allocationmap, cluster_num, nb_clusters);
+
+    if (open_flags & BDRV_O_NOCACHE) {
+        /* in case that cache.direct = on all allocmap entries are
+         * treated as invalid to force a relookup of the block
+         * status on every read request */
+        return 0;
+    }
+
+    iscsilun->allocmap_valid = bitmap_try_new(iscsilun->allocmap_size);
+    if (!iscsilun->allocmap_valid) {
+        /* if we are under memory pressure free the allocmap as well */
+        iscsi_allocmap_free(iscsilun);
+        return -ENOMEM;
+    }
+
+    return 0;
 }
 
-static void iscsi_allocationmap_clear(IscsiLun *iscsilun, int64_t sector_num,
-                                      int nb_sectors)
+static void
+iscsi_allocmap_update(IscsiLun *iscsilun, int64_t sector_num,
+                      int nb_sectors, bool allocated, bool valid)
 {
-    int64_t cluster_num, nb_clusters;
-    if (iscsilun->allocationmap == NULL) {
+    int64_t cl_num_expanded, nb_cls_expanded, cl_num_shrunk, nb_cls_shrunk;
+
+    if (iscsilun->allocmap == NULL) {
         return;
     }
-    cluster_num = DIV_ROUND_UP(sector_num, iscsilun->cluster_sectors);
-    nb_clusters = (sector_num + nb_sectors) / iscsilun->cluster_sectors
-                  - cluster_num;
-    if (nb_clusters > 0) {
-        bitmap_clear(iscsilun->allocationmap, cluster_num, nb_clusters);
+    /* expand to entirely contain all affected clusters */
+    cl_num_expanded = sector_num / iscsilun->cluster_sectors;
+    nb_cls_expanded = DIV_ROUND_UP(sector_num + nb_sectors,
+                                   iscsilun->cluster_sectors) - cl_num_expanded;
+    /* shrink to touch only completely contained clusters */
+    cl_num_shrunk = DIV_ROUND_UP(sector_num, iscsilun->cluster_sectors);
+    nb_cls_shrunk = (sector_num + nb_sectors) / iscsilun->cluster_sectors
+                      - cl_num_shrunk;
+    if (allocated) {
+        bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded);
+    } else {
+        bitmap_clear(iscsilun->allocmap, cl_num_shrunk, nb_cls_shrunk);
+    }
+
+    if (iscsilun->allocmap_valid == NULL) {
+        return;
+    }
+    if (valid) {
+        bitmap_set(iscsilun->allocmap_valid, cl_num_shrunk, nb_cls_shrunk);
+    } else {
+        bitmap_clear(iscsilun->allocmap_valid, cl_num_expanded,
+                     nb_cls_expanded);
+    }
+}
+
+static void
+iscsi_allocmap_set_allocated(IscsiLun *iscsilun, int64_t sector_num,
+                             int nb_sectors)
+{
+    iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, true, true);
+}
+
+static void
+iscsi_allocmap_set_unallocated(IscsiLun *iscsilun, int64_t sector_num,
+                               int nb_sectors)
+{
+    /* Note: if cache.direct=on the fifth argument to iscsi_allocmap_update
+     * is ignored, so this will in effect be an iscsi_allocmap_set_invalid.
+     */
+    iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, false, true);
+}
+
+static void iscsi_allocmap_set_invalid(IscsiLun *iscsilun, int64_t sector_num,
+                                       int nb_sectors)
+{
+    iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, false, false);
+}
+
+static void iscsi_allocmap_invalidate(IscsiLun *iscsilun)
+{
+    if (iscsilun->allocmap) {
+        bitmap_zero(iscsilun->allocmap, iscsilun->allocmap_size);
+    }
+    if (iscsilun->allocmap_valid) {
+        bitmap_zero(iscsilun->allocmap_valid, iscsilun->allocmap_size);
+    }
+}
+
+static inline bool
+iscsi_allocmap_is_allocated(IscsiLun *iscsilun, int64_t sector_num,
+                            int nb_sectors)
+{
+    unsigned long size;
+    if (iscsilun->allocmap == NULL) {
+        return true;
     }
+    size = DIV_ROUND_UP(sector_num + nb_sectors, iscsilun->cluster_sectors);
+    return !(find_next_bit(iscsilun->allocmap, size,
+                           sector_num / iscsilun->cluster_sectors) == size);
+}
+
+static inline bool iscsi_allocmap_is_valid(IscsiLun *iscsilun,
+                                           int64_t sector_num, int nb_sectors)
+{
+    unsigned long size;
+    if (iscsilun->allocmap_valid == NULL) {
+        return false;
+    }
+    size = DIV_ROUND_UP(sector_num + nb_sectors, iscsilun->cluster_sectors);
+    return (find_next_zero_bit(iscsilun->allocmap_valid, size,
+                               sector_num / iscsilun->cluster_sectors) == size);
 }
 
 static int coroutine_fn
@@ -517,26 +629,16 @@ retry:
     }
 
     if (iTask.status != SCSI_STATUS_GOOD) {
+        iscsi_allocmap_set_invalid(iscsilun, sector_num, nb_sectors);
         return iTask.err_code;
     }
 
-    iscsi_allocationmap_set(iscsilun, sector_num, nb_sectors);
+    iscsi_allocmap_set_allocated(iscsilun, sector_num, nb_sectors);
 
     return 0;
 }
 
 
-static bool iscsi_allocationmap_is_allocated(IscsiLun *iscsilun,
-                                             int64_t sector_num, int nb_sectors)
-{
-    unsigned long size;
-    if (iscsilun->allocationmap == NULL) {
-        return true;
-    }
-    size = DIV_ROUND_UP(sector_num + nb_sectors, iscsilun->cluster_sectors);
-    return !(find_next_bit(iscsilun->allocationmap, size,
-                           sector_num / iscsilun->cluster_sectors) == size);
-}
 
 static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
                                                   int64_t sector_num,
@@ -621,9 +723,9 @@ retry:
     }
 
     if (ret & BDRV_BLOCK_ZERO) {
-        iscsi_allocationmap_clear(iscsilun, sector_num, *pnum);
+        iscsi_allocmap_set_unallocated(iscsilun, sector_num, *pnum);
     } else {
-        iscsi_allocationmap_set(iscsilun, sector_num, *pnum);
+        iscsi_allocmap_set_allocated(iscsilun, sector_num, *pnum);
     }
 
     if (*pnum > nb_sectors) {
@@ -659,17 +761,32 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
         return -EINVAL;
     }
 
-    if (iscsilun->lbprz && nb_sectors >= ISCSI_CHECKALLOC_THRES &&
-        !iscsi_allocationmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
-        int64_t ret;
+    /* if cache.direct is off and we have a valid entry in our allocation map
+     * we can skip checking the block status and directly return zeroes if
+     * the request falls within an unallocated area */
+    if (iscsi_allocmap_is_valid(iscsilun, sector_num, nb_sectors) &&
+        !iscsi_allocmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
+            qemu_iovec_memset(iov, 0, 0x00, iov->size);
+            return 0;
+    }
+
+    if (nb_sectors >= ISCSI_CHECKALLOC_THRES &&
+        !iscsi_allocmap_is_valid(iscsilun, sector_num, nb_sectors) &&
+        !iscsi_allocmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
         int pnum;
         BlockDriverState *file;
-        ret = iscsi_co_get_block_status(bs, sector_num,
-                                        BDRV_REQUEST_MAX_SECTORS, &pnum, &file);
+        /* check the block status from the beginning of the cluster
+         * containing the start sector */
+        int64_t ret = iscsi_co_get_block_status(bs,
+                          sector_num - sector_num % iscsilun->cluster_sectors,
+                          BDRV_REQUEST_MAX_SECTORS, &pnum, &file);
         if (ret < 0) {
             return ret;
         }
-        if (ret & BDRV_BLOCK_ZERO && pnum >= nb_sectors) {
+        /* if the whole request falls into an unallocated area we can avoid
+         * to read and directly return zeroes instead */
+        if (ret & BDRV_BLOCK_ZERO &&
+            pnum >= nb_sectors + sector_num % iscsilun->cluster_sectors) {
             qemu_iovec_memset(iov, 0, 0x00, iov->size);
             return 0;
         }
@@ -983,7 +1100,7 @@ retry:
         return iTask.err_code;
     }
 
-    iscsi_allocationmap_clear(iscsilun, sector_num, nb_sectors);
+    iscsi_allocmap_set_invalid(iscsilun, sector_num, nb_sectors);
 
     return 0;
 }
@@ -1073,15 +1190,17 @@ retry:
     }
 
     if (iTask.status != SCSI_STATUS_GOOD) {
+        iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
+                                   count >> BDRV_SECTOR_BITS);
         return iTask.err_code;
     }
 
     if (flags & BDRV_REQ_MAY_UNMAP) {
-        iscsi_allocationmap_clear(iscsilun, offset >> BDRV_SECTOR_BITS,
-                                  count >> BDRV_SECTOR_BITS);
+        iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
+                                   count >> BDRV_SECTOR_BITS);
     } else {
-        iscsi_allocationmap_set(iscsilun, offset >> BDRV_SECTOR_BITS,
-                                count >> BDRV_SECTOR_BITS);
+        iscsi_allocmap_set_allocated(iscsilun, offset >> BDRV_SECTOR_BITS,
+                                     count >> BDRV_SECTOR_BITS);
     }
 
     return 0;
@@ -1654,10 +1773,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
         iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
                                      iscsilun->block_size) >> BDRV_SECTOR_BITS;
         if (iscsilun->lbprz) {
-            iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun);
-            if (iscsilun->allocationmap == NULL) {
-                ret = -ENOMEM;
-            }
+            ret = iscsi_allocmap_init(iscsilun, bs->open_flags);
         }
     }
 
@@ -1694,7 +1810,7 @@ static void iscsi_close(BlockDriverState *bs)
     }
     iscsi_destroy_context(iscsi);
     g_free(iscsilun->zeroblock);
-    g_free(iscsilun->allocationmap);
+    iscsi_allocmap_free(iscsilun);
     memset(iscsilun, 0, sizeof(IscsiLun));
 }
 
@@ -1758,6 +1874,16 @@ static int iscsi_reopen_prepare(BDRVReopenState *state,
     return 0;
 }
 
+static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
+{
+    IscsiLun *iscsilun = reopen_state->bs->opaque;
+
+    /* the cache.direct status might have changed */
+    if (iscsilun->allocmap != NULL) {
+        iscsi_allocmap_init(iscsilun, reopen_state->flags);
+    }
+}
+
 static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
 {
     IscsiLun *iscsilun = bs->opaque;
@@ -1777,9 +1903,8 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
         return -EINVAL;
     }
 
-    if (iscsilun->allocationmap != NULL) {
-        g_free(iscsilun->allocationmap);
-        iscsilun->allocationmap = iscsi_allocationmap_init(iscsilun);
+    if (iscsilun->allocmap != NULL) {
+        iscsi_allocmap_init(iscsilun, bs->open_flags);
     }
 
     return 0;
@@ -1839,6 +1964,13 @@ static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
     return 0;
 }
 
+static void iscsi_invalidate_cache(BlockDriverState *bs,
+                                   Error **errp)
+{
+    IscsiLun *iscsilun = bs->opaque;
+    iscsi_allocmap_invalidate(iscsilun);
+}
+
 static QemuOptsList iscsi_create_opts = {
     .name = "iscsi-create-opts",
     .head = QTAILQ_HEAD_INITIALIZER(iscsi_create_opts.head),
@@ -1862,7 +1994,9 @@ static BlockDriver bdrv_iscsi = {
     .bdrv_close      = iscsi_close,
     .bdrv_create     = iscsi_create,
     .create_opts     = &iscsi_create_opts,
-    .bdrv_reopen_prepare  = iscsi_reopen_prepare,
+    .bdrv_reopen_prepare   = iscsi_reopen_prepare,
+    .bdrv_reopen_commit    = iscsi_reopen_commit,
+    .bdrv_invalidate_cache = iscsi_invalidate_cache,
 
     .bdrv_getlength  = iscsi_getlength,
     .bdrv_get_info   = iscsi_get_info,
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18
  2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
                   ` (22 preceding siblings ...)
  2016-07-18  9:27 ` [Qemu-devel] [PULL 23/23] block/iscsi: allow caching of the allocation map Paolo Bonzini
@ 2016-07-18 11:51 ` Peter Maydell
  2016-07-18 11:54   ` Paolo Bonzini
  23 siblings, 1 reply; 32+ messages in thread
From: Peter Maydell @ 2016-07-18 11:51 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers

On 18 July 2016 at 10:27, Paolo Bonzini <pbonzini@redhat.com> wrote:
> The following changes since commit 6b92bbfe812746fe7841a24c24e6460f5359ce72:
>
>   Merge remote-tracking branch 'remotes/mcayland/tags/qemu-openbios-signed' into staging (2016-07-15 16:56:08 +0100)
>
> are available in the git repository at:
>
>   git://github.com/bonzini/qemu.git tags/for-upstream
>
> for you to fetch changes up to 6e5532eb16b1fcc7b6d5a15bc5fc0089c1f776f0:
>
>   block/iscsi: allow caching of the allocation map (2016-07-18 11:19:47 +0200)
>
> ----------------------------------------------------------------
> * tb_lock-less
> * two old patches from prospective GSoC students
> * i386 -kernel device tree support
> * Coverity fix
> * memory usage improvement from Peter
> * checkpatch fix
> * g_path_get_dirname cleanup
> * caching of block status for iSCSI
>

Hi. I'm afraid this fails to build on 32-bit:

In file included from /home/petmay01/qemu/include/qemu/osdep.h:36:0,
                 from /home/petmay01/qemu/exec.c:19:
/home/petmay01/qemu/include/exec/exec-all.h: In function 'tb_mark_invalid':
/home/petmay01/qemu/include/qemu/compiler.h:85:23: error: size of
array 'qemu_build_bug_on__265' is negative
     typedef char glue(qemu_build_bug_on__,__LINE__)[(x)?-1:1]
__attribute__((unused));
                       ^
/home/petmay01/qemu/include/qemu/compiler.h:50:21: note: in definition
of macro 'xglue'
 #define xglue(x, y) x ## y
                     ^
/home/petmay01/qemu/include/qemu/compiler.h:85:18: note: in expansion
of macro 'glue'
     typedef char glue(qemu_build_bug_on__,__LINE__)[(x)?-1:1]
__attribute__((unused));
                  ^
/home/petmay01/qemu/include/qemu/atomic.h:63:5: note: in expansion of
macro 'QEMU_BUILD_BUG_ON'
     QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
     ^
/home/petmay01/qemu/include/exec/exec-all.h:265:5: note: in expansion
of macro 'atomic_set'
     atomic_set(&tb->pc, pc);
     ^
/home/petmay01/qemu/include/qemu/compiler.h:85:23: error: size of
array 'qemu_build_bug_on__266' is negative
     typedef char glue(qemu_build_bug_on__,__LINE__)[(x)?-1:1]
__attribute__((unused));
                       ^
/home/petmay01/qemu/include/qemu/compiler.h:50:21: note: in definition
of macro 'xglue'
 #define xglue(x, y) x ## y
                     ^
/home/petmay01/qemu/include/qemu/compiler.h:85:18: note: in expansion
of macro 'glue'
     typedef char glue(qemu_build_bug_on__,__LINE__)[(x)?-1:1]
__attribute__((unused));
                  ^
/home/petmay01/qemu/include/qemu/atomic.h:63:5: note: in expansion of
macro 'QEMU_BUILD_BUG_ON'
     QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
     ^
/home/petmay01/qemu/include/exec/exec-all.h:266:5: note: in expansion
of macro 'atomic_set'
     atomic_set(&tb->cs_base, cs_base);
     ^

Looks like an attempt to do an atomic op on a larger-than-host-pointer type.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18
  2016-07-18 11:51 ` [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Peter Maydell
@ 2016-07-18 11:54   ` Paolo Bonzini
  2016-07-18 11:57     ` Peter Maydell
  0 siblings, 1 reply; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18 11:54 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers



On 18/07/2016 13:51, Peter Maydell wrote:
> On 18 July 2016 at 10:27, Paolo Bonzini <pbonzini@redhat.com> wrote:
>> The following changes since commit 6b92bbfe812746fe7841a24c24e6460f5359ce72:
>>
>>   Merge remote-tracking branch 'remotes/mcayland/tags/qemu-openbios-signed' into staging (2016-07-15 16:56:08 +0100)
>>
>> are available in the git repository at:
>>
>>   git://github.com/bonzini/qemu.git tags/for-upstream
>>
>> for you to fetch changes up to 6e5532eb16b1fcc7b6d5a15bc5fc0089c1f776f0:
>>
>>   block/iscsi: allow caching of the allocation map (2016-07-18 11:19:47 +0200)
>>
>> ----------------------------------------------------------------
>> * tb_lock-less
>> * two old patches from prospective GSoC students
>> * i386 -kernel device tree support
>> * Coverity fix
>> * memory usage improvement from Peter
>> * checkpatch fix
>> * g_path_get_dirname cleanup
>> * caching of block status for iSCSI
>>
> 
> Hi. I'm afraid this fails to build on 32-bit:
> 
> In file included from /home/petmay01/qemu/include/qemu/osdep.h:36:0,
>                  from /home/petmay01/qemu/exec.c:19:
> /home/petmay01/qemu/include/exec/exec-all.h: In function 'tb_mark_invalid':
> /home/petmay01/qemu/include/qemu/compiler.h:85:23: error: size of
> array 'qemu_build_bug_on__265' is negative
>      typedef char glue(qemu_build_bug_on__,__LINE__)[(x)?-1:1]
> __attribute__((unused));
>                        ^
> /home/petmay01/qemu/include/qemu/compiler.h:50:21: note: in definition
> of macro 'xglue'
>  #define xglue(x, y) x ## y
>                      ^
> /home/petmay01/qemu/include/qemu/compiler.h:85:18: note: in expansion
> of macro 'glue'
>      typedef char glue(qemu_build_bug_on__,__LINE__)[(x)?-1:1]
> __attribute__((unused));
>                   ^
> /home/petmay01/qemu/include/qemu/atomic.h:63:5: note: in expansion of
> macro 'QEMU_BUILD_BUG_ON'
>      QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
>      ^
> /home/petmay01/qemu/include/exec/exec-all.h:265:5: note: in expansion
> of macro 'atomic_set'
>      atomic_set(&tb->pc, pc);
>      ^
> /home/petmay01/qemu/include/qemu/compiler.h:85:23: error: size of
> array 'qemu_build_bug_on__266' is negative
>      typedef char glue(qemu_build_bug_on__,__LINE__)[(x)?-1:1]
> __attribute__((unused));
>                        ^
> /home/petmay01/qemu/include/qemu/compiler.h:50:21: note: in definition
> of macro 'xglue'
>  #define xglue(x, y) x ## y
>                      ^
> /home/petmay01/qemu/include/qemu/compiler.h:85:18: note: in expansion
> of macro 'glue'
>      typedef char glue(qemu_build_bug_on__,__LINE__)[(x)?-1:1]
> __attribute__((unused));
>                   ^
> /home/petmay01/qemu/include/qemu/atomic.h:63:5: note: in expansion of
> macro 'QEMU_BUILD_BUG_ON'
>      QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
>      ^
> /home/petmay01/qemu/include/exec/exec-all.h:266:5: note: in expansion
> of macro 'atomic_set'
>      atomic_set(&tb->cs_base, cs_base);
>      ^
> 
> Looks like an attempt to do an atomic op on a larger-than-host-pointer type.

Hmm, atomic_set should be acceptable even on 64-bit.  I'll fix that up,
atomics are not necessary here because there's always a smp_wmb afterwards.

Paolo

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18
  2016-07-18 11:54   ` Paolo Bonzini
@ 2016-07-18 11:57     ` Peter Maydell
  2016-07-18 11:59       ` Paolo Bonzini
  0 siblings, 1 reply; 32+ messages in thread
From: Peter Maydell @ 2016-07-18 11:57 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers

On 18 July 2016 at 12:54, Paolo Bonzini <pbonzini@redhat.com> wrote:
> On 18/07/2016 13:51, Peter Maydell wrote:
>> Looks like an attempt to do an atomic op on a larger-than-host-pointer type.
>
> Hmm, atomic_set should be acceptable even on 64-bit.

How does that work, when the host might not have an atomic
64-bit write?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18
  2016-07-18 11:57     ` Peter Maydell
@ 2016-07-18 11:59       ` Paolo Bonzini
  2016-07-18 12:50         ` Peter Maydell
  0 siblings, 1 reply; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18 11:59 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers



On 18/07/2016 13:57, Peter Maydell wrote:
> On 18 July 2016 at 12:54, Paolo Bonzini <pbonzini@redhat.com> wrote:
>> On 18/07/2016 13:51, Peter Maydell wrote:
>>> Looks like an attempt to do an atomic op on a larger-than-host-pointer type.
>>
>> Hmm, atomic_set should be acceptable even on 64-bit.
> 
> How does that work, when the host might not have an atomic
> 64-bit write?

All hosts we support should have it.  Worst case, it could be done
through FP registers.

Paolo

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18
  2016-07-18 11:59       ` Paolo Bonzini
@ 2016-07-18 12:50         ` Peter Maydell
  2016-07-18 13:22           ` Paolo Bonzini
  0 siblings, 1 reply; 32+ messages in thread
From: Peter Maydell @ 2016-07-18 12:50 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers

On 18 July 2016 at 12:59, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 18/07/2016 13:57, Peter Maydell wrote:
>> On 18 July 2016 at 12:54, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>> On 18/07/2016 13:51, Peter Maydell wrote:
>>>> Looks like an attempt to do an atomic op on a larger-than-host-pointer type.
>>>
>>> Hmm, atomic_set should be acceptable even on 64-bit.
>>
>> How does that work, when the host might not have an atomic
>> 64-bit write?
>
> All hosts we support should have it.

32-bit ARM does not guarantee that you can have 64-bit atomic
operations.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18
  2016-07-18 12:50         ` Peter Maydell
@ 2016-07-18 13:22           ` Paolo Bonzini
  2016-07-18 13:41             ` Peter Maydell
  0 siblings, 1 reply; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18 13:22 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers



On 18/07/2016 14:50, Peter Maydell wrote:
> On 18 July 2016 at 12:59, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>
>>
>> On 18/07/2016 13:57, Peter Maydell wrote:
>>> On 18 July 2016 at 12:54, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>>> On 18/07/2016 13:51, Peter Maydell wrote:
>>>>> Looks like an attempt to do an atomic op on a larger-than-host-pointer type.
>>>>
>>>> Hmm, atomic_set should be acceptable even on 64-bit.
>>>
>>> How does that work, when the host might not have an atomic
>>> 64-bit write?
>>
>> All hosts we support should have it.
> 
> 32-bit ARM does not guarantee that you can have 64-bit atomic
> operations.

Doesn't it have LDRDEX and STRDEX?

Paolo

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18
  2016-07-18 13:22           ` Paolo Bonzini
@ 2016-07-18 13:41             ` Peter Maydell
  2016-07-18 13:59               ` Paolo Bonzini
  0 siblings, 1 reply; 32+ messages in thread
From: Peter Maydell @ 2016-07-18 13:41 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers

On 18 July 2016 at 14:22, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 18/07/2016 14:50, Peter Maydell wrote:
>> On 18 July 2016 at 12:59, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>>
>>>
>>> On 18/07/2016 13:57, Peter Maydell wrote:
>>>> On 18 July 2016 at 12:54, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>>>> On 18/07/2016 13:51, Peter Maydell wrote:
>>>>>> Looks like an attempt to do an atomic op on a larger-than-host-pointer type.
>>>>>
>>>>> Hmm, atomic_set should be acceptable even on 64-bit.
>>>>
>>>> How does that work, when the host might not have an atomic
>>>> 64-bit write?
>>>
>>> All hosts we support should have it.
>>
>> 32-bit ARM does not guarantee that you can have 64-bit atomic
>> operations.
>
> Doesn't it have LDRDEX and STRDEX?

Yes, you could use a LDREXD/STREXD sequence for ARMv7 (and it
looks like gcc does so). Doesn't work on ARMv5, though.

MIPS32 and PPC32 are the hosts where attempted 64-bit
atomics generally fail (they want to call out to libatomic),
so those would be the other ones to test before widening the use
of atomic_set.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18
  2016-07-18 13:41             ` Peter Maydell
@ 2016-07-18 13:59               ` Paolo Bonzini
  0 siblings, 0 replies; 32+ messages in thread
From: Paolo Bonzini @ 2016-07-18 13:59 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers



On 18/07/2016 15:41, Peter Maydell wrote:
>> > Doesn't it have LDRDEX and STRDEX?
> Yes, you could use a LDREXD/STREXD sequence for ARMv7 (and it
> looks like gcc does so). Doesn't work on ARMv5, though.
> 
> MIPS32 and PPC32 are the hosts where attempted 64-bit
> atomics generally fail (they want to call out to libatomic),
> so those would be the other ones to test before widening the use
> of atomic_set.

In the meanwhile we can degrade these particular accesses to volatile.

Paolo

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2016-07-18 13:59 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-18  9:27 [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 01/23] use g_path_get_dirname instead of dirname Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 02/23] Changed malloc to g_malloc, free to g_free in bsd-user/qemu.h Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 03/23] hw/i386: add device tree support Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 04/23] compiler: never omit assertions if using a static analysis tool Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 05/23] megasas: remove useless check for cmd->frame Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 06/23] checkpatch: consider git extended headers valid patches Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 07/23] exec: avoid realloc in phys_map_node_reserve Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 08/23] cpu-exec: Move down some declarations in cpu_exec() Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 09/23] util/qht: Document memory ordering assumptions Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 10/23] tcg: Pass last_tb by value to tb_find_fast() Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 11/23] tcg: Prepare safe tb_jmp_cache lookup out of tb_lock Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 12/23] tcg: Prepare safe access to tb_flushed " Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 13/23] target-i386: Remove redundant HF_SOFTMMU_MASK Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 14/23] tcg: Introduce tb_mark_invalid() and tb_is_invalid() Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 15/23] tcg: Prepare TB invalidation for lockless TB lookup Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 16/23] tcg: set up tb->page_addr before insertion Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 17/23] tcg: cpu-exec: remove tb_lock from the hot-path Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 18/23] tcg: Avoid bouncing tb_lock between tb_gen_code() and tb_add_jump() Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 19/23] tcg: Merge tb_find_slow() and tb_find_fast() Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 20/23] tcg: rename tb_find_physical() Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 21/23] Move README to markdown Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 22/23] block/iscsi: fix rounding in iscsi_allocationmap_set Paolo Bonzini
2016-07-18  9:27 ` [Qemu-devel] [PULL 23/23] block/iscsi: allow caching of the allocation map Paolo Bonzini
2016-07-18 11:51 ` [Qemu-devel] [PULL 00/23] TCG and misc patches for 2.7 hard freeze from 2016-07-18 Peter Maydell
2016-07-18 11:54   ` Paolo Bonzini
2016-07-18 11:57     ` Peter Maydell
2016-07-18 11:59       ` Paolo Bonzini
2016-07-18 12:50         ` Peter Maydell
2016-07-18 13:22           ` Paolo Bonzini
2016-07-18 13:41             ` Peter Maydell
2016-07-18 13:59               ` Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.