Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH v3] x86/setup: get ramdisk parameters only once

16 views
Skip to first unread message

Alexander Kuleshov

unread,
Feb 9, 2016, 8:00:09 AM2/9/16
to
The check and definitions related to ramdisk are similar in the
early_reserve_initrd() and reserve_initrd() functions. We can
get size and address of ramdisk in the setup_arch() and than
pass ramdisk structure with filled ramdisk related parameters
to early_reserve_initrd(), reserve_initrd() and relocate_initrd()
functions.

This allows us to not get ramdisk parameters from the bootparams
every time and save 59 bytes:

text data bss dec hex filename
9281618 5010736 15474688 29767042 1c63582 vmlinux.orig

text data bss dec hex filename
9281559 5010736 15474688 29766983 1c63547 vmlinux

Signed-off-by: Alexander Kuleshov <kulesh...@gmail.com>
---
Tested as with virtual machine as with real hardware.

Changelog:

v3: introduced ramdisk setup which is filled in th
setup_arch() and passed to the early_reserve_initrd()
and reserve_initrd().

v2: parameter of reserve_initrd() - int -> bool.
commit message updated.

arch/x86/kernel/setup.c | 92 +++++++++++++++++++++++++------------------------
1 file changed, 47 insertions(+), 45 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d3d80e6..c9d8a86 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -169,6 +169,14 @@ static struct resource bss_resource = {
.flags = IORESOURCE_BUSY | IORESOURCE_MEM
};

+/*
+ * ramdisk setup
+ */
+struct ramdisk {
+ u64 image;
+ u64 size;
+ u64 end;
+};

#ifdef CONFIG_X86_32
/* cpu data as detected by the assembly code in head.S */
@@ -318,12 +326,10 @@ static u64 __init get_ramdisk_size(void)
return ramdisk_size;
}

-static void __init relocate_initrd(void)
+static void __init relocate_initrd(struct ramdisk ramdisk)
{
/* Assume only end is not page aligned */
- u64 ramdisk_image = get_ramdisk_image();
- u64 ramdisk_size = get_ramdisk_size();
- u64 area_size = PAGE_ALIGN(ramdisk_size);
+ u64 area_size = PAGE_ALIGN(ramdisk.size);

/* We need to move the initrd down into directly mapped mem */
relocated_ramdisk = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
@@ -331,77 +337,60 @@ static void __init relocate_initrd(void)

if (!relocated_ramdisk)
panic("Cannot find place for new RAMDISK of size %lld\n",
- ramdisk_size);
+ ramdisk.size);

/* Note: this includes all the mem currently occupied by
the initrd, we rely on that fact to keep the data intact. */
memblock_reserve(relocated_ramdisk, area_size);
initrd_start = relocated_ramdisk + PAGE_OFFSET;
- initrd_end = initrd_start + ramdisk_size;
+ initrd_end = initrd_start + ramdisk.size;
printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
- relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
+ relocated_ramdisk, relocated_ramdisk + ramdisk.size - 1);

- copy_from_early_mem((void *)initrd_start, ramdisk_image, ramdisk_size);
+ copy_from_early_mem((void *)initrd_start, ramdisk.image, ramdisk.size);

printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
" [mem %#010llx-%#010llx]\n",
- ramdisk_image, ramdisk_image + ramdisk_size - 1,
- relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
+ ramdisk.image, ramdisk.image + ramdisk.size - 1,
+ relocated_ramdisk, relocated_ramdisk + ramdisk.size - 1);
}

-static void __init early_reserve_initrd(void)
+static void __init early_reserve_initrd(struct ramdisk ramdisk)
{
- /* Assume only end is not page aligned */
- u64 ramdisk_image = get_ramdisk_image();
- u64 ramdisk_size = get_ramdisk_size();
- u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
-
- if (!boot_params.hdr.type_of_loader ||
- !ramdisk_image || !ramdisk_size)
- return; /* No initrd provided by bootloader */
-
- memblock_reserve(ramdisk_image, ramdisk_end - ramdisk_image);
+ memblock_reserve(ramdisk.image, ramdisk.end - ramdisk.image);
}
-static void __init reserve_initrd(void)
+static void __init reserve_initrd(struct ramdisk ramdisk)
{
- /* Assume only end is not page aligned */
- u64 ramdisk_image = get_ramdisk_image();
- u64 ramdisk_size = get_ramdisk_size();
- u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
u64 mapped_size;

- if (!boot_params.hdr.type_of_loader ||
- !ramdisk_image || !ramdisk_size)
- return; /* No initrd provided by bootloader */
-
initrd_start = 0;

mapped_size = memblock_mem_size(max_pfn_mapped);
- if (ramdisk_size >= (mapped_size>>1))
+ if (ramdisk.size >= (mapped_size>>1))
panic("initrd too large to handle, "
"disabling initrd (%lld needed, %lld available)\n",
- ramdisk_size, mapped_size>>1);
+ ramdisk.size, mapped_size>>1);

- printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n", ramdisk_image,
- ramdisk_end - 1);
+ printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n", ramdisk.image,
+ ramdisk.end - 1);

