diff mbox

[1/1] pc & q35: fix handling of lowmem

Message ID 1393531262-5884-1-git-send-email-dslutz@verizon.com
State New
Headers show

Commit Message

Don Slutz Feb. 27, 2014, 8:01 p.m. UTC
Without this, asking for 3.25G on memory for pc-i440fx-2.0 does not
adjust the pci hole to start at 3G.  Asking for 3.75G does do this
adjustment.

Here is what the current code does:

out/x86_64-softmmu/qemu-system-x86_64 -serial pty ~/qemu-img/Lin-Net-disk1.raw -machine pc-i440fx-2.0 -m 3.75G

BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000bfffe000 (usable)
 BIOS-e820: 00000000bfffe000 - 00000000c0000000 (reserved)
 BIOS-e820: 00000000feffc000 - 00000000ff000000 (reserved)
 BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved)
 BIOS-e820: 0000000100000000 - 0000000130000000 (usable)

out/x86_64-softmmu/qemu-system-x86_64 -serial pty ~/qemu-img/Lin-Net-disk1.raw -machine pc-i440fx-1.7 -m 3.75G

BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000dfffe000 (usable)
 BIOS-e820: 00000000dfffe000 - 00000000e0000000 (reserved)
 BIOS-e820: 00000000feffc000 - 00000000ff000000 (reserved)
 BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved)
 BIOS-e820: 0000000100000000 - 0000000110000000 (usable)

out/x86_64-softmmu/qemu-system-x86_64 -serial pty ~/qemu-img/Lin-Net-disk1.raw -machine pc-i440fx-2.0 -m 3.25G

BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000cfffe000 (usable)
 BIOS-e820: 00000000cfffe000 - 00000000d0000000 (reserved)
 BIOS-e820: 00000000feffc000 - 00000000ff000000 (reserved)
 BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved)

out/x86_64-softmmu/qemu-system-x86_64 -serial pty ~/qemu-img/Lin-Net-disk1.raw -machine pc-i440fx-1.7 -m 3.25G

BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000cfffe000 (usable)
 BIOS-e820: 00000000cfffe000 - 00000000d0000000 (reserved)
 BIOS-e820: 00000000feffc000 - 00000000ff000000 (reserved)
 BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved)

After this patch:

out/x86_64-softmmu/qemu-system-x86_64 -serial pty ~/qemu-img/Lin-Net-disk1.raw -machine pc-i440fx-2.0 -m 3.75G

BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000bfffe000 (usable)
 BIOS-e820: 00000000bfffe000 - 00000000c0000000 (reserved)
 BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved)
 BIOS-e820: 0000000100000000 - 0000000130000000 (usable)

out/x86_64-softmmu/qemu-system-x86_64 -serial pty ~/qemu-img/Lin-Net-disk1.raw -machine pc-i440fx-1.7 -m 3.75G

BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000dfffe000 (usable)
 BIOS-e820: 00000000dfffe000 - 00000000e0000000 (reserved)
 BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved)
 BIOS-e820: 0000000100000000 - 0000000110000000 (usable)

out/x86_64-softmmu/qemu-system-x86_64 -serial pty ~/qemu-img/Lin-Net-disk1.raw -machine pc-i440fx-2.0 -m 3.25G

BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000bfffe000 (usable)
 BIOS-e820: 00000000bfffe000 - 00000000c0000000 (reserved)
 BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved)
 BIOS-e820: 0000000100000000 - 0000000110000000 (usable)

out/x86_64-softmmu/qemu-system-x86_64 -serial pty ~/qemu-img/Lin-Net-disk1.raw -machine pc-i440fx-1.7 -m 3.25G

BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000cfffe000 (usable)
 BIOS-e820: 00000000cfffe000 - 00000000d0000000 (reserved)
 BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved)

Signed-off-by: Don Slutz <dslutz@verizon.com>
---
 hw/i386/pc_piix.c | 13 ++++++++-----
 hw/i386/pc_q35.c  | 17 ++++++++++-------
 2 files changed, 18 insertions(+), 12 deletions(-)

Comments

Gerd Hoffmann Feb. 28, 2014, 1:35 p.m. UTC | #1
On Do, 2014-02-27 at 15:01 -0500, Don Slutz wrote:
> Without this, asking for 3.25G on memory for pc-i440fx-2.0 does not
> adjust the pci hole to start at 3G.  Asking for 3.75G does do this
> adjustment.

This is intentional.

If we can fit all ram into low memory, because it is less than 3.5G,
we'll do that (pc machine type, q35 numbers are different but logic is
the same).  This way 32bit (+non-PAE) guests can continue to have up to
3.5G memory.

If we can't fit all ram into low memory (thus the guest should be able
to access ram above 4G anyway), then we'll cut off at a gigabyte
boundary (3G for pc machine type).  This way our ram is nicely
gigabyte-aligned and we can get best performance benefits from huge
pages.

The size of the pci hole changing in the second case is only a side
effect, it's not the main reason for the change.

cheers,
  Gerd
Don Slutz Feb. 28, 2014, 3:14 p.m. UTC | #2
On 02/28/14 08:35, Gerd Hoffmann wrote:
> On Do, 2014-02-27 at 15:01 -0500, Don Slutz wrote:
>> Without this, asking for 3.25G on memory for pc-i440fx-2.0 does not
>> adjust the pci hole to start at 3G.  Asking for 3.75G does do this
>> adjustment.
> This is intentional.
>
> If we can fit all ram into low memory, because it is less than 3.5G,
> we'll do that (pc machine type, q35 numbers are different but logic is
> the same).  This way 32bit (+non-PAE) guests can continue to have up to
> 3.5G memory.
>
> If we can't fit all ram into low memory (thus the guest should be able
> to access ram above 4G anyway), then we'll cut off at a gigabyte
> boundary (3G for pc machine type).  This way our ram is nicely
> gigabyte-aligned and we can get best performance benefits from huge
> pages.
>
> The size of the pci hole changing in the second case is only a side
> effect, it's not the main reason for the change.
>
> cheers,
>    Gerd
>
>
Ok, I will drop this patch.
     -Don Slutz
diff mbox

Patch

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index d5dc1ef..4e63d8f 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -95,6 +95,11 @@  static void pc_init1(QEMUMachineInitArgs *args,
     DeviceState *icc_bridge;
     FWCfgState *fw_cfg = NULL;
     PcGuestInfo *guest_info;
+    /*
+     * For old machine types, use whatever split we used historically to avoid
+     * breaking migration.
+     */
+    ram_addr_t lowmem = gigabyte_align ? 0xc0000000 : 0xe0000000;
 
     if (xen_enabled() && xen_hvm_init(&ram_memory) != 0) {
         fprintf(stderr, "xen hardware virtual machine initialisation failed\n");
@@ -111,15 +116,13 @@  static void pc_init1(QEMUMachineInitArgs *args,
         kvmclock_create();
     }
 
-    /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory).
+    /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory (old)
+     * or 1 GByte for IO memory (new)).
      * If it doesn't, we need to split it in chunks below and above 4G.
      * In any case, try to make sure that guest addresses aligned at
      * 1G boundaries get mapped to host addresses aligned at 1G boundaries.
-     * For old machine types, use whatever split we used historically to avoid
-     * breaking migration.
      */
-    if (args->ram_size >= 0xe0000000) {
-        ram_addr_t lowmem = gigabyte_align ? 0xc0000000 : 0xe0000000;
+    if (args->ram_size >= lowmem) {
         above_4g_mem_size = args->ram_size - lowmem;
         below_4g_mem_size = lowmem;
     } else {
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index a7f6260..2627927 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -82,6 +82,11 @@  static void pc_q35_init(QEMUMachineInitArgs *args)
     PCIDevice *ahci;
     DeviceState *icc_bridge;
     PcGuestInfo *guest_info;
+    /*
+     * For old machine types, use whatever split we used historically to avoid
+     * breaking migration.
+     */
+    ram_addr_t lowmem = gigabyte_align ? 0x80000000 : 0xb0000000;
 
     if (xen_enabled() && xen_hvm_init(&ram_memory) != 0) {
         fprintf(stderr, "xen hardware virtual machine initialisation failed\n");
@@ -97,17 +102,15 @@  static void pc_q35_init(QEMUMachineInitArgs *args)
 
     kvmclock_create();
 
-    /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
-     * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
-     * also known as MMCFG).
+    /* Check whether RAM fits below 4G (leaving 1 and 3/8 GByte for
+     * IO memory and 256 Mbytes for PCI Express Enhanced
+     * Configuration Access Mapping also known as MMCFG (old) or
+     * leaving 2 GByte for IO memory (new)).
      * If it doesn't, we need to split it in chunks below and above 4G.
      * In any case, try to make sure that guest addresses aligned at
      * 1G boundaries get mapped to host addresses aligned at 1G boundaries.
-     * For old machine types, use whatever split we used historically to avoid
-     * breaking migration.
      */
-    if (args->ram_size >= 0xb0000000) {
-        ram_addr_t lowmem = gigabyte_align ? 0x80000000 : 0xb0000000;
+    if (args->ram_size >= lowmem) {
         above_4g_mem_size = args->ram_size - lowmem;
         below_4g_mem_size = lowmem;
     } else {