Re: [PATCH v3 13/20] cputlb: Move NOTDIRTY handling from I/O path to TLB path

2019-09-23 Thread Philippe Mathieu-Daudé
On 9/22/19 5:54 AM, Richard Henderson wrote:
> Pages that we want to track for NOTDIRTY are RAM.  We do not
> really need to go through the I/O path to handle them.
> 
> Signed-off-by: Richard Henderson 
> ---
>  include/exec/cpu-common.h |  2 --
>  accel/tcg/cputlb.c| 26 +---
>  exec.c| 50 ---
>  memory.c  | 16 -
>  4 files changed, 23 insertions(+), 71 deletions(-)
> 
> diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
> index 1c0e03ddc2..81753bbb34 100644
> --- a/include/exec/cpu-common.h
> +++ b/include/exec/cpu-common.h
> @@ -100,8 +100,6 @@ void qemu_flush_coalesced_mmio_buffer(void);
>  
>  void cpu_flush_icache_range(hwaddr start, hwaddr len);
>  
> -extern struct MemoryRegion io_mem_notdirty;
> -
>  typedef int (RAMBlockIterFunc)(RAMBlock *rb, void *opaque);
>  
>  int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque);
> diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
> index 7ab523d7ec..b7bd738115 100644
> --- a/accel/tcg/cputlb.c
> +++ b/accel/tcg/cputlb.c
> @@ -904,7 +904,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
> *iotlbentry,
>  mr = section->mr;
>  mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
>  cpu->mem_io_pc = retaddr;
> -if (mr != _mem_notdirty && !cpu->can_do_io) {
> +if (!cpu->can_do_io) {
>  cpu_io_recompile(cpu, retaddr);
>  }
>  
> @@ -945,7 +945,7 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
> *iotlbentry,
>  section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
>  mr = section->mr;
>  mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
> -if (mr != _mem_notdirty && !cpu->can_do_io) {
> +if (!cpu->can_do_io) {
>  cpu_io_recompile(cpu, retaddr);
>  }
>  cpu->mem_io_vaddr = addr;
> @@ -1606,7 +1606,7 @@ store_helper(CPUArchState *env, target_ulong addr, 
> uint64_t val,
>  }
>  
>  /* Handle I/O access.  */
> -if (likely(tlb_addr & (TLB_MMIO | TLB_NOTDIRTY))) {
> +if (tlb_addr & TLB_MMIO) {
>  io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr,
>op ^ (tlb_addr & TLB_BSWAP ? MO_BSWAP : 0));
>  return;
> @@ -1619,6 +1619,26 @@ store_helper(CPUArchState *env, target_ulong addr, 
> uint64_t val,
>  
>  haddr = (void *)((uintptr_t)addr + entry->addend);
>  
> +/* Handle clean RAM pages.  */
> +if (tlb_addr & TLB_NOTDIRTY) {
> +NotDirtyInfo ndi;
> +
> +/* We require mem_io_pc in tb_invalidate_phys_page_range.  */
> +env_cpu(env)->mem_io_pc = retaddr;
> +
> +memory_notdirty_write_prepare(, env_cpu(env), addr,
> +  addr + iotlbentry->addr, size);
> +
> +if (unlikely(tlb_addr & TLB_BSWAP)) {
> +direct_swap(haddr, val);
> +} else {
> +direct(haddr, val);
> +}
> +
> +memory_notdirty_write_complete();
> +return;
> +}
> +
>  if (unlikely(tlb_addr & TLB_BSWAP)) {
>  direct_swap(haddr, val);
>  } else {
> diff --git a/exec.c b/exec.c
> index e21e068535..abf58b68a0 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -88,7 +88,6 @@ static MemoryRegion *system_io;
>  AddressSpace address_space_io;
>  AddressSpace address_space_memory;
>  
> -MemoryRegion io_mem_notdirty;
>  static MemoryRegion io_mem_unassigned;
>  #endif
>  
> @@ -157,7 +156,6 @@ typedef struct subpage_t {
>  } subpage_t;
>  
>  #define PHYS_SECTION_UNASSIGNED 0
> -#define PHYS_SECTION_NOTDIRTY 1
>  
>  static void io_mem_init(void);
>  static void memory_map_init(void);
> @@ -1438,9 +1436,6 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
>  if (memory_region_is_ram(section->mr)) {
>  /* Normal RAM.  */
>  iotlb = memory_region_get_ram_addr(section->mr) + xlat;
> -if (!section->readonly) {
> -iotlb |= PHYS_SECTION_NOTDIRTY;
> -}
>  } else {
>  AddressSpaceDispatch *d;
>  
> @@ -2749,42 +2744,6 @@ void memory_notdirty_write_complete(NotDirtyInfo *ndi)
>  }
>  }
>  
> -/* Called within RCU critical section.  */
> -static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
> -   uint64_t val, unsigned size)
> -{
> -NotDirtyInfo ndi;
> -
> -memory_notdirty_write_prepare(, current_cpu, 
> current_cpu->mem_io_vaddr,
> - ram_addr, size);
> -
> -stn_p(qemu_map_ram_ptr(NULL, ram_addr), size, val);
> -memory_notdirty_write_complete();
> -}
> -
> -static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
> - unsigned size, bool is_write,
> - MemTxAttrs attrs)
> -{
> -return is_write;
> -}
> -
> -static const MemoryRegionOps notdirty_mem_ops = {
> -

Re: [PATCH v3 13/20] cputlb: Move NOTDIRTY handling from I/O path to TLB path

2019-09-23 Thread David Hildenbrand
On 22.09.19 05:54, Richard Henderson wrote:
> Pages that we want to track for NOTDIRTY are RAM.  We do not
> really need to go through the I/O path to handle them.
> 
> Signed-off-by: Richard Henderson 
> ---
>  include/exec/cpu-common.h |  2 --
>  accel/tcg/cputlb.c| 26 +---
>  exec.c| 50 ---
>  memory.c  | 16 -
>  4 files changed, 23 insertions(+), 71 deletions(-)
> 
> diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
> index 1c0e03ddc2..81753bbb34 100644
> --- a/include/exec/cpu-common.h
> +++ b/include/exec/cpu-common.h
> @@ -100,8 +100,6 @@ void qemu_flush_coalesced_mmio_buffer(void);
>  
>  void cpu_flush_icache_range(hwaddr start, hwaddr len);
>  
> -extern struct MemoryRegion io_mem_notdirty;
> -
>  typedef int (RAMBlockIterFunc)(RAMBlock *rb, void *opaque);
>  
>  int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque);
> diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
> index 7ab523d7ec..b7bd738115 100644
> --- a/accel/tcg/cputlb.c
> +++ b/accel/tcg/cputlb.c
> @@ -904,7 +904,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
> *iotlbentry,
>  mr = section->mr;
>  mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
>  cpu->mem_io_pc = retaddr;
> -if (mr != _mem_notdirty && !cpu->can_do_io) {
> +if (!cpu->can_do_io) {
>  cpu_io_recompile(cpu, retaddr);
>  }
>  
> @@ -945,7 +945,7 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
> *iotlbentry,
>  section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
>  mr = section->mr;
>  mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
> -if (mr != _mem_notdirty && !cpu->can_do_io) {
> +if (!cpu->can_do_io) {
>  cpu_io_recompile(cpu, retaddr);
>  }
>  cpu->mem_io_vaddr = addr;
> @@ -1606,7 +1606,7 @@ store_helper(CPUArchState *env, target_ulong addr, 
> uint64_t val,
>  }
>  
>  /* Handle I/O access.  */
> -if (likely(tlb_addr & (TLB_MMIO | TLB_NOTDIRTY))) {
> +if (tlb_addr & TLB_MMIO) {
>  io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr,
>op ^ (tlb_addr & TLB_BSWAP ? MO_BSWAP : 0));
>  return;
> @@ -1619,6 +1619,26 @@ store_helper(CPUArchState *env, target_ulong addr, 
> uint64_t val,
>  
>  haddr = (void *)((uintptr_t)addr + entry->addend);
>  
> +/* Handle clean RAM pages.  */
> +if (tlb_addr & TLB_NOTDIRTY) {
> +NotDirtyInfo ndi;
> +
> +/* We require mem_io_pc in tb_invalidate_phys_page_range.  */
> +env_cpu(env)->mem_io_pc = retaddr;
> +
> +memory_notdirty_write_prepare(, env_cpu(env), addr,
> +  addr + iotlbentry->addr, size);
> +
> +if (unlikely(tlb_addr & TLB_BSWAP)) {
> +direct_swap(haddr, val);
> +} else {
> +direct(haddr, val);
> +}
> +
> +memory_notdirty_write_complete();
> +return;
> +}
> +
>  if (unlikely(tlb_addr & TLB_BSWAP)) {
>  direct_swap(haddr, val);
>  } else {
> diff --git a/exec.c b/exec.c
> index e21e068535..abf58b68a0 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -88,7 +88,6 @@ static MemoryRegion *system_io;
>  AddressSpace address_space_io;
>  AddressSpace address_space_memory;
>  
> -MemoryRegion io_mem_notdirty;
>  static MemoryRegion io_mem_unassigned;
>  #endif
>  
> @@ -157,7 +156,6 @@ typedef struct subpage_t {
>  } subpage_t;
>  
>  #define PHYS_SECTION_UNASSIGNED 0
> -#define PHYS_SECTION_NOTDIRTY 1
>  
>  static void io_mem_init(void);
>  static void memory_map_init(void);
> @@ -1438,9 +1436,6 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
>  if (memory_region_is_ram(section->mr)) {
>  /* Normal RAM.  */
>  iotlb = memory_region_get_ram_addr(section->mr) + xlat;
> -if (!section->readonly) {
> -iotlb |= PHYS_SECTION_NOTDIRTY;
> -}
>  } else {
>  AddressSpaceDispatch *d;
>  
> @@ -2749,42 +2744,6 @@ void memory_notdirty_write_complete(NotDirtyInfo *ndi)
>  }
>  }
>  
> -/* Called within RCU critical section.  */
> -static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
> -   uint64_t val, unsigned size)
> -{
> -NotDirtyInfo ndi;
> -
> -memory_notdirty_write_prepare(, current_cpu, 
> current_cpu->mem_io_vaddr,
> - ram_addr, size);
> -
> -stn_p(qemu_map_ram_ptr(NULL, ram_addr), size, val);
> -memory_notdirty_write_complete();
> -}
> -
> -static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
> - unsigned size, bool is_write,
> - MemTxAttrs attrs)
> -{
> -return is_write;
> -}
> -
> -static const MemoryRegionOps notdirty_mem_ops = {
> -

[PATCH v3 13/20] cputlb: Move NOTDIRTY handling from I/O path to TLB path

2019-09-21 Thread Richard Henderson
Pages that we want to track for NOTDIRTY are RAM.  We do not
really need to go through the I/O path to handle them.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu-common.h |  2 --
 accel/tcg/cputlb.c| 26 +---
 exec.c| 50 ---
 memory.c  | 16 -
 4 files changed, 23 insertions(+), 71 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 1c0e03ddc2..81753bbb34 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -100,8 +100,6 @@ void qemu_flush_coalesced_mmio_buffer(void);
 
 void cpu_flush_icache_range(hwaddr start, hwaddr len);
 
-extern struct MemoryRegion io_mem_notdirty;
-
 typedef int (RAMBlockIterFunc)(RAMBlock *rb, void *opaque);
 
 int qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque);
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 7ab523d7ec..b7bd738115 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -904,7 +904,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
 cpu->mem_io_pc = retaddr;
-if (mr != _mem_notdirty && !cpu->can_do_io) {
+if (!cpu->can_do_io) {
 cpu_io_recompile(cpu, retaddr);
 }
 
@@ -945,7 +945,7 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
-if (mr != _mem_notdirty && !cpu->can_do_io) {
+if (!cpu->can_do_io) {
 cpu_io_recompile(cpu, retaddr);
 }
 cpu->mem_io_vaddr = addr;
@@ -1606,7 +1606,7 @@ store_helper(CPUArchState *env, target_ulong addr, 
uint64_t val,
 }
 
 /* Handle I/O access.  */
-if (likely(tlb_addr & (TLB_MMIO | TLB_NOTDIRTY))) {
+if (tlb_addr & TLB_MMIO) {
 io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr,
   op ^ (tlb_addr & TLB_BSWAP ? MO_BSWAP : 0));
 return;
@@ -1619,6 +1619,26 @@ store_helper(CPUArchState *env, target_ulong addr, 
uint64_t val,
 
 haddr = (void *)((uintptr_t)addr + entry->addend);
 
+/* Handle clean RAM pages.  */
+if (tlb_addr & TLB_NOTDIRTY) {
+NotDirtyInfo ndi;
+
+/* We require mem_io_pc in tb_invalidate_phys_page_range.  */
+env_cpu(env)->mem_io_pc = retaddr;
+
+memory_notdirty_write_prepare(, env_cpu(env), addr,
+  addr + iotlbentry->addr, size);
+
+if (unlikely(tlb_addr & TLB_BSWAP)) {
+direct_swap(haddr, val);
+} else {
+direct(haddr, val);
+}
+
+memory_notdirty_write_complete();
+return;
+}
+
 if (unlikely(tlb_addr & TLB_BSWAP)) {
 direct_swap(haddr, val);
 } else {
diff --git a/exec.c b/exec.c
index e21e068535..abf58b68a0 100644
--- a/exec.c
+++ b/exec.c
@@ -88,7 +88,6 @@ static MemoryRegion *system_io;
 AddressSpace address_space_io;
 AddressSpace address_space_memory;
 
-MemoryRegion io_mem_notdirty;
 static MemoryRegion io_mem_unassigned;
 #endif
 
@@ -157,7 +156,6 @@ typedef struct subpage_t {
 } subpage_t;
 
 #define PHYS_SECTION_UNASSIGNED 0
-#define PHYS_SECTION_NOTDIRTY 1
 
 static void io_mem_init(void);
 static void memory_map_init(void);
@@ -1438,9 +1436,6 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
 if (memory_region_is_ram(section->mr)) {
 /* Normal RAM.  */
 iotlb = memory_region_get_ram_addr(section->mr) + xlat;
-if (!section->readonly) {
-iotlb |= PHYS_SECTION_NOTDIRTY;
-}
 } else {
 AddressSpaceDispatch *d;
 
@@ -2749,42 +2744,6 @@ void memory_notdirty_write_complete(NotDirtyInfo *ndi)
 }
 }
 
-/* Called within RCU critical section.  */
-static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
-   uint64_t val, unsigned size)
-{
-NotDirtyInfo ndi;
-
-memory_notdirty_write_prepare(, current_cpu, current_cpu->mem_io_vaddr,
- ram_addr, size);
-
-stn_p(qemu_map_ram_ptr(NULL, ram_addr), size, val);
-memory_notdirty_write_complete();
-}
-
-static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
- unsigned size, bool is_write,
- MemTxAttrs attrs)
-{
-return is_write;
-}
-
-static const MemoryRegionOps notdirty_mem_ops = {
-.write = notdirty_mem_write,
-.valid.accepts = notdirty_mem_accepts,
-.endianness = DEVICE_NATIVE_ENDIAN,
-.valid = {
-.min_access_size = 1,
-.max_access_size = 8,
-.unaligned = false,
-},
-.impl = {
-.min_access_size = 1,
-.max_access_size = 8,
-.unaligned =