- if (pfn_range_is_mapped(PFN_DOWN(ramdisk_image),
- PFN_DOWN(ramdisk_end))) {
+ if (pfn_range_is_mapped(PFN_DOWN(ramdisk.image),
+ PFN_DOWN(ramdisk.end))) {
/* All are mapped, easy case */
- initrd_start = ramdisk_image + PAGE_OFFSET;
- initrd_end = initrd_start + ramdisk_size;
+ initrd_start = ramdisk.image + PAGE_OFFSET;
+ initrd_end = initrd_start + ramdisk.size;
return;
}

- relocate_initrd();
+ relocate_initrd(ramdisk);

- memblock_free(ramdisk_image, ramdisk_end - ramdisk_image);
+ memblock_free(ramdisk.image, ramdisk.end - ramdisk.image);
}
#else
-static void __init early_reserve_initrd(void)
+static void __init early_reserve_initrd(struct ramdisk ramdisk)
{
}
-static void __init reserve_initrd(void)
+static void __init reserve_initrd(struct ramdisk ramdisk)
{
}
#endif /* CONFIG_BLK_DEV_INITRD */
@@ -844,13 +833,25 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
*
* Note: On x86_64, fixmaps are ready for use even before this is called.
*/
-
void __init setup_arch(char **cmdline_p)
{
+ struct ramdisk ramdisk_image = {
+ .image = get_ramdisk_image(),
+ .size = get_ramdisk_size(),
+ /* Assume only end is not page aligned */
+ .end = PAGE_ALIGN(ramdisk_image.image + ramdisk_image.size)
+ };
+ bool reserve_ramdisk = true;
+
memblock_reserve(__pa_symbol(_text),
(unsigned long)__bss_stop - (unsigned long)_text);

- early_reserve_initrd();
+ if (!boot_params.hdr.type_of_loader || !ramdisk_image.image
+ || !ramdisk_image.size) {
+ reserve_ramdisk = false;
+ return; /* No initrd provided by bootloader */
+ } else
+ early_reserve_initrd(ramdisk_image);

/*
* At this point everything still needed from the boot loader
@@ -1135,7 +1136,8 @@ void __init setup_arch(char **cmdline_p)
/* Allocate bigger log buffer */
setup_log_buf(1);

- reserve_initrd();
+ if (reserve_ramdisk)
+ reserve_initrd(ramdisk_image);

#if defined(CONFIG_ACPI) && defined(CONFIG_BLK_DEV_INITRD)
acpi_initrd_override((void *)initrd_start, initrd_end - initrd_start);
--
2.7.0.25.gfc10eb5

Ingo Molnar

unread,
Feb 9, 2016, 8:20:07 AM2/9/16
to

* Alexander Kuleshov <kulesh...@gmail.com> wrote:

> +/*
> + * ramdisk setup
> + */
> +struct ramdisk {
> + u64 image;
> + u64 size;
> + u64 end;
> +};

So what exactly are 'image' and 'end'? The names are not self-descriptory. Please
add comments that describe them and use the opportunity to rename the fields to
more self-descriptory names.

> +static void __init relocate_initrd(struct ramdisk ramdisk)

Why pass by value, why not by address?

> {
> + u64 area_size = PAGE_ALIGN(ramdisk.size);

Why introduce a local variable here? Also, isn't ramdisk.size already page
aligned?

> +static void __init early_reserve_initrd(struct ramdisk ramdisk)
> {
> + memblock_reserve(ramdisk.image, ramdisk.end - ramdisk.image);
> }

Looks like a pretty pointless function now - can be expanded into its call site.

> void __init setup_arch(char **cmdline_p)
> {
> + struct ramdisk ramdisk_image = {
> + .image = get_ramdisk_image(),
> + .size = get_ramdisk_size(),
> + /* Assume only end is not page aligned */
> + .end = PAGE_ALIGN(ramdisk_image.image + ramdisk_image.size)
> + };
> + bool reserve_ramdisk = true;

Why not merge 'reserve_ramdisk' into the ramdisk state structure as well?

> - early_reserve_initrd();
> + if (!boot_params.hdr.type_of_loader || !ramdisk_image.image
> + || !ramdisk_image.size) {
> + reserve_ramdisk = false;
> + return; /* No initrd provided by bootloader */
> + } else
> + early_reserve_initrd(ramdisk_image);

Curly braces should be balanced.

Thanks,

Ingo

Alexander Kuleshov

unread,
Feb 11, 2016, 4:40:07 AM2/11/16
to
The check and definitions related to ramdisk are similar in the
early_reserve_initrd() and reserve_initrd() functions.

This patch introduces struct ramdisk which contains information
about initrd. This structure will be filled in the setup_arch()
and passed to the reserve_initrd() and relocate_initrd() functions.

This allows us to not get/check ramdisk parameters from the bootparams
every time in the early_reserve_initrd(), reserve_initrd() and
relocate_initrd() function.

Additionally we save 85 bytes:

text data bss dec hex filename
9292602 5011696 15675392 29979690 1c9742a vmlinux.orig

text data bss dec hex filename
9292517 5011696 15675392 29979605 1c973d5 vmlinux


Signed-off-by: Alexander Kuleshov <kulesh...@gmail.com>
---
Tested as with virtual machine as with real hardware.

Changelog:

v4:

* bool reserve_ramdisk moved to the struct ramdisk;
* fields of struct ramdisk are renamed to more understandable
names
* early_reserve_initrd() removed as it contains only one call
of memblock_resere. It was moved to the setup_arch
* stubs added for get_ramdisk_image() and get_ramdisk_size()
to prevent compilation error if CONFIG_BLK_DEV_INITRD=n
* initialization of ramdisk->end_addr is moved from in-place
initialization to prevent ‘ramdisk_image.size’ is used uninitialized
in this function warning.

v3: introduced ramdisk setup which is filled in th
setup_arch() and passed to the early_reserve_initrd()
and reserve_initrd().

v2: parameter of reserve_initrd() - int -> bool.
commit message updated.

arch/x86/kernel/setup.c | 105 +++++++++++++++++++++++++-----------------------
1 file changed, 54 insertions(+), 51 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d3d80e6..0f0ba51 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -169,6 +169,15 @@ static struct resource bss_resource = {
.flags = IORESOURCE_BUSY | IORESOURCE_MEM
};

+/*
+ * ramdisk setup
+ */
+struct ramdisk {
+ u64 start_addr; /* ramdisk load address */
+ u64 end_addr; /* ramdisk end address */
+ u64 size; /* ramdisk size */
+ bool reserve_ramdisk; /* do initrd provided by bootloader */
+};

#ifdef CONFIG_X86_32
/* cpu data as detected by the assembly code in head.S */
@@ -318,90 +327,70 @@ static u64 __init get_ramdisk_size(void)
return ramdisk_size;
}

-static void __init relocate_initrd(void)
+static void __init relocate_initrd(struct ramdisk *ramdisk)
{
- /* Assume only end is not page aligned */
- u64 ramdisk_image = get_ramdisk_image();
- u64 ramdisk_size = get_ramdisk_size();
- u64 area_size = PAGE_ALIGN(ramdisk_size);
-
/* We need to move the initrd down into directly mapped mem */
relocated_ramdisk = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
- area_size, PAGE_SIZE);
+ ramdisk->size, PAGE_SIZE);

if (!relocated_ramdisk)
panic("Cannot find place for new RAMDISK of size %lld\n",
- ramdisk_size);
+ ramdisk->size);

