qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers
Date: Thu, 31 Mar 2011 19:43:29 +0200	[thread overview]
Message-ID: <20110331174328.GA25133@redhat.com> (raw)

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 <mst@redhat.com>
---
 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	other threads:[~2011-03-31 17:43 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-31 17:43 Michael S. Tsirkin [this message]
2011-03-31 18:33 ` [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers Anthony Liguori
2011-03-31 18:49   ` Michael S. Tsirkin
2011-03-31 19:01     ` Anthony Liguori
2011-03-31 19:07       ` Michael S. Tsirkin
2011-03-31 19:26         ` Anthony Liguori
2011-03-31 20:03           ` Michael S. Tsirkin
2011-03-31 20:21             ` Anthony Liguori
2011-03-31 19:17       ` Alex Williamson
2011-03-31 19:18       ` Peter Maydell
2011-03-31 19:29         ` Anthony Liguori
2011-03-31 20:12           ` Peter Maydell
2011-03-31 20:23             ` Anthony Liguori
2011-03-31 21:32               ` Peter Maydell
2011-03-31 21:38                 ` Michael S. Tsirkin
2011-03-31 21:49                   ` Anthony Liguori
2011-03-31 23:42                     ` Michael S. Tsirkin
2011-04-01  0:44                       ` Anthony Liguori
2011-04-01  1:07                         ` Michael S. Tsirkin
2011-04-01  7:12                   ` Peter Maydell
2011-04-01 11:21                     ` Michael S. Tsirkin
2011-03-31 21:26           ` Michael S. Tsirkin
2011-03-31 21:32             ` Anthony Liguori
2011-03-31 21:37               ` Michael S. Tsirkin
2011-03-31 21:48                 ` Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110331174328.GA25133@redhat.com \
    --to=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).