qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers


From: Michael S. Tsirkin
Subject: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers
Date: Thu, 31 Mar 2011 19:43:29 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

Currently, vga cards that allocate vga ram,
register it as regular ram. When this happens
a lot, vhost need to get notified and flush
its memory tables, which is slow.

This was observed with cirrus vga.

As a solution, add an explicit flag when
registering vga ram, vhost-net can simply ignore it.

Long term, we might be able to use this API
to avoid the need to request
dirty loggin from devices explicitly.

Tested: with cirrus vga only.

Signed-off-by: Michael S. Tsirkin <address@hidden>
---
 cpu-common.h    |   22 +++++++++++++++++-----
 exec.c          |   14 ++++++++------
 hw/cirrus_vga.c |   34 ++++++++++++++++++++++------------
 hw/g364fb.c     |    2 +-
 hw/vga-isa-mm.c |    4 ++--
 hw/vga-pci.c    |    3 ++-
 hw/vga.c        |    4 ++--
 hw/vhost.c      |    7 ++++++-
 8 files changed, 60 insertions(+), 30 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index acb91ac..e0477e9 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -18,10 +18,21 @@ typedef unsigned long ram_addr_t;
 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, 
uint32_t value);
 typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
 
-void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
-                                         ram_addr_t size,
-                                         ram_addr_t phys_offset,
-                                         ram_addr_t region_offset);
+void cpu_register_physical_memory_vga(target_phys_addr_t start_addr,
+                                      ram_addr_t size,
+                                      ram_addr_t phys_offset,
+                                      ram_addr_t region_offset,
+                                      bool vga_ram);
+
+static inline void cpu_register_physical_memory_offset(target_phys_addr_t 
start_addr,
+                                                       ram_addr_t size,
+                                                       ram_addr_t phys_offset,
+                                                       ram_addr_t 
region_offset)
+{
+    cpu_register_physical_memory_vga(start_addr, size, phys_offset,
+                                     region_offset, false);
+}
+
 static inline void cpu_register_physical_memory(target_phys_addr_t start_addr,
                                                 ram_addr_t size,
                                                 ram_addr_t phys_offset)
@@ -69,7 +80,8 @@ struct CPUPhysMemoryClient {
     void (*set_memory)(struct CPUPhysMemoryClient *client,
                        target_phys_addr_t start_addr,
                        ram_addr_t size,
-                       ram_addr_t phys_offset);
+                       ram_addr_t phys_offset,
+                       bool vga_ram);
     int (*sync_dirty_bitmap)(struct CPUPhysMemoryClient *client,
                              target_phys_addr_t start_addr,
                              target_phys_addr_t end_addr);
diff --git a/exec.c b/exec.c
index b992016..6435378 100644
--- a/exec.c
+++ b/exec.c
@@ -1635,11 +1635,12 @@ static QLIST_HEAD(memory_client_list, 
CPUPhysMemoryClient) memory_client_list
 
 static void cpu_notify_set_memory(target_phys_addr_t start_addr,
                                  ram_addr_t size,
-                                 ram_addr_t phys_offset)
+                                 ram_addr_t phys_offset,
+                                  bool vga_ram)
 {
     CPUPhysMemoryClient *client;
     QLIST_FOREACH(client, &memory_client_list, list) {
-        client->set_memory(client, start_addr, size, phys_offset);
+        client->set_memory(client, start_addr, size, phys_offset, vga_ram);
     }
 }
 
@@ -1682,7 +1683,7 @@ static void phys_page_for_each_in_l1_map(PhysPageDesc 
**phys_map,
                 continue;
             }
             client->set_memory(client, pd[l2].region_offset,
-                               TARGET_PAGE_SIZE, pd[l2].phys_offset);
+                               TARGET_PAGE_SIZE, pd[l2].phys_offset, false);
         }
     }
 }
@@ -2418,10 +2419,11 @@ static void *subpage_init (target_phys_addr_t base, 
ram_addr_t *phys,
    start_addr and region_offset are rounded down to a page boundary
    before calculating this offset.  This should not be a problem unless
    the low bits of start_addr and region_offset differ.  */
-void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
+void cpu_register_physical_memory_vga(target_phys_addr_t start_addr,
                                          ram_addr_t size,
                                          ram_addr_t phys_offset,
-                                         ram_addr_t region_offset)
+                                         ram_addr_t region_offset,
+                                         bool vga_ram)
 {
     target_phys_addr_t addr, end_addr;
     PhysPageDesc *p;
@@ -2432,7 +2434,7 @@ void 
cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
     if (kvm_enabled())
         kvm_set_phys_mem(start_addr, size, phys_offset);
 
-    cpu_notify_set_memory(start_addr, size, phys_offset);
+    cpu_notify_set_memory(start_addr, size, phys_offset, vga_ram);
 
     if (phys_offset == IO_MEM_UNASSIGNED) {
         region_offset = start_addr;
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index d04adeb..435d914 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2557,7 +2557,9 @@ static void map_linear_vram(CirrusVGAState *s)
     if (!s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
         s->vga.map_addr = s->vga.lfb_addr;
         s->vga.map_end = s->vga.lfb_end;
-        cpu_register_physical_memory(s->vga.map_addr, s->vga.map_end - 
s->vga.map_addr, s->vga.vram_offset);
+        cpu_register_physical_memory_vga(s->vga.map_addr,
+                                        s->vga.map_end - s->vga.map_addr,
+                                        s->vga.vram_offset, 0, true);
     }
 
     if (!s->vga.map_addr)
@@ -2566,26 +2568,34 @@ static void map_linear_vram(CirrusVGAState *s)
 #ifndef TARGET_IA64
     s->vga.lfb_vram_mapped = 0;
 
-    cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000,
-                                (s->vga.vram_offset + s->cirrus_bank_base[0]) 
| IO_MEM_UNASSIGNED);
-    cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000,
-                                (s->vga.vram_offset + s->cirrus_bank_base[1]) 
| IO_MEM_UNASSIGNED);
+    cpu_register_physical_memory_vga(isa_mem_base + 0xa0000, 0x8000,
+                                    (s->vga.vram_offset +
+                                     s->cirrus_bank_base[0]) |
+                                    IO_MEM_UNASSIGNED, 0, true);
+    cpu_register_physical_memory_vga(isa_mem_base + 0xa8000, 0x8000,
+                                    (s->vga.vram_offset +
+                                     s->cirrus_bank_base[1]) |
+                                    IO_MEM_UNASSIGNED, 0, true);
     if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
         && !((s->vga.sr[0x07] & 0x01) == 0)
         && !((s->vga.gr[0x0B] & 0x14) == 0x14)
         && !(s->vga.gr[0x0B] & 0x02)) {
 
         vga_dirty_vga_stop(&s->vga);
-        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000,
-                                    (s->vga.vram_offset + 
s->cirrus_bank_base[0]) | IO_MEM_RAM);
-        cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000,
-                                    (s->vga.vram_offset + 
s->cirrus_bank_base[1]) | IO_MEM_RAM);
+        cpu_register_physical_memory_vga(isa_mem_base + 0xa0000, 0x8000,
+                                        (s->vga.vram_offset +
+                                         s->cirrus_bank_base[0]) |
+                                        IO_MEM_RAM, 0, true);
+        cpu_register_physical_memory_vga(isa_mem_base + 0xa8000, 0x8000,
+                                        (s->vga.vram_offset +
+                                         s->cirrus_bank_base[1]) |
+                                        IO_MEM_RAM, 0, true);
 
         s->vga.lfb_vram_mapped = 1;
     }
     else {
         cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
                                      s->vga.vga_io_memory);
     }
 #endif
 
diff --git a/hw/g364fb.c b/hw/g364fb.c
index 3c8fb98..3734902 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -605,7 +605,7 @@ int g364fb_mm_init(target_phys_addr_t vram_base,
                                  g364fb_invalidate_display,
                                  g364fb_screen_dump, NULL, s);
 
-    cpu_register_physical_memory(vram_base, s->vram_size, s->vram_offset);
+    cpu_register_physical_memory_vga(vram_base, s->vram_size, s->vram_offset, 
0, true);
 
     io_ctrl = cpu_register_io_memory(g364fb_ctrl_read, g364fb_ctrl_write, s);
     cpu_register_physical_memory(ctrl_base, 0x200000, io_ctrl);
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index b4ff23c..500507d 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -123,8 +123,8 @@ int isa_vga_mm_init(target_phys_addr_t vram_base,
 
 #ifdef CONFIG_BOCHS_VBE
     /* XXX: use optimized standard vga accesses */
-    cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
-                                 VGA_RAM_SIZE, s->vga.vram_offset);
+    cpu_register_physical_memory_vga(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
+                                     VGA_RAM_SIZE, s->vga.vram_offset, 0, 
true);
 #endif
     return 0;
 }
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index f6fb1b3..3a673cf 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -55,7 +55,8 @@ static void vga_map(PCIDevice *pci_dev, int region_num,
     if (region_num == PCI_ROM_SLOT) {
         cpu_register_physical_memory(addr, s->bios_size, s->bios_offset);
     } else {
-        cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
+        cpu_register_physical_memory_vga(addr, s->vram_size, s->vram_offset, 0,
+                                         true);
         s->map_addr = addr;
         s->map_end = addr + s->vram_size;
         vga_dirty_vga_start(s);
diff --git a/hw/vga.c b/hw/vga.c
index 1d269d5..a742dd4 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2359,8 +2359,8 @@ void vga_init_vbe(VGACommonState *s)
 {
 #ifdef CONFIG_BOCHS_VBE
     /* XXX: use optimized standard vga accesses */
-    cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
-                                 VGA_RAM_SIZE, s->vram_offset);
+    cpu_register_physical_memory_vga(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
+                                     VGA_RAM_SIZE, s->vram_offset,0 , true);
     s->vbe_mapped = 1;
 #endif 
 }
diff --git a/hw/vhost.c b/hw/vhost.c
index 8e28fd9..27d08c0 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -379,7 +379,8 @@ static bool vhost_dev_cmp_memory(struct vhost_dev *dev,
 static void vhost_client_set_memory(CPUPhysMemoryClient *client,
                                     target_phys_addr_t start_addr,
                                     ram_addr_t size,
-                                    ram_addr_t phys_offset)
+                                    ram_addr_t phys_offset,
+                                    bool vga_ram)
 {
     struct vhost_dev *dev = container_of(client, struct vhost_dev, client);
     ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK;
@@ -388,6 +389,10 @@ static void vhost_client_set_memory(CPUPhysMemoryClient 
*client,
     uint64_t log_size;
     int r;
 
+    if (vga_ram) {
+        flags = IO_MEM_UNASSIGNED;
+    }
+
     /* Optimize no-change case. At least cirrus_vga does this a lot at this 
time. */
     if (flags == IO_MEM_RAM) {
         if (!vhost_dev_cmp_memory(dev, start_addr, size,
-- 
1.7.3.2.91.g446ac



reply via email to

[Prev in Thread] Current Thread [Next in Thread]