/* Note: this includes all the mem currently occupied by
the initrd, we rely on that fact to keep the data intact. */
- memblock_reserve(relocated_ramdisk, area_size);
+ memblock_reserve(relocated_ramdisk, ramdisk->size);
initrd_start = relocated_ramdisk + PAGE_OFFSET;
- initrd_end = initrd_start + ramdisk_size;
+ initrd_end = initrd_start + ramdisk->size;
printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
- relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
+ relocated_ramdisk, relocated_ramdisk + ramdisk->size - 1);

- copy_from_early_mem((void *)initrd_start, ramdisk_image, ramdisk_size);
+ copy_from_early_mem((void *)initrd_start, ramdisk->start_addr, ramdisk->size);

printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
" [mem %#010llx-%#010llx]\n",
- ramdisk_image, ramdisk_image + ramdisk_size - 1,
- relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
+ ramdisk->start_addr, ramdisk->start_addr + ramdisk->size - 1,
+ relocated_ramdisk, relocated_ramdisk + ramdisk->size - 1);
}

-static void __init early_reserve_initrd(void)
-{
- /* Assume only end is not page aligned */
- u64 ramdisk_image = get_ramdisk_image();
- u64 ramdisk_size = get_ramdisk_size();
- u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
-
- if (!boot_params.hdr.type_of_loader ||
- !ramdisk_image || !ramdisk_size)
- return; /* No initrd provided by bootloader */
-
- memblock_reserve(ramdisk_image, ramdisk_end - ramdisk_image);
-}
-static void __init reserve_initrd(void)
+static void __init reserve_initrd(struct ramdisk *ramdisk)
{
- /* Assume only end is not page aligned */
- u64 ramdisk_image = get_ramdisk_image();
- u64 ramdisk_size = get_ramdisk_size();
- u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
u64 mapped_size;

- if (!boot_params.hdr.type_of_loader ||
- !ramdisk_image || !ramdisk_size)
- return; /* No initrd provided by bootloader */
-
initrd_start = 0;

mapped_size = memblock_mem_size(max_pfn_mapped);
- if (ramdisk_size >= (mapped_size>>1))
+ if (ramdisk->size >= (mapped_size>>1))
panic("initrd too large to handle, "
"disabling initrd (%lld needed, %lld available)\n",
- ramdisk_size, mapped_size>>1);
+ ramdisk->size, mapped_size>>1);

- printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n", ramdisk_image,
- ramdisk_end - 1);
+ printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n",
+ ramdisk->start_addr, ramdisk->end_addr - 1);

