* [PATCH] x86, ACPI: Increase override tables number limit
@ 2013-09-07 2:08 Yinghai Lu
2013-09-07 22:08 ` Rafael J. Wysocki
2013-09-09 13:25 ` Thomas Renninger
0 siblings, 2 replies; 5+ messages in thread
From: Yinghai Lu @ 2013-09-07 2:08 UTC (permalink / raw)
To: Rafael J. Wysocki, H. Peter Anvin
Cc: Tejun Heo, Thomas Renninger, Tang Chen, Toshi Kani, Len Brown,
linux-acpi, linux-kernel, Yinghai Lu
Current acpi tables in initrd is limited to 10, that is too small.
64 should be good enough as we have 35 sigs and could have several
SSDT.
Two problems in current code prevent us from increasing limit:
1. that cpio file info array is put in stack, as every element is 32
bytes, could run out of stack if we have that array size to 64.
We can move it out from stack, and make it as global and put it in
__initdata section.
2. early_ioremap only can remap 256k one time. Current code is mapping
10 tables one time. If we increase that limit, whole size could be
more than 256k, early_ioremap will fail with that.
We can map chunks one by one during copying, instead of mapping
all them one time.
-v2: According to tj, split it out to separated patch, also
rename array name to acpi_initrd_files.
-v3: Add some comments about mapping table one by one during copying
per tj.
-v4: copy one by one chunk instead as one single DSDT/SSDT could be
more than 256k.
-v5: fix compiling err when !CONFIG_SMP, found by Fengguang's robot
Signed-off-by: Yinghai <yinghai@kernel.org>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: linux-acpi@vger.kernel.org
Acked-by: Tejun Heo <tj@kernel.org>
Tested-by: Thomas Renninger <trenn@suse.de>
Reviewed-by: Tang Chen <tangchen@cn.fujitsu.com>
Tested-by: Tang Chen <tangchen@cn.fujitsu.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
---
arch/x86/include/asm/acpi.h | 1 +
drivers/acpi/osl.c | 44 ++++++++++++++++++++++++++++++++------------
2 files changed, 33 insertions(+), 12 deletions(-)
Index: linux-2.6/drivers/acpi/osl.c
===================================================================
--- linux-2.6.orig/drivers/acpi/osl.c
+++ linux-2.6/drivers/acpi/osl.c
@@ -569,8 +569,10 @@ static const char * const table_sigs[] =
#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
-/* Must not increase 10 or needs code modification below */
-#define ACPI_OVERRIDE_TABLES 10
+#define ACPI_OVERRIDE_TABLES 64
+static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES];
+
+#define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT)
void __init acpi_initrd_override(void *data, size_t size)
{
@@ -579,8 +581,6 @@ void __init acpi_initrd_override(void *d
struct acpi_table_header *table;
char cpio_path[32] = "kernel/firmware/acpi/";
struct cpio_data file;
- struct cpio_data early_initrd_files[ACPI_OVERRIDE_TABLES];
- char *p;
if (data == NULL || size == 0)
return;
@@ -625,8 +625,8 @@ void __init acpi_initrd_override(void *d
table->signature, cpio_path, file.name, table->length);
all_tables_size += table->length;
- early_initrd_files[table_nr].data = file.data;
- early_initrd_files[table_nr].size = file.size;
+ acpi_initrd_files[table_nr].data = file.data;
+ acpi_initrd_files[table_nr].size = file.size;
table_nr++;
}
if (table_nr == 0)
@@ -652,14 +652,34 @@ void __init acpi_initrd_override(void *d
memblock_reserve(acpi_tables_addr, all_tables_size);
arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
- p = early_ioremap(acpi_tables_addr, all_tables_size);
-
+ /*
+ * early_ioremap only can remap 256k one time. If we map all
+ * tables one time, we will hit the limit. Need to map chunks
+ * one by one during copying the same as that in relocate_initrd().
+ */
for (no = 0; no < table_nr; no++) {
- memcpy(p + total_offset, early_initrd_files[no].data,
- early_initrd_files[no].size);
- total_offset += early_initrd_files[no].size;
+ unsigned char *src_p = acpi_initrd_files[no].data;
+ phys_addr_t size = acpi_initrd_files[no].size;
+ phys_addr_t dest_addr = acpi_tables_addr + total_offset;
+ phys_addr_t slop, clen;
+ char *dest_p;
+
+ total_offset += size;
+
+ while (size) {
+ slop = dest_addr & ~PAGE_MASK;
+ clen = size;
+ if (clen > MAP_CHUNK_SIZE - slop)
+ clen = MAP_CHUNK_SIZE - slop;
+ dest_p = early_ioremap(dest_addr & PAGE_MASK,
+ clen + slop);
+ memcpy(dest_p + slop, src_p, clen);
+ early_iounmap(dest_p, clen + slop);
+ src_p += clen;
+ dest_addr += clen;
+ size -= clen;
+ }
}
- early_iounmap(p, all_tables_size);
}
#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
Index: linux-2.6/arch/x86/include/asm/acpi.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/acpi.h
+++ linux-2.6/arch/x86/include/asm/acpi.h
@@ -26,6 +26,7 @@
#include <acpi/pdc_intel.h>
#include <asm/numa.h>
+#include <asm/fixmap.h>
#include <asm/processor.h>
#include <asm/mmu.h>
#include <asm/mpspec.h>
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] x86, ACPI: Increase override tables number limit
2013-09-07 2:08 [PATCH] x86, ACPI: Increase override tables number limit Yinghai Lu
@ 2013-09-07 22:08 ` Rafael J. Wysocki
2013-09-09 14:49 ` H. Peter Anvin
2013-09-09 13:25 ` Thomas Renninger
1 sibling, 1 reply; 5+ messages in thread
From: Rafael J. Wysocki @ 2013-09-07 22:08 UTC (permalink / raw)
To: Yinghai Lu, H. Peter Anvin
Cc: Tejun Heo, Thomas Renninger, Tang Chen, Toshi Kani, Len Brown,
linux-acpi, linux-kernel
On Friday, September 06, 2013 07:08:00 PM Yinghai Lu wrote:
> Current acpi tables in initrd is limited to 10, that is too small.
> 64 should be good enough as we have 35 sigs and could have several
> SSDT.
>
> Two problems in current code prevent us from increasing limit:
> 1. that cpio file info array is put in stack, as every element is 32
> bytes, could run out of stack if we have that array size to 64.
> We can move it out from stack, and make it as global and put it in
> __initdata section.
> 2. early_ioremap only can remap 256k one time. Current code is mapping
> 10 tables one time. If we increase that limit, whole size could be
> more than 256k, early_ioremap will fail with that.
> We can map chunks one by one during copying, instead of mapping
> all them one time.
>
> -v2: According to tj, split it out to separated patch, also
> rename array name to acpi_initrd_files.
> -v3: Add some comments about mapping table one by one during copying
> per tj.
> -v4: copy one by one chunk instead as one single DSDT/SSDT could be
> more than 256k.
> -v5: fix compiling err when !CONFIG_SMP, found by Fengguang's robot
>
> Signed-off-by: Yinghai <yinghai@kernel.org>
Full name would be nice.
> Cc: Rafael J. Wysocki <rjw@sisk.pl>
> Cc: linux-acpi@vger.kernel.org
> Acked-by: Tejun Heo <tj@kernel.org>
> Tested-by: Thomas Renninger <trenn@suse.de>
> Reviewed-by: Tang Chen <tangchen@cn.fujitsu.com>
> Tested-by: Tang Chen <tangchen@cn.fujitsu.com>
> Acked-by: Toshi Kani <toshi.kani@hp.com>
Peter, any objections to the changes below from the x86 perspective?
> ---
> arch/x86/include/asm/acpi.h | 1 +
> drivers/acpi/osl.c | 44 ++++++++++++++++++++++++++++++++------------
> 2 files changed, 33 insertions(+), 12 deletions(-)
>
> Index: linux-2.6/drivers/acpi/osl.c
> ===================================================================
> --- linux-2.6.orig/drivers/acpi/osl.c
> +++ linux-2.6/drivers/acpi/osl.c
> @@ -569,8 +569,10 @@ static const char * const table_sigs[] =
>
> #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
>
> -/* Must not increase 10 or needs code modification below */
> -#define ACPI_OVERRIDE_TABLES 10
> +#define ACPI_OVERRIDE_TABLES 64
> +static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES];
> +
> +#define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT)
>
> void __init acpi_initrd_override(void *data, size_t size)
> {
> @@ -579,8 +581,6 @@ void __init acpi_initrd_override(void *d
> struct acpi_table_header *table;
> char cpio_path[32] = "kernel/firmware/acpi/";
> struct cpio_data file;
> - struct cpio_data early_initrd_files[ACPI_OVERRIDE_TABLES];
> - char *p;
>
> if (data == NULL || size == 0)
> return;
> @@ -625,8 +625,8 @@ void __init acpi_initrd_override(void *d
> table->signature, cpio_path, file.name, table->length);
>
> all_tables_size += table->length;
> - early_initrd_files[table_nr].data = file.data;
> - early_initrd_files[table_nr].size = file.size;
> + acpi_initrd_files[table_nr].data = file.data;
> + acpi_initrd_files[table_nr].size = file.size;
> table_nr++;
> }
> if (table_nr == 0)
> @@ -652,14 +652,34 @@ void __init acpi_initrd_override(void *d
> memblock_reserve(acpi_tables_addr, all_tables_size);
> arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
>
> - p = early_ioremap(acpi_tables_addr, all_tables_size);
> -
> + /*
> + * early_ioremap only can remap 256k one time. If we map all
> + * tables one time, we will hit the limit. Need to map chunks
> + * one by one during copying the same as that in relocate_initrd().
> + */
> for (no = 0; no < table_nr; no++) {
> - memcpy(p + total_offset, early_initrd_files[no].data,
> - early_initrd_files[no].size);
> - total_offset += early_initrd_files[no].size;
> + unsigned char *src_p = acpi_initrd_files[no].data;
> + phys_addr_t size = acpi_initrd_files[no].size;
> + phys_addr_t dest_addr = acpi_tables_addr + total_offset;
> + phys_addr_t slop, clen;
> + char *dest_p;
> +
> + total_offset += size;
> +
> + while (size) {
> + slop = dest_addr & ~PAGE_MASK;
> + clen = size;
> + if (clen > MAP_CHUNK_SIZE - slop)
> + clen = MAP_CHUNK_SIZE - slop;
> + dest_p = early_ioremap(dest_addr & PAGE_MASK,
> + clen + slop);
> + memcpy(dest_p + slop, src_p, clen);
> + early_iounmap(dest_p, clen + slop);
> + src_p += clen;
> + dest_addr += clen;
> + size -= clen;
> + }
> }
> - early_iounmap(p, all_tables_size);
> }
> #endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
>
> Index: linux-2.6/arch/x86/include/asm/acpi.h
> ===================================================================
> --- linux-2.6.orig/arch/x86/include/asm/acpi.h
> +++ linux-2.6/arch/x86/include/asm/acpi.h
> @@ -26,6 +26,7 @@
> #include <acpi/pdc_intel.h>
>
> #include <asm/numa.h>
> +#include <asm/fixmap.h>
> #include <asm/processor.h>
> #include <asm/mmu.h>
> #include <asm/mpspec.h>
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] x86, ACPI: Increase override tables number limit
2013-09-07 22:08 ` Rafael J. Wysocki
@ 2013-09-09 14:49 ` H. Peter Anvin
0 siblings, 0 replies; 5+ messages in thread
From: H. Peter Anvin @ 2013-09-09 14:49 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Yinghai Lu, Tejun Heo, Thomas Renninger, Tang Chen, Toshi Kani,
Len Brown, linux-acpi, linux-kernel
On 09/07/2013 03:08 PM, Rafael J. Wysocki wrote:
>
> Peter, any objections to the changes below from the x86 perspective?
>
No objection from me.
-hpa
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] x86, ACPI: Increase override tables number limit
2013-09-07 2:08 [PATCH] x86, ACPI: Increase override tables number limit Yinghai Lu
2013-09-07 22:08 ` Rafael J. Wysocki
@ 2013-09-09 13:25 ` Thomas Renninger
1 sibling, 0 replies; 5+ messages in thread
From: Thomas Renninger @ 2013-09-09 13:25 UTC (permalink / raw)
To: Yinghai Lu
Cc: Rafael J. Wysocki, H. Peter Anvin, Tejun Heo, Tang Chen,
Toshi Kani, Len Brown, linux-acpi, linux-kernel
Hi,
I do not have a problem with this, just for info:
On Friday, September 06, 2013 07:08:00 PM Yinghai Lu wrote:
> Current acpi tables in initrd is limited to 10, that is too small.
> 64 should be good enough as we have 35 sigs and could have several
> SSDT.
The whole mechanism is for debugging only. Nobody would (or should,
there simply is no use case), override all the ACPI tables.
You would either override the APIC table if you try with interrupt
assignments. Or correct a part in the DSDT and/or SSDT(s) and check if the
kernel runs smoothly without errors then, etc.
>
> Two problems in current code prevent us from increasing limit:
> 1. that cpio file info array is put in stack, as every element is 32
> bytes, could run out of stack if we have that array size to 64.
> We can move it out from stack, and make it as global and put it in
> __initdata section.
> 2. early_ioremap only can remap 256k one time. Current code is mapping
> 10 tables one time. If we increase that limit, whole size could be
> more than 256k, early_ioremap will fail with that.
> We can map chunks one by one during copying, instead of mapping
> all them one time.
This problem would persist, because the by far biggest table typically
is the DSDT with several ten thousand lines of code, while the other
tables typically only have some hundred.
Thomas
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] x86, ACPI: Increase override tables number limit
@ 2013-08-15 5:58 Yinghai Lu
0 siblings, 0 replies; 5+ messages in thread
From: Yinghai Lu @ 2013-08-15 5:58 UTC (permalink / raw)
To: Rafael J. Wysocki, H. Peter Anvin
Cc: Tejun Heo, Thomas Renninger, Tang Chen, Toshi Kani, Len Brown,
linux-acpi, linux-kernel, Yinghai Lu
Current acpi tables in initrd is limited to 10, that is too small.
64 should be good enough as we have 35 sigs and could have several
SSDT.
Two problems in current code prevent us from increasing limit:
1. that cpio file info array is put in stack, as every element is 32
bytes, could run out of stack if we have that array size to 64.
We can move it out from stack, and make it as global and put it in
__initdata section.
2. early_ioremap only can remap 256k one time. Current code is mapping
10 tables one time. If we increase that limit, whole size could be
more than 256k, early_ioremap will fail with that.
We can map table one by one during copying, instead of mapping
all them one time.
-v2: According to tj, split it out to separated patch, also
rename array name to acpi_initrd_files.
-v3: Add some comments about mapping table one by one during copying
per tj.
Signed-off-by: Yinghai <yinghai@kernel.org>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Cc: linux-acpi@vger.kernel.org
Acked-by: Tejun Heo <tj@kernel.org>
Tested-by: Thomas Renninger <trenn@suse.de>
Reviewed-by: Tang Chen <tangchen@cn.fujitsu.com>
Tested-by: Tang Chen <tangchen@cn.fujitsu.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
---
drivers/acpi/osl.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
Index: linux-2.6/drivers/acpi/osl.c
===================================================================
--- linux-2.6.orig/drivers/acpi/osl.c
+++ linux-2.6/drivers/acpi/osl.c
@@ -569,8 +569,8 @@ static const char * const table_sigs[] =
#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
-/* Must not increase 10 or needs code modification below */
-#define ACPI_OVERRIDE_TABLES 10
+#define ACPI_OVERRIDE_TABLES 64
+static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES];
void __init acpi_initrd_override(void *data, size_t size)
{
@@ -579,7 +579,6 @@ void __init acpi_initrd_override(void *d
struct acpi_table_header *table;
char cpio_path[32] = "kernel/firmware/acpi/";
struct cpio_data file;
- struct cpio_data early_initrd_files[ACPI_OVERRIDE_TABLES];
char *p;
if (data == NULL || size == 0)
@@ -617,8 +616,8 @@ void __init acpi_initrd_override(void *d
table->signature, cpio_path, file.name, table->length);
all_tables_size += table->length;
- early_initrd_files[table_nr].data = file.data;
- early_initrd_files[table_nr].size = file.size;
+ acpi_initrd_files[table_nr].data = file.data;
+ acpi_initrd_files[table_nr].size = file.size;
table_nr++;
}
if (table_nr == 0)
@@ -648,14 +647,19 @@ void __init acpi_initrd_override(void *d
memblock_reserve(acpi_tables_addr, all_tables_size);
arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
- p = early_ioremap(acpi_tables_addr, all_tables_size);
-
+ /*
+ * early_ioremap only can remap 256k one time. If we map all
+ * tables one time, we will hit the limit. Need to map table
+ * one by one during copying.
+ */
for (no = 0; no < table_nr; no++) {
- memcpy(p + total_offset, early_initrd_files[no].data,
- early_initrd_files[no].size);
- total_offset += early_initrd_files[no].size;
+ phys_addr_t size = acpi_initrd_files[no].size;
+
+ p = early_ioremap(acpi_tables_addr + total_offset, size);
+ memcpy(p, acpi_initrd_files[no].data, size);
+ early_iounmap(p, size);
+ total_offset += size;
}
- early_iounmap(p, all_tables_size);
}
#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-09-09 14:50 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-07 2:08 [PATCH] x86, ACPI: Increase override tables number limit Yinghai Lu
2013-09-07 22:08 ` Rafael J. Wysocki
2013-09-09 14:49 ` H. Peter Anvin
2013-09-09 13:25 ` Thomas Renninger
-- strict thread matches above, loose matches on Subject: below --
2013-08-15 5:58 Yinghai Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox