[Top][All Lists]
[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
- [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers,
Michael S. Tsirkin <=
- Re: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers, Anthony Liguori, 2011/03/31
- Re: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers, Michael S. Tsirkin, 2011/03/31
- Re: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers, Anthony Liguori, 2011/03/31
- Re: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers, Michael S. Tsirkin, 2011/03/31
- Re: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers, Anthony Liguori, 2011/03/31
- Re: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers, Michael S. Tsirkin, 2011/03/31
- Re: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers, Anthony Liguori, 2011/03/31
- Re: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers, Alex Williamson, 2011/03/31
- Re: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers, Peter Maydell, 2011/03/31
- Re: [Qemu-devel] [PATCH RFC] vga: flag vga ram for notifiers, Anthony Liguori, 2011/03/31