- if (pfn_range_is_mapped(PFN_DOWN(ramdisk_image),
- PFN_DOWN(ramdisk_end))) {
+ if (pfn_range_is_mapped(PFN_DOWN(ramdisk->start_addr),
+ PFN_DOWN(ramdisk->end_addr))) {
/* All are mapped, easy case */
- initrd_start = ramdisk_image + PAGE_OFFSET;
- initrd_end = initrd_start + ramdisk_size;
+ initrd_start = ramdisk->start_addr + PAGE_OFFSET;
+ initrd_end = initrd_start + ramdisk->size;
return;
}

- relocate_initrd();
+ relocate_initrd(ramdisk);

- memblock_free(ramdisk_image, ramdisk_end - ramdisk_image);
+ memblock_free(ramdisk->start_addr,
+ ramdisk->end_addr - ramdisk->start_addr);
}
#else
-static void __init early_reserve_initrd(void)
+static u64 __init get_ramdisk_image(void)
+{
+ return 0;
+}
+static u64 __init get_ramdisk_size(void)
{
+ return 0;
}
-static void __init reserve_initrd(void)
+static void __init reserve_initrd(struct ramdisk *ramdisk)
{
}
#endif /* CONFIG_BLK_DEV_INITRD */
@@ -844,13 +833,26 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
*
* Note: On x86_64, fixmaps are ready for use even before this is called.
*/
-
void __init setup_arch(char **cmdline_p)
{
+ struct ramdisk ramdisk_image = {
+ .start_addr = get_ramdisk_image(),
+ .size = get_ramdisk_size(),
+ .reserve_ramdisk = true
+ };
+
+ /* Assume only end is not page aligned */
+ ramdisk_image.end_addr = PAGE_ALIGN(ramdisk_image.start_addr + ramdisk_image.size),
+
memblock_reserve(__pa_symbol(_text),
(unsigned long)__bss_stop - (unsigned long)_text);

- early_reserve_initrd();
+ if (!boot_params.hdr.type_of_loader || !ramdisk_image.start_addr
+ || !ramdisk_image.size)
+ ramdisk_image.reserve_ramdisk = false; /* No initrd provided by bootloader */
+ else
+ memblock_reserve(ramdisk_image.start_addr,
+ ramdisk_image.end_addr - ramdisk_image.start_addr);

/*
* At this point everything still needed from the boot loader
@@ -1135,7 +1137,8 @@ void __init setup_arch(char **cmdline_p)
/* Allocate bigger log buffer */
setup_log_buf(1);

- reserve_initrd();
+ if (ramdisk_image.reserve_ramdisk)
+ reserve_initrd(&ramdisk_image);

Ingo Molnar

unread,
Feb 17, 2016, 3:30:09 AM2/17/16
to

* Alexander Kuleshov <kulesh...@gmail.com> wrote:

> void __init setup_arch(char **cmdline_p)
> {
> + struct ramdisk ramdisk_image = {
> + .start_addr = get_ramdisk_image(),
> + .size = get_ramdisk_size(),
> + .reserve_ramdisk = true
> + };
> +
> + /* Assume only end is not page aligned */
> + ramdisk_image.end_addr = PAGE_ALIGN(ramdisk_image.start_addr + ramdisk_image.size),
> +
> memblock_reserve(__pa_symbol(_text),
> (unsigned long)__bss_stop - (unsigned long)_text);
>
> - early_reserve_initrd();
> + if (!boot_params.hdr.type_of_loader || !ramdisk_image.start_addr
> + || !ramdisk_image.size)

Don't do pointless line breaks.

> + ramdisk_image.reserve_ramdisk = false; /* No initrd provided by bootloader */
> + else
> + memblock_reserve(ramdisk_image.start_addr,
> + ramdisk_image.end_addr - ramdisk_image.start_addr);

There's a simpler way to write that line ...

> /*
> * At this point everything still needed from the boot loader
> @@ -1135,7 +1137,8 @@ void __init setup_arch(char **cmdline_p)
> /* Allocate bigger log buffer */
> setup_log_buf(1);
>
> - reserve_initrd();
> + if (ramdisk_image.reserve_ramdisk)
> + reserve_initrd(&ramdisk_image);

It's cleaner to make that check inside reserve_initrd() ...

Thanks,

Ingo

Alexander Kuleshov

unread,
Feb 17, 2016, 4:20:06 AM2/17/16
to
The check and definitions related to ramdisk are similar in the
early_reserve_initrd() and reserve_initrd() functions.

This patch introduces struct ramdisk which contains information
about initrd. This structure will be filled in the setup_arch()
and passed to the reserve_initrd() and relocate_initrd() functions.

This allows us to not get/check ramdisk parameters from the bootparams
every time in the early_reserve_initrd(), reserve_initrd() and
relocate_initrd() function.

Additionally we save 85 bytes:

text data bss dec hex filename
9292517 5011696 15675392 29979605 1c973d5 vmlinux

text data bss dec hex filename
9292602 5011696 15675392 29979690 1c9742a vmlinux

Signed-off-by: Alexander Kuleshov <kulesh...@gmail.com>
---
Tested as with virtual machine as with real hardware.

Changelog:

v5:

* move check of the reserve_ramdisk to the reserve_initrd()
* align ramdisk size in setup_arch() as it maybe not page
aligned and start_addr + size() will be different with end_addr
in this case
* style fixes

v4:

* bool reserve_ramdisk moved to the struct ramdisk;
* fields of struct ramdisk are renamed to more understandable
names
* early_reserve_initrd() removed as it contains only one call
of memblock_resere. It was moved to the setup_arch
* stubs added for get_ramdisk_image() and get_ramdisk_size()
to prevent compilation error if CONFIG_BLK_DEV_INITRD=n
* initialization of ramdisk->end_addr is moved from in-place
initialization to prevent ‘ramdisk_image.size’ is used uninitialized
in this function warning.

v3: introduced ramdisk setup which is filled in th
setup_arch() and passed to the early_reserve_initrd()
and reserve_initrd().

v2: parameter of reserve_initrd() - int -> bool.
commit message updated.

arch/x86/kernel/setup.c | 103 +++++++++++++++++++++++++-----------------------
1 file changed, 53 insertions(+), 50 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d3d80e6..d89d9ea 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -169,6 +169,15 @@ static struct resource bss_resource = {
.flags = IORESOURCE_BUSY | IORESOURCE_MEM
};

+/*
+ * ramdisk setup
+ */
+struct ramdisk {
+ u64 start_addr; /* ramdisk load address */
+ u64 end_addr; /* ramdisk end address */
+ u64 size; /* ramdisk size */
+ bool reserve_ramdisk; /* do initrd provided by bootloader */
+};

#ifdef CONFIG_X86_32
/* cpu data as detected by the assembly code in head.S */
@@ -318,90 +327,73 @@ static u64 __init get_ramdisk_size(void)
- return; /* No initrd provided by bootloader */
+ if (!ramdisk->reserve_ramdisk)
+ return;
+ return 0;
+}
+static u64 __init get_ramdisk_size(void)
+{
+ return 0;
}
-static void __init reserve_initrd(void)
+static void __init reserve_initrd(struct ramdisk *ramdisk)
{
}
#endif /* CONFIG_BLK_DEV_INITRD */
@@ -844,13 +836,24 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
*
* Note: On x86_64, fixmaps are ready for use even before this is called.
*/
-
void __init setup_arch(char **cmdline_p)
{
+ struct ramdisk ramdisk_image = {
+ .start_addr = get_ramdisk_image(),
+ .size = PAGE_ALIGN(get_ramdisk_size()),
+ .reserve_ramdisk = true
+ };
+
+ /* Assume end is not page aligned */
+ ramdisk_image.end_addr = PAGE_ALIGN(ramdisk_image.start_addr + ramdisk_image.size);
+
memblock_reserve(__pa_symbol(_text),
(unsigned long)__bss_stop - (unsigned long)_text);

- early_reserve_initrd();
+ if (!boot_params.hdr.type_of_loader || !ramdisk_image.start_addr || !ramdisk_image.size)
+ ramdisk_image.reserve_ramdisk = false; /* No initrd provided by bootloader */
+ else
+ memblock_reserve(ramdisk_image.start_addr, ramdisk_image.size);

/*
* At this point everything still needed from the boot loader
@@ -1135,7 +1138,7 @@ void __init setup_arch(char **cmdline_p)
/* Allocate bigger log buffer */
setup_log_buf(1);

- reserve_initrd();
+ reserve_initrd(&ramdisk_image);

#if defined(CONFIG_ACPI) && defined(CONFIG_BLK_DEV_INITRD)
acpi_initrd_override((void *)initrd_start, initrd_end - initrd_start);
--
2.7.0.364.g4943984

Ingo Molnar

unread,
Feb 17, 2016, 4:30:06 AM2/17/16
to

* Alexander Kuleshov <kulesh...@gmail.com> wrote:

> - early_reserve_initrd();
> + if (!boot_params.hdr.type_of_loader || !ramdisk_image.start_addr || !ramdisk_image.size)
> + ramdisk_image.reserve_ramdisk = false; /* No initrd provided by bootloader */
> + else
> + memblock_reserve(ramdisk_image.start_addr, ramdisk_image.size);

... and _now_ it's clear that it makes sense to keep early_reserve_initrd(), move
that new chunk of code to it and pass in the ramdisk structure.

Also, please rename the too long 'ramdisk_image' local variable to something
shorter: 'rd' is commonly used - but the original 'ramdisk' name was fine too.

Thanks,

Ingo

Alexander Kuleshov

unread,
Feb 17, 2016, 5:20:05 AM2/17/16
to
The check and definitions related to ramdisk are similar in the
early_reserve_initrd() and reserve_initrd() functions.

This patch introduces struct ramdisk which contains information
about initrd. This structure will be filled in the setup_arch()
and passed to the reserve_initrd() and relocate_initrd() functions.

This allows us to not get/check ramdisk parameters from the bootparams
every time in the early_reserve_initrd(), reserve_initrd() and
relocate_initrd() function.

Signed-off-by: Alexander Kuleshov <kulesh...@gmail.com>
---
Tested as with virtual machine as with real hardware.

Changelog:

v6:

* ramdisk_image renamed to ramdisk
* early check of initrd and memory reservation for it is
moved to the early_reserve_initrd() again.

v5:

* move check of the reserve_ramdisk to the reserve_initrd()
* align ramdisk size in setup_arch() as it maybe not page
aligned and start_addr + size() will be different with end_addr
in this case
* style fixes

v4:

* bool reserve_ramdisk moved to the struct ramdisk;
* fields of struct ramdisk are renamed to more understandable
names
* early_reserve_initrd() removed as it contains only one call
of memblock_resere. It was moved to the setup_arch
* stubs added for get_ramdisk_image() and get_ramdisk_size()
to prevent compilation error if CONFIG_BLK_DEV_INITRD=n
* initialization of ramdisk->end_addr is moved from in-place
initialization to prevent ‘ramdisk_image.size’ is used uninitialized
in this function warning.

v3: introduced ramdisk setup which is filled in th
setup_arch() and passed to the early_reserve_initrd()
and reserve_initrd().

v2: parameter of reserve_initrd() - int -> bool.
commit message updated.

arch/x86/kernel/setup.c | 109 ++++++++++++++++++++++++++----------------------
1 file changed, 60 insertions(+), 49 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d3d80e6..3a139b3 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -169,6 +169,15 @@ static struct resource bss_resource = {
.flags = IORESOURCE_BUSY | IORESOURCE_MEM
};

+/*
+ * ramdisk setup
+ */
+struct ramdisk {
+ u64 start_addr; /* ramdisk load address */
+ u64 end_addr; /* ramdisk end address */
+ u64 size; /* ramdisk size */
+ bool reserve_ramdisk; /* do initrd provided by bootloader */
+};

#ifdef CONFIG_X86_32
/* cpu data as detected by the assembly code in head.S */
@@ -318,90 +327,84 @@ static u64 __init get_ramdisk_size(void)
-static void __init early_reserve_initrd(void)
+static void __init early_reserve_initrd(struct ramdisk *ramdisk)
{
- /* Assume only end is not page aligned */
- u64 ramdisk_image = get_ramdisk_image();
- u64 ramdisk_size = get_ramdisk_size();
- u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
-
- if (!boot_params.hdr.type_of_loader ||
- !ramdisk_image || !ramdisk_size)
- return; /* No initrd provided by bootloader */
-
- memblock_reserve(ramdisk_image, ramdisk_end - ramdisk_image);
+ if (!boot_params.hdr.type_of_loader || !ramdisk->start_addr || !ramdisk->size)
+ ramdisk->reserve_ramdisk = false; /* No initrd provided by bootloader */
+ else
+ memblock_reserve(ramdisk->start_addr, ramdisk->size);
}
-static void __init reserve_initrd(void)
+
+static u64 __init get_ramdisk_size(void)
+{
+ return 0;
+}
+static void __init early_reserve_initrd(struct ramdisk *ramdisk)
+{
+
+}
+static void __init reserve_initrd(struct ramdisk *ramdisk)
{
}
#endif /* CONFIG_BLK_DEV_INITRD */
@@ -844,13 +847,21 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
*
* Note: On x86_64, fixmaps are ready for use even before this is called.
*/
-
void __init setup_arch(char **cmdline_p)
{
+ struct ramdisk ramdisk_image = {
+ .start_addr = get_ramdisk_image(),
+ .size = PAGE_ALIGN(get_ramdisk_size()),
+ .reserve_ramdisk = true
+ };
+
+ /* Assume end is not page aligned */
+ ramdisk_image.end_addr = PAGE_ALIGN(ramdisk_image.start_addr + ramdisk_image.size);
+
memblock_reserve(__pa_symbol(_text),
(unsigned long)__bss_stop - (unsigned long)_text);

- early_reserve_initrd();
+ early_reserve_initrd(&ramdisk_image);

/*
* At this point everything still needed from the boot loader
@@ -1135,7 +1146,7 @@ void __init setup_arch(char **cmdline_p)

Alexander Kuleshov

unread,
Feb 26, 2016, 2:40:06 AM2/26/16
to
The check and definitions related to ramdisk are similar in the
early_reserve_initrd() and reserve_initrd() functions.

This patch introduces struct ramdisk which contains information
about initrd. This structure will be filled in the setup_arch()
and passed to the reserve_initrd() and relocate_initrd() functions.

This allows us to not get/check ramdisk parameters from the bootparams
every time in the early_reserve_initrd(), reserve_initrd() and
relocate_initrd() function.

Signed-off-by: Alexander Kuleshov <kulesh...@gmail.com>
---
Tested as with virtual machine as with real hardware.

Changelog:

v7:

* ramdisk_image renamed to ramdisk in the setup_arch().
index d3d80e6..449b4da 100644
+ struct ramdisk ramdisk = {
+ .start_addr = get_ramdisk_image(),
+ .size = PAGE_ALIGN(get_ramdisk_size()),
+ .reserve_ramdisk = true
+ };
+
+ /* Assume end is not page aligned */
+ ramdisk.end_addr = PAGE_ALIGN(ramdisk.start_addr + ramdisk.size);
+
memblock_reserve(__pa_symbol(_text),
(unsigned long)__bss_stop - (unsigned long)_text);

- early_reserve_initrd();
+ early_reserve_initrd(&ramdisk);

/*
* At this point everything still needed from the boot loader
@@ -1135,7 +1146,7 @@ void __init setup_arch(char **cmdline_p)
/* Allocate bigger log buffer */
setup_log_buf(1);

- reserve_initrd();
+ reserve_initrd(&ramdisk);

#if defined(CONFIG_ACPI) && defined(CONFIG_BLK_DEV_INITRD)
acpi_initrd_override((void *)initrd_start, initrd_end - initrd_start);
--
2.7.2.335.g3476f70

Borislav Petkov

unread,
Feb 26, 2016, 3:40:06 AM2/26/16
to
On Fri, Feb 26, 2016 at 01:31:45PM +0600, Alexander Kuleshov wrote:
> arch/x86/kernel/setup.c | 109 ++++++++++++++++++++++++++----------------------
> 1 file changed, 60 insertions(+), 49 deletions(-)
>
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index d3d80e6..449b4da 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -169,6 +169,15 @@ static struct resource bss_resource = {
> .flags = IORESOURCE_BUSY | IORESOURCE_MEM
> };
>
> +/*
> + * ramdisk setup
> + */

No need for that comment - the struct naming and members should be
sufficient.
I think all those printks talking about ramdisk should be

printk(KERN_INFO "RAMDISK: ..."

for easier grepping of dmesg about ramdisk-specific messages. This
should be another patch though.

> - relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
> + relocated_ramdisk, relocated_ramdisk + ramdisk->size - 1);
>
> - copy_from_early_mem((void *)initrd_start, ramdisk_image, ramdisk_size);
> + copy_from_early_mem((void *)initrd_start, ramdisk->start_addr, ramdisk->size);
>
> printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
> " [mem %#010llx-%#010llx]\n",
> - ramdisk_image, ramdisk_image + ramdisk_size - 1,
> - relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
> + ramdisk->start_addr, ramdisk->start_addr + ramdisk->size - 1,
> + relocated_ramdisk, relocated_ramdisk + ramdisk->size - 1);
> }
> -

That \n should not have been deleted here.

> -static void __init early_reserve_initrd(void)
> +static void __init early_reserve_initrd(struct ramdisk *ramdisk)
> {
> - /* Assume only end is not page aligned */
> - u64 ramdisk_image = get_ramdisk_image();
> - u64 ramdisk_size = get_ramdisk_size();
> - u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
> -
> - if (!boot_params.hdr.type_of_loader ||
> - !ramdisk_image || !ramdisk_size)
> - return; /* No initrd provided by bootloader */
> -
> - memblock_reserve(ramdisk_image, ramdisk_end - ramdisk_image);
> + if (!boot_params.hdr.type_of_loader || !ramdisk->start_addr || !ramdisk->size)
> + ramdisk->reserve_ramdisk = false; /* No initrd provided by bootloader */
> + else
> + memblock_reserve(ramdisk->start_addr, ramdisk->size);
> }

Make this one even more readable:

static void __init early_reserve_initrd(struct ramdisk *ramdisk)
{
/* No initrd provided by bootloader */
if (!boot_params.hdr.type_of_loader ||
!ramdisk->start_addr ||
!ramdisk->size)
ramdisk->reserve_ramdisk = false;
else
memblock_reserve(ramdisk->start_addr, ramdisk->size);
}

It also has some whitespace damage.

> -static void __init reserve_initrd(void)
> +
> +static void __init reserve_initrd(struct ramdisk *ramdisk)
> {
> - /* Assume only end is not page aligned */
> - u64 ramdisk_image = get_ramdisk_image();
> - u64 ramdisk_size = get_ramdisk_size();
> - u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
> u64 mapped_size;
>
> - if (!boot_params.hdr.type_of_loader ||
> - !ramdisk_image || !ramdisk_size)
> - return; /* No initrd provided by bootloader */
> + if (!ramdisk->reserve_ramdisk)
> + return;
>
> initrd_start = 0;
>
> mapped_size = memblock_mem_size(max_pfn_mapped);
> - if (ramdisk_size >= (mapped_size>>1))
> + if (ramdisk->size >= (mapped_size>>1))

Space that shift out:

... mapped_size >> 1))

