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
next 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 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.