> panic("initrd too large to handle, "
> "disabling initrd (%lld needed, %lld available)\n",

The string in this panic() call should be a single line only for easier
grepping. With another patch though.

> - ramdisk_size, mapped_size>>1);
> + ramdisk->size, mapped_size>>1);

Space that shift out too.

>
> - printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n", ramdisk_image,
> - ramdisk_end - 1);
> + printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n",
> + ramdisk->start_addr, ramdisk->end_addr - 1);
>
> - if (pfn_range_is_mapped(PFN_DOWN(ramdisk_image),
> - PFN_DOWN(ramdisk_end))) {
> + if (pfn_range_is_mapped(PFN_DOWN(ramdisk->start_addr),
> + PFN_DOWN(ramdisk->end_addr))) {
> /* All are mapped, easy case */
> - initrd_start = ramdisk_image + PAGE_OFFSET;
> - initrd_end = initrd_start + ramdisk_size;
> + initrd_start = ramdisk->start_addr + PAGE_OFFSET;
> + initrd_end = initrd_start + ramdisk->size;
> return;
> }
>
> - relocate_initrd();
> + relocate_initrd(ramdisk);
>
> - memblock_free(ramdisk_image, ramdisk_end - ramdisk_image);
> + memblock_free(ramdisk->start_addr,
> + ramdisk->end_addr - ramdisk->start_addr);

Arg alignment should start at the function's opening brace.
More readable:

struct ramdisk ramdisk = {
.start_addr = get_ramdisk_image(),
.size = PAGE_ALIGN(get_ramdisk_size()),
.reserve_ramdisk = true,
};

> +
> + /* Assume end is not page aligned */
> + ramdisk.end_addr = PAGE_ALIGN(ramdisk.start_addr + ramdisk.size);
> +
> memblock_reserve(__pa_symbol(_text),
> (unsigned long)__bss_stop - (unsigned long)_text);
>
> - early_reserve_initrd();
> + early_reserve_initrd(&ramdisk);
>
> /*
> * At this point everything still needed from the boot loader
> @@ -1135,7 +1146,7 @@ void __init setup_arch(char **cmdline_p)
> /* Allocate bigger log buffer */
> setup_log_buf(1);
>
> - reserve_initrd();
> + reserve_initrd(&ramdisk);
>
> #if defined(CONFIG_ACPI) && defined(CONFIG_BLK_DEV_INITRD)
> acpi_initrd_override((void *)initrd_start, initrd_end - initrd_start);
> --
> 2.7.2.335.g3476f70
>

--
Regards/Gruss,
Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
--

Alexander Kuleshov

unread,
Feb 26, 2016, 4:10:05 AM2/26/16
to
The check and definitions related to ramdisk are similar in the
early_reserve_initrd() and reserve_initrd() functions.

This patch introduces struct ramdisk which contains information
about initrd. This structure will be filled in the setup_arch()
and passed to the reserve_initrd() and relocate_initrd() functions.

This allows us to not get/check ramdisk parameters from the bootparams
every time in the early_reserve_initrd(), reserve_initrd() and
relocate_initrd() function.

Signed-off-by: Alexander Kuleshov <kulesh...@gmail.com>
---
Tested as with virtual machine as with real hardware.

Changelog:

v8:

* style fixes.
arch/x86/kernel/setup.c | 107 ++++++++++++++++++++++++++----------------------
1 file changed, 59 insertions(+), 48 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d3d80e6..f18bbe2 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -169,6 +169,12 @@ static struct resource bss_resource = {
.flags = IORESOURCE_BUSY | IORESOURCE_MEM
};

+struct ramdisk {
+ u64 start_addr; /* ramdisk load address */
+ u64 end_addr; /* ramdisk end address */
+ u64 size; /* ramdisk size */
+ bool reserve_ramdisk; /* do initrd provided by bootloader */
+};

#ifdef CONFIG_X86_32
/* cpu data as detected by the assembly code in head.S */
@@ -318,90 +324,87 @@ static u64 __init get_ramdisk_size(void)
return ramdisk_size;
}

-static void __init relocate_initrd(void)
+static void __init relocate_initrd(struct ramdisk *ramdisk)
{
- /* Assume only end is not page aligned */
- u64 ramdisk_image = get_ramdisk_image();
- u64 ramdisk_size = get_ramdisk_size();
- u64 area_size = PAGE_ALIGN(ramdisk_size);
-
/* We need to move the initrd down into directly mapped mem */
relocated_ramdisk = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
- area_size, PAGE_SIZE);
+ ramdisk->size, PAGE_SIZE);

if (!relocated_ramdisk)
panic("Cannot find place for new RAMDISK of size %lld\n",
- ramdisk_size);
+ ramdisk->size);

/* Note: this includes all the mem currently occupied by
the initrd, we rely on that fact to keep the data intact. */
- memblock_reserve(relocated_ramdisk, area_size);
+ memblock_reserve(relocated_ramdisk, ramdisk->size);
initrd_start = relocated_ramdisk + PAGE_OFFSET;
- initrd_end = initrd_start + ramdisk_size;
+ initrd_end = initrd_start + ramdisk->size;
printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
- relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
+ relocated_ramdisk, relocated_ramdisk + ramdisk->size - 1);

- copy_from_early_mem((void *)initrd_start, ramdisk_image, ramdisk_size);
+ copy_from_early_mem((void *)initrd_start, ramdisk->start_addr, ramdisk->size);

printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
" [mem %#010llx-%#010llx]\n",
- ramdisk_image, ramdisk_image + ramdisk_size - 1,
- relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
+ ramdisk->start_addr, ramdisk->start_addr + ramdisk->size - 1,
+ relocated_ramdisk, relocated_ramdisk + ramdisk->size - 1);
}

-static void __init early_reserve_initrd(void)
+static void __init early_reserve_initrd(struct ramdisk *ramdisk)
{
- /* Assume only end is not page aligned */
- u64 ramdisk_image = get_ramdisk_image();
- u64 ramdisk_size = get_ramdisk_size();
- u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
-
+ /* No initrd provided by bootloader */
if (!boot_params.hdr.type_of_loader ||
- !ramdisk_image || !ramdisk_size)
- return; /* No initrd provided by bootloader */
-
- memblock_reserve(ramdisk_image, ramdisk_end - ramdisk_image);
+ !ramdisk->start_addr ||
+ !ramdisk->size)
+ ramdisk->reserve_ramdisk = false;
+ else
+ memblock_reserve(ramdisk->start_addr, ramdisk->size);
}
-static void __init reserve_initrd(void)
+
+static void __init reserve_initrd(struct ramdisk *ramdisk)
{
- /* Assume only end is not page aligned */
- u64 ramdisk_image = get_ramdisk_image();
- u64 ramdisk_size = get_ramdisk_size();
- u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
u64 mapped_size;

- if (!boot_params.hdr.type_of_loader ||
- !ramdisk_image || !ramdisk_size)
- return; /* No initrd provided by bootloader */
+ if (!ramdisk->reserve_ramdisk)
+ return;

initrd_start = 0;

mapped_size = memblock_mem_size(max_pfn_mapped);
- if (ramdisk_size >= (mapped_size>>1))
+ if (ramdisk->size >= (mapped_size >> 1))
panic("initrd too large to handle, "
- "disabling initrd (%lld needed, %lld available)\n",
- ramdisk_size, mapped_size>>1);
+ "disabling initrd (%lld needed, %lld available)\n",
+ ramdisk->size, mapped_size >> 1);

- printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n", ramdisk_image,
- ramdisk_end - 1);
+ printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n",
+ ramdisk->start_addr, ramdisk->end_addr - 1);

- if (pfn_range_is_mapped(PFN_DOWN(ramdisk_image),
- PFN_DOWN(ramdisk_end))) {
+ if (pfn_range_is_mapped(PFN_DOWN(ramdisk->start_addr),
+ PFN_DOWN(ramdisk->end_addr))) {
/* All are mapped, easy case */
- initrd_start = ramdisk_image + PAGE_OFFSET;
- initrd_end = initrd_start + ramdisk_size;
+ initrd_start = ramdisk->start_addr + PAGE_OFFSET;
+ initrd_end = initrd_start + ramdisk->size;
return;
}

- relocate_initrd();
+ relocate_initrd(ramdisk);

- memblock_free(ramdisk_image, ramdisk_end - ramdisk_image);
+ memblock_free(ramdisk->start_addr, ramdisk->size);

Borislav Petkov

unread,
Feb 26, 2016, 4:50:07 AM2/26/16
to
On Fri, Feb 26, 2016 at 03:04:36PM +0600, Alexander Kuleshov wrote:
> The check and definitions related to ramdisk are similar in the
> early_reserve_initrd() and reserve_initrd() functions.
>
> This patch introduces struct ramdisk which contains information
> about initrd. This structure will be filled in the setup_arch()
> and passed to the reserve_initrd() and relocate_initrd() functions.
>
> This allows us to not get/check ramdisk parameters from the bootparams
> every time in the early_reserve_initrd(), reserve_initrd() and
> relocate_initrd() function.
>
> Signed-off-by: Alexander Kuleshov <kulesh...@gmail.com>

...

> arch/x86/kernel/setup.c | 107 ++++++++++++++++++++++++++----------------------
> 1 file changed, 59 insertions(+), 48 deletions(-)

Reviewed-by: Borislav Petkov <b...@suse.de>

Ingo Molnar

unread,
Feb 27, 2016, 7:00:06 AM2/27/16
to

* Borislav Petkov <b...@suse.de> wrote:

> > void __init setup_arch(char **cmdline_p)
> > {
> > + struct ramdisk ramdisk = {
> > + .start_addr = get_ramdisk_image(),
> > + .size = PAGE_ALIGN(get_ramdisk_size()),
> > + .reserve_ramdisk = true
> > + };
>
> More readable:
>
> struct ramdisk ramdisk = {
> .start_addr = get_ramdisk_image(),
> .size = PAGE_ALIGN(get_ramdisk_size()),
> .reserve_ramdisk = true,
> };

So I find it highly annoying that this review feedback was done by Boris, but not
implemented in v8 :-(

I'd much have preferred fewer iterations and more careful implementation, which
would have resulted in much less time wasted on the reviewer side...

Anyway, to stop this trainwreck I've fixed this (and a few other small details)
and applied the patch, but I'd also like to point out that from now on I'll stop
accepting trivial patches from serial trivial patches contributors that are not
part of some larger, more substantial work...

Thanks,

Ingo

Borislav Petkov

unread,
Feb 27, 2016, 7:50:07 AM2/27/16
to
On Sat, Feb 27, 2016 at 12:55:46PM +0100, Ingo Molnar wrote:
> So I find it highly annoying that this review feedback was done by Boris, but not
> implemented in v8 :-(

And I missed it when going over v8. :-(

FWIW, since recently I get the impression that people don't take review
feedback seriously. Starting to think, why even bother...

> I'd much have preferred fewer iterations and more careful implementation, which
> would have resulted in much less time wasted on the reviewer side...

Agreed.

> Anyway, to stop this trainwreck I've fixed this (and a few other small details)
> and applied the patch, but I'd also like to point out that from now on I'll stop
> accepting trivial patches from serial trivial patches contributors that are not
> part of some larger, more substantial work...

Good idea. ACK.

tip-bot for Alexander Kuleshov

unread,
Feb 29, 2016, 6:00:06 AM2/29/16
to
Commit-ID: 6fc77525f509e16b1e909e5ffd6f9ad9dccc0f82
Gitweb: http://git.kernel.org/tip/6fc77525f509e16b1e909e5ffd6f9ad9dccc0f82
Author: Alexander Kuleshov <kulesh...@gmail.com>
AuthorDate: Fri, 26 Feb 2016 15:04:36 +0600
Committer: Ingo Molnar <mi...@kernel.org>
CommitDate: Sat, 27 Feb 2016 12:52:27 +0100

x86/setup: Calculate ramdisk parameters only once

The check and definitions related to ramdisk are similar in the
early_reserve_initrd() and reserve_initrd() functions.

This patch introduces 'struct ramdisk' which contains information
about initrd. This structure will be filled in the setup_arch()
and passed to the reserve_initrd() and relocate_initrd() functions.

This allows us to not get/check ramdisk parameters from the bootparams
every time in the early_reserve_initrd(), reserve_initrd() and
relocate_initrd() function.

Signed-off-by: Alexander Kuleshov <kulesh...@gmail.com>
Reviewed-by: Borislav Petkov <b...@suse.de>
Cc: Andrew Morton <ak...@linux-foundation.org>
Cc: Baoquan He <b...@redhat.com>
Cc: Dave Young <dyo...@redhat.com>
Cc: Joerg Roedel <jro...@suse.de>
Cc: Linus Torvalds <torv...@linux-foundation.org>
Cc: Mark Salter <msa...@redhat.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <tg...@linutronix.de>
Link: http://lkml.kernel.org/r/1456477476-16415-1-git-...@gmail.com
[ Small readability changes. ]
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
arch/x86/kernel/setup.c | 111 ++++++++++++++++++++++++++----------------------
1 file changed, 61 insertions(+), 50 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d3d80e6..5cf832c 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -169,6 +169,12 @@ static struct resource bss_resource = {
.flags = IORESOURCE_BUSY | IORESOURCE_MEM
};

+struct ramdisk {
+ u64 start_addr; /* ramdisk load address */
+ u64 end_addr; /* ramdisk end address */
+ u64 size; /* ramdisk size */
+ bool reserve_ramdisk; /* do initrd provided by bootloader */
+};

#ifdef CONFIG_X86_32
/* cpu data as detected by the assembly code in head.S */
@@ -309,6 +315,7 @@ static u64 __init get_ramdisk_image(void)

return ramdisk_image;
}
+
static u64 __init get_ramdisk_size(void)
{
u64 ramdisk_size = boot_params.hdr.ramdisk_size;
@@ -318,90 +325,87 @@ static u64 __init get_ramdisk_size(void)
+{
+ return 0;
+}
+static u64 __init get_ramdisk_size(void)
{
+ return 0;
}
-static void __init reserve_initrd(void)
+static void __init early_reserve_initrd(struct ramdisk *ramdisk)
+{
+
+}
+static void __init reserve_initrd(struct ramdisk *ramdisk)
{
}
#endif /* CONFIG_BLK_DEV_INITRD */
@@ -844,13 +848,20 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
*
* Note: On x86_64, fixmaps are ready for use even before this is called.
*/
-
void __init setup_arch(char **cmdline_p)
{
- memblock_reserve(__pa_symbol(_text),
- (unsigned long)__bss_stop - (unsigned long)_text);
+ struct ramdisk ramdisk = {
+ .start_addr = get_ramdisk_image(),
+ .size = PAGE_ALIGN(get_ramdisk_size()),
+ .reserve_ramdisk = true
+ };
+
+ /* Assume end is not page aligned */
+ ramdisk.end_addr = PAGE_ALIGN(ramdisk.start_addr + ramdisk.size);
+
+ memblock_reserve(__pa_symbol(_text), (unsigned long)(__bss_stop - _text));
0 new messages