All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/5] ACPI: parse the SPCR table
@ 2016-02-15 18:05 ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Aleksey Makarov,
	Russell King, Greg Kroah-Hartman, Rafael J . Wysocki,
	Leif Lindholm, Graeme Gregory, Al Stone, Christopher Covington

This patchset is based on the patchset by Leif Lindholm [1]

'ARM Server Base Boot Requirements' [2] mentions SPCR (Serial Port
Console Redirection Table) [3] as a mandatory ACPI table that
specifies the configuration of serial console.

SPCR support is included in QEMU's ARM mach-virt since 2.4 release.

Introduce a new function acpi_console_check().  At the uart port
registration, this function checks if the ACPI SPCR table specifies
its argument of type struct uart_port to be a console
and if so calls add_preferred_console().

Use SPCR to tell if SBSA serial driver should use 32-bit access to registers.

To be able to access SPCR table each time any console is registered
change __init to __ref for early_acpi_os_unmap_memory().

The patchset should be applied to tty-next.

v3:
Greg Kroah-Hartman did not like v2 so I have rewritten this patchset:

- drop acpi_match() member of struct console
- drop implementations of this member for pl011 and 8250
- drop the patch that renames some vars in printk.c as it is not needed anymore
- drpo patch that introduces system wide acpi_table_parse2().
  Instead introduce a custom acpi_table_parse_spcr() in spcr.c

Instead of introducing a new match_acpi() member of struct console,
this patchset introduces a new function acpi_console_check().
This function is called when a new uart is registered at serial_core.c
the same way OF code checks for console.  If the registered uart is the
console specified by SPCR table, this function calls add_preferred_console()

The restrictions of this approach are:

- only serial consoles can be set up
- only consoles specified by the memory/io address can be set up
  (SPCR can specify devices by PCI id/PCI address)

v2:
https://lkml.kernel.org/g/1455299022-11641-1-git-send-email-aleksey.makarov@linaro.org
- don't use SPCR if user specified console in command line
- fix initialization order of newcon->index = 0
- rename some variables at printk.c (Joe Perches, Peter Hurley)
- enable ACPI_SPCR_TABLE in a separate patch (Andy Shevchenko)
- remove the retry loop for console registering (Peter Hurley).
  Instead, obtain SPCR with acpi_get_table().  That works after
  call to acpi_early_init() i. e. in any *_initcall()
- describe design decision behind introducing acpi_match() (Peter Hurley)
- fix compilation for x86 + ACPI (Graeme Gregory)
- introduce DBG2 constants in a separate patch (Andy Shevchenko)
- fix a typo in DBG2 constants (Andy Shevchenko)
- add ACPI_DBG2_ARM_SBSA_32BIT constant (Christopher Covington)
- add support for ACPI_DBG2_ARM_SBSA_* consoles (Christopher Covington)
- add documentation for functions
- add a patch that uses SPCR to find if SBSA serial driver should use 32-bit
  accessor functions (Christopher Covington)
- change __init to __ref for early_acpi_os_unmap_memory() in a separate patch
- introduce acpi_table_parse2() in a separate patch
- fix fetching the SPCR table early (Mark Salter)
- add a patch from Mark Salter that introduces support for matching 8250-based
  consoles

v1:
https://lkml.kernel.org/g/1453722324-22407-1-git-send-email-aleksey.makarov@linaro.org

[1] https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm@linaro.org
[2] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
[3] https://msdn.microsoft.com/en-us/library/windows/hardware/dn639132(v=vs.85).aspx

Aleksey Makarov (5):
  ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  ACPI: parse SPCR and enable matching console
  ACPI: enable ACPI_SPCR_TABLE on ARM64
  ACPI: add definition of DBG2 subtypes
  serial: pl011: use SPCR to setup 32-bit access

 arch/arm64/Kconfig               |   1 +
 drivers/acpi/Kconfig             |   3 +
 drivers/acpi/Makefile            |   1 +
 drivers/acpi/osl.c               |   6 +-
 drivers/acpi/spcr.c              | 122 +++++++++++++++++++++++++++++++++++++++
 drivers/tty/serial/amba-pl011.c  |   2 +
 drivers/tty/serial/serial_core.c |  14 ++++-
 include/acpi/actbl2.h            |   5 ++
 include/linux/acpi.h             |  15 +++++
 9 files changed, 166 insertions(+), 3 deletions(-)
 create mode 100644 drivers/acpi/spcr.c

-- 
2.7.1

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 0/5] ACPI: parse the SPCR table
@ 2016-02-15 18:05 ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset is based on the patchset by Leif Lindholm [1]

'ARM Server Base Boot Requirements' [2] mentions SPCR (Serial Port
Console Redirection Table) [3] as a mandatory ACPI table that
specifies the configuration of serial console.

SPCR support is included in QEMU's ARM mach-virt since 2.4 release.

Introduce a new function acpi_console_check().  At the uart port
registration, this function checks if the ACPI SPCR table specifies
its argument of type struct uart_port to be a console
and if so calls add_preferred_console().

Use SPCR to tell if SBSA serial driver should use 32-bit access to registers.

To be able to access SPCR table each time any console is registered
change __init to __ref for early_acpi_os_unmap_memory().

The patchset should be applied to tty-next.

v3:
Greg Kroah-Hartman did not like v2 so I have rewritten this patchset:

- drop acpi_match() member of struct console
- drop implementations of this member for pl011 and 8250
- drop the patch that renames some vars in printk.c as it is not needed anymore
- drpo patch that introduces system wide acpi_table_parse2().
  Instead introduce a custom acpi_table_parse_spcr() in spcr.c

Instead of introducing a new match_acpi() member of struct console,
this patchset introduces a new function acpi_console_check().
This function is called when a new uart is registered at serial_core.c
the same way OF code checks for console.  If the registered uart is the
console specified by SPCR table, this function calls add_preferred_console()

The restrictions of this approach are:

- only serial consoles can be set up
- only consoles specified by the memory/io address can be set up
  (SPCR can specify devices by PCI id/PCI address)

v2:
https://lkml.kernel.org/g/1455299022-11641-1-git-send-email-aleksey.makarov at linaro.org
- don't use SPCR if user specified console in command line
- fix initialization order of newcon->index = 0
- rename some variables at printk.c (Joe Perches, Peter Hurley)
- enable ACPI_SPCR_TABLE in a separate patch (Andy Shevchenko)
- remove the retry loop for console registering (Peter Hurley).
  Instead, obtain SPCR with acpi_get_table().  That works after
  call to acpi_early_init() i. e. in any *_initcall()
- describe design decision behind introducing acpi_match() (Peter Hurley)
- fix compilation for x86 + ACPI (Graeme Gregory)
- introduce DBG2 constants in a separate patch (Andy Shevchenko)
- fix a typo in DBG2 constants (Andy Shevchenko)
- add ACPI_DBG2_ARM_SBSA_32BIT constant (Christopher Covington)
- add support for ACPI_DBG2_ARM_SBSA_* consoles (Christopher Covington)
- add documentation for functions
- add a patch that uses SPCR to find if SBSA serial driver should use 32-bit
  accessor functions (Christopher Covington)
- change __init to __ref for early_acpi_os_unmap_memory() in a separate patch
- introduce acpi_table_parse2() in a separate patch
- fix fetching the SPCR table early (Mark Salter)
- add a patch from Mark Salter that introduces support for matching 8250-based
  consoles

v1:
https://lkml.kernel.org/g/1453722324-22407-1-git-send-email-aleksey.makarov at linaro.org

[1] https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm at linaro.org
[2] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
[3] https://msdn.microsoft.com/en-us/library/windows/hardware/dn639132(v=vs.85).aspx

Aleksey Makarov (5):
  ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  ACPI: parse SPCR and enable matching console
  ACPI: enable ACPI_SPCR_TABLE on ARM64
  ACPI: add definition of DBG2 subtypes
  serial: pl011: use SPCR to setup 32-bit access

 arch/arm64/Kconfig               |   1 +
 drivers/acpi/Kconfig             |   3 +
 drivers/acpi/Makefile            |   1 +
 drivers/acpi/osl.c               |   6 +-
 drivers/acpi/spcr.c              | 122 +++++++++++++++++++++++++++++++++++++++
 drivers/tty/serial/amba-pl011.c  |   2 +
 drivers/tty/serial/serial_core.c |  14 ++++-
 include/acpi/actbl2.h            |   5 ++
 include/linux/acpi.h             |  15 +++++
 9 files changed, 166 insertions(+), 3 deletions(-)
 create mode 100644 drivers/acpi/spcr.c

-- 
2.7.1

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-15 18:05 ` Aleksey Makarov
@ 2016-02-15 18:05   ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Aleksey Makarov,
	Russell King, Greg Kroah-Hartman, Rafael J . Wysocki,
	Leif Lindholm, Graeme Gregory, Al Stone, Christopher Covington,
	Len Brown

early_acpi_os_unmap_memory() is marked as __init because it calls
__acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not set.

acpi_gbl_permanent_mmap is set in __init acpi_early_init()
so it is safe to call early_acpi_os_unmap_memory() from anywhere

We need this function to be non-__init because we need access to
some tables at unpredictable time--it may be before or after
acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
Redirection) table is needed each time a new console is registered.
It can be quite early (console_initcall) or when a module is inserted.
When this table accessed before acpi_gbl_permanent_mmap is set,
the pointer should be unmapped.  This is exactly what this function
does.

Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
---
 drivers/acpi/osl.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 67da6fb..8a552cd 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
 }
 EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
 
-void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
+/*
+ * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
+ * so it is safe to call early_acpi_os_unmap_memory() from anywhere
+ */
+void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
 {
 	if (!acpi_gbl_permanent_mmap)
 		__acpi_unmap_table(virt, size);
-- 
2.7.1

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-15 18:05   ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-arm-kernel

early_acpi_os_unmap_memory() is marked as __init because it calls
__acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not set.

acpi_gbl_permanent_mmap is set in __init acpi_early_init()
so it is safe to call early_acpi_os_unmap_memory() from anywhere

We need this function to be non-__init because we need access to
some tables at unpredictable time--it may be before or after
acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
Redirection) table is needed each time a new console is registered.
It can be quite early (console_initcall) or when a module is inserted.
When this table accessed before acpi_gbl_permanent_mmap is set,
the pointer should be unmapped.  This is exactly what this function
does.

Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
---
 drivers/acpi/osl.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 67da6fb..8a552cd 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
 }
 EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
 
-void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
+/*
+ * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
+ * so it is safe to call early_acpi_os_unmap_memory() from anywhere
+ */
+void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
 {
 	if (!acpi_gbl_permanent_mmap)
 		__acpi_unmap_table(virt, size);
-- 
2.7.1

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
  2016-02-15 18:05 ` Aleksey Makarov
@ 2016-02-15 18:05   ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Aleksey Makarov,
	Russell King, Greg Kroah-Hartman, Rafael J . Wysocki,
	Leif Lindholm, Graeme Gregory, Al Stone, Christopher Covington,
	Len Brown, Jiri Slaby

'ARM Server Base Boot Requiremets' [1] mentions SPCR (Serial Port
Console Redirection Table) [2] as a mandatory ACPI table that
specifies the configuration of serial console.

Parse this table and check if any registered console match the
description.  If it does, enable that console.

Introduce a new function acpi_console_check().  At the uart port
registration, this function checks if the ACPI SPCR table specifies
its argument of type struct uart_port to be a console
and if so calls add_preferred_console().

[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
[2] http://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx

Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
---
 drivers/acpi/Kconfig             |  3 ++
 drivers/acpi/Makefile            |  1 +
 drivers/acpi/spcr.c              | 97 ++++++++++++++++++++++++++++++++++++++++
 drivers/tty/serial/serial_core.c | 14 +++++-
 include/linux/acpi.h             | 10 +++++
 5 files changed, 123 insertions(+), 2 deletions(-)
 create mode 100644 drivers/acpi/spcr.c

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 65fb483..5611eb6 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -77,6 +77,9 @@ config ACPI_DEBUGGER_USER
 
 endif
 
+config ACPI_SPCR_TABLE
+	bool
+
 config ACPI_SLEEP
 	bool
 	depends on SUSPEND || HIBERNATION
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 346101c..708b143 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
+obj-$(CONFIG_ACPI_SPCR_TABLE)	+= spcr.o
 obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
 
 # processor has its own "processor." module_param namespace
diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
new file mode 100644
index 0000000..a1eca91
--- /dev/null
+++ b/drivers/acpi/spcr.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, Intel Corporation
+ * Copyright (c) 2015, Red Hat, Inc.
+ * Copyright (c) 2015, 2016 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define pr_fmt(fmt) "ACPI: SPCR: " fmt
+
+#include <linux/acpi.h>
+#include <linux/console.h>
+#include <linux/kernel.h>
+#include <linux/serial_core.h>
+
+static int acpi_table_parse_spcr(int (*handler)(struct acpi_table_spcr *table,
+						void *data), void *data)
+{
+	struct acpi_table_spcr *table = NULL;
+	acpi_size table_size;
+	acpi_status status;
+	int err;
+
+	status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0,
+					  (struct acpi_table_header **)&table,
+					  &table_size);
+
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	err = handler(table, data);
+
+	early_acpi_os_unmap_memory(table, table_size);
+
+	return err;
+}
+
+static int spcr_table_handler_check(struct acpi_table_spcr *table, void *data)
+{
+	struct uart_port *uport = data;
+	char *options;
+
+	if (table->header.revision < 2)
+		return -EOPNOTSUPP;
+
+	switch (table->baud_rate) {
+	case 3:
+		options = "9600";
+		break;
+	case 4:
+		options = "19200";
+		break;
+	case 6:
+		options = "57600";
+		break;
+	case 7:
+		options = "115200";
+		break;
+	default:
+		options = "";
+		break;
+	}
+
+	if ((table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY &&
+	     table->serial_port.address == (u64)uport->mapbase) ||
+	    (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_IO &&
+	     table->serial_port.address == (u64)uport->iobase)) {
+		pr_info("adding preferred console [%s%d]\n", uport->cons->name,
+			uport->line);
+		add_preferred_console(uport->cons->name, uport->line, options);
+		return 1;
+
+	}
+
+	return 0;
+}
+
+/**
+ * acpi_console_check - Check if uart matches the console specified by SPCR.
+ *
+ * @uport:	uart port to check
+ *
+ * This function checks if the ACPI SPCR table specifies @uport to be a console
+ * and if so calls add_preferred_console()
+ *
+ * Return: a non-error value if the console matches.
+ */
+bool acpi_console_check(struct uart_port *uport)
+{
+	if (acpi_disabled || console_set_on_cmdline)
+		return false;
+
+	return acpi_table_parse_spcr(spcr_table_handler_check, uport) > 0;
+}
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index a126a60..459ab54 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -34,6 +34,7 @@
 #include <linux/serial_core.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/acpi.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
@@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
 		spin_lock_init(&uport->lock);
 		lockdep_set_class(&uport->lock, &port_lock_key);
 	}
-	if (uport->cons && uport->dev)
-		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
+
+	/*
+	 * Support both open FW and ACPI access to console definitions.
+	 * Both of_console_check() and acpi_console_check() will call
+	 * add_preferred_console() if a console definition is found.
+	 */
+	if (uport->cons && uport->dev) {
+		if (!acpi_console_check(uport))
+			of_console_check(uport->dev->of_node, uport->cons->name,
+					 uport->line);
+	}
 
 	uart_configure_port(drv, state, uport);
 
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 06ed7e5..ea0c297 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
 #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
 #endif
 
+struct uart_port;
+#ifdef CONFIG_ACPI_SPCR_TABLE
+bool acpi_console_check(struct uart_port *uport);
+#else
+static inline bool acpi_console_check(struct uart_port *uport)
+{
+	return FALSE;
+}
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
-- 
2.7.1

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
@ 2016-02-15 18:05   ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-arm-kernel

'ARM Server Base Boot Requiremets' [1] mentions SPCR (Serial Port
Console Redirection Table) [2] as a mandatory ACPI table that
specifies the configuration of serial console.

Parse this table and check if any registered console match the
description.  If it does, enable that console.

Introduce a new function acpi_console_check().  At the uart port
registration, this function checks if the ACPI SPCR table specifies
its argument of type struct uart_port to be a console
and if so calls add_preferred_console().

[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
[2] http://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx

Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
---
 drivers/acpi/Kconfig             |  3 ++
 drivers/acpi/Makefile            |  1 +
 drivers/acpi/spcr.c              | 97 ++++++++++++++++++++++++++++++++++++++++
 drivers/tty/serial/serial_core.c | 14 +++++-
 include/linux/acpi.h             | 10 +++++
 5 files changed, 123 insertions(+), 2 deletions(-)
 create mode 100644 drivers/acpi/spcr.c

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 65fb483..5611eb6 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -77,6 +77,9 @@ config ACPI_DEBUGGER_USER
 
 endif
 
+config ACPI_SPCR_TABLE
+	bool
+
 config ACPI_SLEEP
 	bool
 	depends on SUSPEND || HIBERNATION
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 346101c..708b143 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
+obj-$(CONFIG_ACPI_SPCR_TABLE)	+= spcr.o
 obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
 
 # processor has its own "processor." module_param namespace
diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
new file mode 100644
index 0000000..a1eca91
--- /dev/null
+++ b/drivers/acpi/spcr.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, Intel Corporation
+ * Copyright (c) 2015, Red Hat, Inc.
+ * Copyright (c) 2015, 2016 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define pr_fmt(fmt) "ACPI: SPCR: " fmt
+
+#include <linux/acpi.h>
+#include <linux/console.h>
+#include <linux/kernel.h>
+#include <linux/serial_core.h>
+
+static int acpi_table_parse_spcr(int (*handler)(struct acpi_table_spcr *table,
+						void *data), void *data)
+{
+	struct acpi_table_spcr *table = NULL;
+	acpi_size table_size;
+	acpi_status status;
+	int err;
+
+	status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0,
+					  (struct acpi_table_header **)&table,
+					  &table_size);
+
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	err = handler(table, data);
+
+	early_acpi_os_unmap_memory(table, table_size);
+
+	return err;
+}
+
+static int spcr_table_handler_check(struct acpi_table_spcr *table, void *data)
+{
+	struct uart_port *uport = data;
+	char *options;
+
+	if (table->header.revision < 2)
+		return -EOPNOTSUPP;
+
+	switch (table->baud_rate) {
+	case 3:
+		options = "9600";
+		break;
+	case 4:
+		options = "19200";
+		break;
+	case 6:
+		options = "57600";
+		break;
+	case 7:
+		options = "115200";
+		break;
+	default:
+		options = "";
+		break;
+	}
+
+	if ((table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY &&
+	     table->serial_port.address == (u64)uport->mapbase) ||
+	    (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_IO &&
+	     table->serial_port.address == (u64)uport->iobase)) {
+		pr_info("adding preferred console [%s%d]\n", uport->cons->name,
+			uport->line);
+		add_preferred_console(uport->cons->name, uport->line, options);
+		return 1;
+
+	}
+
+	return 0;
+}
+
+/**
+ * acpi_console_check - Check if uart matches the console specified by SPCR.
+ *
+ * @uport:	uart port to check
+ *
+ * This function checks if the ACPI SPCR table specifies @uport to be a console
+ * and if so calls add_preferred_console()
+ *
+ * Return: a non-error value if the console matches.
+ */
+bool acpi_console_check(struct uart_port *uport)
+{
+	if (acpi_disabled || console_set_on_cmdline)
+		return false;
+
+	return acpi_table_parse_spcr(spcr_table_handler_check, uport) > 0;
+}
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index a126a60..459ab54 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -34,6 +34,7 @@
 #include <linux/serial_core.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/acpi.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
@@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
 		spin_lock_init(&uport->lock);
 		lockdep_set_class(&uport->lock, &port_lock_key);
 	}
-	if (uport->cons && uport->dev)
-		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
+
+	/*
+	 * Support both open FW and ACPI access to console definitions.
+	 * Both of_console_check() and acpi_console_check() will call
+	 * add_preferred_console() if a console definition is found.
+	 */
+	if (uport->cons && uport->dev) {
+		if (!acpi_console_check(uport))
+			of_console_check(uport->dev->of_node, uport->cons->name,
+					 uport->line);
+	}
 
 	uart_configure_port(drv, state, uport);
 
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 06ed7e5..ea0c297 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
 #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
 #endif
 
+struct uart_port;
+#ifdef CONFIG_ACPI_SPCR_TABLE
+bool acpi_console_check(struct uart_port *uport);
+#else
+static inline bool acpi_console_check(struct uart_port *uport)
+{
+	return FALSE;
+}
+#endif
+
 #endif	/*_LINUX_ACPI_H*/
-- 
2.7.1

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] ACPI: enable ACPI_SPCR_TABLE on ARM64
  2016-02-15 18:05 ` Aleksey Makarov
@ 2016-02-15 18:05   ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Aleksey Makarov,
	Russell King, Greg Kroah-Hartman, Rafael J . Wysocki,
	Leif Lindholm, Graeme Gregory, Al Stone, Christopher Covington,
	Catalin Marinas, Will Deacon

SBBR mentions SPCR as a mandatory ACPI table.
So enable it for ARM64

Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
---
 arch/arm64/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6bb21d8..75739cd 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -3,6 +3,7 @@ config ARM64
 	select ACPI_CCA_REQUIRED if ACPI
 	select ACPI_GENERIC_GSI if ACPI
 	select ACPI_REDUCED_HARDWARE_ONLY if ACPI
+	select ACPI_SPCR_TABLE if ACPI
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_ELF_RANDOMIZE
-- 
2.7.1

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] ACPI: enable ACPI_SPCR_TABLE on ARM64
@ 2016-02-15 18:05   ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-arm-kernel

SBBR mentions SPCR as a mandatory ACPI table.
So enable it for ARM64

Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
---
 arch/arm64/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6bb21d8..75739cd 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -3,6 +3,7 @@ config ARM64
 	select ACPI_CCA_REQUIRED if ACPI
 	select ACPI_GENERIC_GSI if ACPI
 	select ACPI_REDUCED_HARDWARE_ONLY if ACPI
+	select ACPI_SPCR_TABLE if ACPI
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_ELF_RANDOMIZE
-- 
2.7.1

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v3 4/5] ACPI: add definition of DBG2 subtypes
  2016-02-15 18:05 ` Aleksey Makarov
@ 2016-02-15 18:05   ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Aleksey Makarov,
	Russell King, Greg Kroah-Hartman, Rafael J . Wysocki,
	Leif Lindholm, Graeme Gregory, Al Stone, Christopher Covington,
	Len Brown, Robert Moore, Lv Zheng, devel

The recent version of Microsoft Debug Port Table 2 (DBG2) [1]
specifies additional serial debug port subtypes.  These constants
are also referred by Serial Port Console Redirection Table (SPCR) [2]

Add these constants.

[1] https://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx
[2] https://msdn.microsoft.com/en-us/library/windows/hardware/dn639132(v=vs.85).aspx

Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
---
 include/acpi/actbl2.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index a4ef625..e9930ab 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -371,6 +371,11 @@ struct acpi_dbg2_device {
 
 #define ACPI_DBG2_16550_COMPATIBLE  0x0000
 #define ACPI_DBG2_16550_SUBSET      0x0001
+#define ACPI_DBG2_ARM_PL011         0x0003
+#define ACPI_DBG2_ARM_SBSA_32BIT    0x000d
+#define ACPI_DBG2_ARM_SBSA_GENERIC  0x000e
+#define ACPI_DBG2_ARM_DCC           0x000f
+#define ACPI_DBG2_BCM2835           0x0010
 
 #define ACPI_DBG2_1394_STANDARD     0x0000
 
-- 
2.7.1

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v3 4/5] ACPI: add definition of DBG2 subtypes
@ 2016-02-15 18:05   ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-arm-kernel

The recent version of Microsoft Debug Port Table 2 (DBG2) [1]
specifies additional serial debug port subtypes.  These constants
are also referred by Serial Port Console Redirection Table (SPCR) [2]

Add these constants.

[1] https://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx
[2] https://msdn.microsoft.com/en-us/library/windows/hardware/dn639132(v=vs.85).aspx

Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
---
 include/acpi/actbl2.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index a4ef625..e9930ab 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -371,6 +371,11 @@ struct acpi_dbg2_device {
 
 #define ACPI_DBG2_16550_COMPATIBLE  0x0000
 #define ACPI_DBG2_16550_SUBSET      0x0001
+#define ACPI_DBG2_ARM_PL011         0x0003
+#define ACPI_DBG2_ARM_SBSA_32BIT    0x000d
+#define ACPI_DBG2_ARM_SBSA_GENERIC  0x000e
+#define ACPI_DBG2_ARM_DCC           0x000f
+#define ACPI_DBG2_BCM2835           0x0010
 
 #define ACPI_DBG2_1394_STANDARD     0x0000
 
-- 
2.7.1

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v3 5/5] serial: pl011: use SPCR to setup 32-bit access
  2016-02-15 18:05 ` Aleksey Makarov
@ 2016-02-15 18:05   ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Aleksey Makarov,
	Russell King, Greg Kroah-Hartman, Rafael J . Wysocki,
	Leif Lindholm, Graeme Gregory, Al Stone, Christopher Covington,
	Len Brown, Jiri Slaby

Some implementations of ARM SBSA serial port hardware require that access
to the registers should be 32-bit.  Unfortunately, the only way for
the driver to tell if it's the case is to use the data from ACPI SPCR/DBG2
tables.  In this case the value of the 'Interface Type' field of the SPCR
table is ACPI_DBG2_ARM_SBSA_32BIT.

How this value is described in the DBG2 spec:
"(deprecated) ARM SBSA (2.x only) Generic UART supporting only
32-bit accesses"

Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
---
 drivers/acpi/spcr.c             | 25 +++++++++++++++++++++++++
 drivers/tty/serial/amba-pl011.c |  2 ++
 include/linux/acpi.h            |  5 +++++
 3 files changed, 32 insertions(+)

diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
index a1eca91..a5e241d 100644
--- a/drivers/acpi/spcr.c
+++ b/drivers/acpi/spcr.c
@@ -95,3 +95,28 @@ bool acpi_console_check(struct uart_port *uport)
 
 	return acpi_table_parse_spcr(spcr_table_handler_check, uport) > 0;
 }
+
+static int spcr_table_handler_32_bit(struct acpi_table_spcr *table, void *data)
+{
+	return table->interface_type == ACPI_DBG2_ARM_SBSA_32BIT;
+}
+
+/**
+ * acpi_console_sbsa_32bit - Tell if SPCR specifies 32-bit SBSA.
+ *
+ * Some implementations of ARM SBSA serial port hardware require that access
+ * to the registers should be 32-bit.  Unfortunately, the only way for
+ * the driver to tell if it's the case is to use the data from ACPI SPCR/DBG2
+ * tables.  In this case the value of the 'Interface Type' field of the SPCR
+ * table is ACPI_DBG2_ARM_SBSA_32BIT.
+ *
+ * Return: true if access should be 32-bit wide.
+ */
+bool acpi_console_sbsa_32bit(void)
+{
+	if (acpi_disabled)
+		return false;
+
+	return acpi_table_parse_spcr(spcr_table_handler_32_bit, NULL) > 0;
+}
+EXPORT_SYMBOL(acpi_console_sbsa_32bit);
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 500232a..d9ca3a4 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -2541,6 +2541,8 @@ static int sbsa_uart_probe(struct platform_device *pdev)
 		baudrate = 115200;
 	}
 
+	vendor_sbsa.access_32b = acpi_console_sbsa_32bit();
+
 	portnr = pl011_find_free_port();
 	if (portnr < 0)
 		return portnr;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index ea0c297..da1eb23 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1007,11 +1007,16 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
 struct uart_port;
 #ifdef CONFIG_ACPI_SPCR_TABLE
 bool acpi_console_check(struct uart_port *uport);
+bool acpi_console_sbsa_32bit(void);
 #else
 static inline bool acpi_console_check(struct uart_port *uport)
 {
 	return FALSE;
 }
+static inline bool acpi_console_sbsa_32bit(void)
+{
+	return false;
+}
 #endif
 
 #endif	/*_LINUX_ACPI_H*/
-- 
2.7.1

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v3 5/5] serial: pl011: use SPCR to setup 32-bit access
@ 2016-02-15 18:05   ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-15 18:05 UTC (permalink / raw)
  To: linux-arm-kernel

Some implementations of ARM SBSA serial port hardware require that access
to the registers should be 32-bit.  Unfortunately, the only way for
the driver to tell if it's the case is to use the data from ACPI SPCR/DBG2
tables.  In this case the value of the 'Interface Type' field of the SPCR
table is ACPI_DBG2_ARM_SBSA_32BIT.

How this value is described in the DBG2 spec:
"(deprecated) ARM SBSA (2.x only) Generic UART supporting only
32-bit accesses"

Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
---
 drivers/acpi/spcr.c             | 25 +++++++++++++++++++++++++
 drivers/tty/serial/amba-pl011.c |  2 ++
 include/linux/acpi.h            |  5 +++++
 3 files changed, 32 insertions(+)

diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
index a1eca91..a5e241d 100644
--- a/drivers/acpi/spcr.c
+++ b/drivers/acpi/spcr.c
@@ -95,3 +95,28 @@ bool acpi_console_check(struct uart_port *uport)
 
 	return acpi_table_parse_spcr(spcr_table_handler_check, uport) > 0;
 }
+
+static int spcr_table_handler_32_bit(struct acpi_table_spcr *table, void *data)
+{
+	return table->interface_type == ACPI_DBG2_ARM_SBSA_32BIT;
+}
+
+/**
+ * acpi_console_sbsa_32bit - Tell if SPCR specifies 32-bit SBSA.
+ *
+ * Some implementations of ARM SBSA serial port hardware require that access
+ * to the registers should be 32-bit.  Unfortunately, the only way for
+ * the driver to tell if it's the case is to use the data from ACPI SPCR/DBG2
+ * tables.  In this case the value of the 'Interface Type' field of the SPCR
+ * table is ACPI_DBG2_ARM_SBSA_32BIT.
+ *
+ * Return: true if access should be 32-bit wide.
+ */
+bool acpi_console_sbsa_32bit(void)
+{
+	if (acpi_disabled)
+		return false;
+
+	return acpi_table_parse_spcr(spcr_table_handler_32_bit, NULL) > 0;
+}
+EXPORT_SYMBOL(acpi_console_sbsa_32bit);
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 500232a..d9ca3a4 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -2541,6 +2541,8 @@ static int sbsa_uart_probe(struct platform_device *pdev)
 		baudrate = 115200;
 	}
 
+	vendor_sbsa.access_32b = acpi_console_sbsa_32bit();
+
 	portnr = pl011_find_free_port();
 	if (portnr < 0)
 		return portnr;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index ea0c297..da1eb23 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1007,11 +1007,16 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
 struct uart_port;
 #ifdef CONFIG_ACPI_SPCR_TABLE
 bool acpi_console_check(struct uart_port *uport);
+bool acpi_console_sbsa_32bit(void);
 #else
 static inline bool acpi_console_check(struct uart_port *uport)
 {
 	return FALSE;
 }
+static inline bool acpi_console_sbsa_32bit(void)
+{
+	return false;
+}
 #endif
 
 #endif	/*_LINUX_ACPI_H*/
-- 
2.7.1

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 0/5] ACPI: parse the SPCR table
  2016-02-15 18:05 ` Aleksey Makarov
@ 2016-02-16 19:11   ` Mark Salter
  -1 siblings, 0 replies; 86+ messages in thread
From: Mark Salter @ 2016-02-16 19:11 UTC (permalink / raw)
  To: Aleksey Makarov, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington

On Mon, 2016-02-15 at 21:05 +0300, Aleksey Makarov wrote:
> This patchset is based on the patchset by Leif Lindholm [1]
> 
> 'ARM Server Base Boot Requirements' [2] mentions SPCR (Serial Port
> Console Redirection Table) [3] as a mandatory ACPI table that
> specifies the configuration of serial console.
> 
> SPCR support is included in QEMU's ARM mach-virt since 2.4 release.
> 
> Introduce a new function acpi_console_check().  At the uart port
> registration, this function checks if the ACPI SPCR table specifies
> its argument of type struct uart_port to be a console
> and if so calls add_preferred_console().
> 
> Use SPCR to tell if SBSA serial driver should use 32-bit access to registers.
> 
> To be able to access SPCR table each time any console is registered
> change __init to __ref for early_acpi_os_unmap_memory().
> 
> The patchset should be applied to tty-next.

On Mustang, m400, and Seattle:

Tested-by: Mark Salter <msalter@redhat.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 0/5] ACPI: parse the SPCR table
@ 2016-02-16 19:11   ` Mark Salter
  0 siblings, 0 replies; 86+ messages in thread
From: Mark Salter @ 2016-02-16 19:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 2016-02-15 at 21:05 +0300, Aleksey Makarov wrote:
> This patchset is based on the patchset by Leif Lindholm [1]
> 
> 'ARM Server Base Boot Requirements' [2] mentions SPCR (Serial Port
> Console Redirection Table) [3] as a mandatory ACPI table that
> specifies the configuration of serial console.
> 
> SPCR support is included in QEMU's ARM mach-virt since 2.4 release.
> 
> Introduce a new function acpi_console_check().? At the uart port
> registration, this function checks if the ACPI SPCR table specifies
> its argument of type struct uart_port to be a console
> and if so calls add_preferred_console().
> 
> Use SPCR to tell if SBSA serial driver should use 32-bit access to registers.
> 
> To be able to access SPCR table each time any console is registered
> change __init to __ref for early_acpi_os_unmap_memory().
> 
> The patchset should be applied to tty-next.

On Mustang, m400, and Seattle:

Tested-by: Mark Salter <msalter@redhat.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 0/5] ACPI: parse the SPCR table
  2016-02-15 18:05 ` Aleksey Makarov
@ 2016-02-17  2:36   ` Christopher Covington
  -1 siblings, 0 replies; 86+ messages in thread
From: Christopher Covington @ 2016-02-17  2:36 UTC (permalink / raw)
  To: Aleksey Makarov, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone



On February 15, 2016 1:05:24 PM EST, Aleksey Makarov <aleksey.makarov@linaro.org> wrote:
>This patchset is based on the patchset by Leif Lindholm [1]
>
>'ARM Server Base Boot Requirements' [2] mentions SPCR (Serial Port
>Console Redirection Table) [3] as a mandatory ACPI table that
>specifies the configuration of serial console.
>
>SPCR support is included in QEMU's ARM mach-virt since 2.4 release.
>
>Introduce a new function acpi_console_check().  At the uart port
>registration, this function checks if the ACPI SPCR table specifies
>its argument of type struct uart_port to be a console
>and if so calls add_preferred_console().
>
>Use SPCR to tell if SBSA serial driver should use 32-bit access to
>registers.

On QDF2432:

Tested-by: Christopher Covington <cov@codeaurora.org>

-- 
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

Sent from my Snapdragon powered Android device with K-9 Mail. Please excuse my brevity.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 0/5] ACPI: parse the SPCR table
@ 2016-02-17  2:36   ` Christopher Covington
  0 siblings, 0 replies; 86+ messages in thread
From: Christopher Covington @ 2016-02-17  2:36 UTC (permalink / raw)
  To: linux-arm-kernel



On February 15, 2016 1:05:24 PM EST, Aleksey Makarov <aleksey.makarov@linaro.org> wrote:
>This patchset is based on the patchset by Leif Lindholm [1]
>
>'ARM Server Base Boot Requirements' [2] mentions SPCR (Serial Port
>Console Redirection Table) [3] as a mandatory ACPI table that
>specifies the configuration of serial console.
>
>SPCR support is included in QEMU's ARM mach-virt since 2.4 release.
>
>Introduce a new function acpi_console_check().  At the uart port
>registration, this function checks if the ACPI SPCR table specifies
>its argument of type struct uart_port to be a console
>and if so calls add_preferred_console().
>
>Use SPCR to tell if SBSA serial driver should use 32-bit access to
>registers.

On QDF2432:

Tested-by: Christopher Covington <cov@codeaurora.org>

-- 
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

Sent from my Snapdragon powered Android device with K-9 Mail. Please excuse my brevity.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-15 18:05   ` Aleksey Makarov
  (?)
@ 2016-02-17  2:44     ` Zheng, Lv
  -1 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-17  2:44 UTC (permalink / raw)
  To: Aleksey Makarov, linux-acpi
  Cc: Russell King, Graeme Gregory, Greg Kroah-Hartman,
	Rafael J . Wysocki, linux-kernel, Leif Lindholm,
	Christopher Covington, linux-serial, Al Stone, linux-arm-kernel,
	Len Brown

Hi,

> -----Original Message-----
> From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-
> owner@vger.kernel.org] On Behalf Of Aleksey Makarov
> Sent: Tuesday, February 16, 2016 2:05 AM
> To: linux-acpi@vger.kernel.org
> Cc: linux-serial@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; Aleksey Makarov <aleksey.makarov@linaro.org>;
> Russell King <linux@arm.linux.org.uk>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Rafael J . Wysocki <rjw@rjwysocki.net>; Leif
> Lindholm <leif.lindholm@linaro.org>; Graeme Gregory
> <graeme.gregory@linaro.org>; Al Stone <ahs3@redhat.com>; Christopher
> Covington <cov@codeaurora.org>; Len Brown <lenb@kernel.org>
> Subject: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> early_acpi_os_unmap_memory() is marked as __init because it calls
> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not set.
> 
> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> 
> We need this function to be non-__init because we need access to
> some tables at unpredictable time--it may be before or after
> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
> Redirection) table is needed each time a new console is registered.
> It can be quite early (console_initcall) or when a module is inserted.
> When this table accessed before acpi_gbl_permanent_mmap is set,
> the pointer should be unmapped.  This is exactly what this function
> does.
[Lv Zheng] 
Why don't you use another API instead of early_acpi_os_unmap_memory() in case you want to unmap things in any cases.
acpi_os_unmap_memory() should be the one to match this purpose.
It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
And in fact early_acpi_os_unmap_memory() should be removed.

Thanks and best regards
-Lv

> 
> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> ---
>  drivers/acpi/osl.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> index 67da6fb..8a552cd 100644
> --- a/drivers/acpi/osl.c
> +++ b/drivers/acpi/osl.c
> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> acpi_size size)
>  }
>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> 
> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
> +/*
> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> + */
> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
>  {
>  	if (!acpi_gbl_permanent_mmap)
>  		__acpi_unmap_table(virt, size);
> --
> 2.7.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-17  2:44     ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-17  2:44 UTC (permalink / raw)
  To: Aleksey Makarov, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi,

> -----Original Message-----
> From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-
> owner@vger.kernel.org] On Behalf Of Aleksey Makarov
> Sent: Tuesday, February 16, 2016 2:05 AM
> To: linux-acpi@vger.kernel.org
> Cc: linux-serial@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; Aleksey Makarov <aleksey.makarov@linaro.org>;
> Russell King <linux@arm.linux.org.uk>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Rafael J . Wysocki <rjw@rjwysocki.net>; Leif
> Lindholm <leif.lindholm@linaro.org>; Graeme Gregory
> <graeme.gregory@linaro.org>; Al Stone <ahs3@redhat.com>; Christopher
> Covington <cov@codeaurora.org>; Len Brown <lenb@kernel.org>
> Subject: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> early_acpi_os_unmap_memory() is marked as __init because it calls
> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not set.
> 
> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> 
> We need this function to be non-__init because we need access to
> some tables at unpredictable time--it may be before or after
> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
> Redirection) table is needed each time a new console is registered.
> It can be quite early (console_initcall) or when a module is inserted.
> When this table accessed before acpi_gbl_permanent_mmap is set,
> the pointer should be unmapped.  This is exactly what this function
> does.
[Lv Zheng] 
Why don't you use another API instead of early_acpi_os_unmap_memory() in case you want to unmap things in any cases.
acpi_os_unmap_memory() should be the one to match this purpose.
It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
And in fact early_acpi_os_unmap_memory() should be removed.

Thanks and best regards
-Lv

> 
> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> ---
>  drivers/acpi/osl.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> index 67da6fb..8a552cd 100644
> --- a/drivers/acpi/osl.c
> +++ b/drivers/acpi/osl.c
> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> acpi_size size)
>  }
>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> 
> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
> +/*
> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> + */
> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
>  {
>  	if (!acpi_gbl_permanent_mmap)
>  		__acpi_unmap_table(virt, size);
> --
> 2.7.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-17  2:44     ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-17  2:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> -----Original Message-----
> From: linux-acpi-owner at vger.kernel.org [mailto:linux-acpi-
> owner at vger.kernel.org] On Behalf Of Aleksey Makarov
> Sent: Tuesday, February 16, 2016 2:05 AM
> To: linux-acpi at vger.kernel.org
> Cc: linux-serial at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; Aleksey Makarov <aleksey.makarov@linaro.org>;
> Russell King <linux@arm.linux.org.uk>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Rafael J . Wysocki <rjw@rjwysocki.net>; Leif
> Lindholm <leif.lindholm@linaro.org>; Graeme Gregory
> <graeme.gregory@linaro.org>; Al Stone <ahs3@redhat.com>; Christopher
> Covington <cov@codeaurora.org>; Len Brown <lenb@kernel.org>
> Subject: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> early_acpi_os_unmap_memory() is marked as __init because it calls
> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not set.
> 
> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> 
> We need this function to be non-__init because we need access to
> some tables at unpredictable time--it may be before or after
> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
> Redirection) table is needed each time a new console is registered.
> It can be quite early (console_initcall) or when a module is inserted.
> When this table accessed before acpi_gbl_permanent_mmap is set,
> the pointer should be unmapped.  This is exactly what this function
> does.
[Lv Zheng] 
Why don't you use another API instead of early_acpi_os_unmap_memory() in case you want to unmap things in any cases.
acpi_os_unmap_memory() should be the one to match this purpose.
It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
And in fact early_acpi_os_unmap_memory() should be removed.

Thanks and best regards
-Lv

> 
> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> ---
>  drivers/acpi/osl.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> index 67da6fb..8a552cd 100644
> --- a/drivers/acpi/osl.c
> +++ b/drivers/acpi/osl.c
> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> acpi_size size)
>  }
>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> 
> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
> +/*
> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> + */
> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
>  {
>  	if (!acpi_gbl_permanent_mmap)
>  		__acpi_unmap_table(virt, size);
> --
> 2.7.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-17  2:44     ` Zheng, Lv
  (?)
@ 2016-02-17  2:51       ` Zheng, Lv
  -1 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-17  2:51 UTC (permalink / raw)
  To: Zheng, Lv, Aleksey Makarov, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi,

> From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-
> owner@vger.kernel.org] On Behalf Of Zheng, Lv
> Subject: RE: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi,
> 
> > -----Original Message-----
> > From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-
> > owner@vger.kernel.org] On Behalf Of Aleksey Makarov
> > Sent: Tuesday, February 16, 2016 2:05 AM
> > To: linux-acpi@vger.kernel.org
> > Cc: linux-serial@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm-
> > kernel@lists.infradead.org; Aleksey Makarov <aleksey.makarov@linaro.org>;
> > Russell King <linux@arm.linux.org.uk>; Greg Kroah-Hartman
> > <gregkh@linuxfoundation.org>; Rafael J . Wysocki <rjw@rjwysocki.net>; Leif
> > Lindholm <leif.lindholm@linaro.org>; Graeme Gregory
> > <graeme.gregory@linaro.org>; Al Stone <ahs3@redhat.com>; Christopher
> > Covington <cov@codeaurora.org>; Len Brown <lenb@kernel.org>
> > Subject: [PATCH v3 1/5] ACPI: change __init to __ref for
> > early_acpi_os_unmap_memory()
> >
> > early_acpi_os_unmap_memory() is marked as __init because it calls
> > __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not set.
> >
> > acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> > so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >
> > We need this function to be non-__init because we need access to
> > some tables at unpredictable time--it may be before or after
> > acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
> > Redirection) table is needed each time a new console is registered.
> > It can be quite early (console_initcall) or when a module is inserted.
> > When this table accessed before acpi_gbl_permanent_mmap is set,
> > the pointer should be unmapped.  This is exactly what this function
> > does.
> [Lv Zheng]
> Why don't you use another API instead of early_acpi_os_unmap_memory() in
> case you want to unmap things in any cases.
> acpi_os_unmap_memory() should be the one to match this purpose.
> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> And in fact early_acpi_os_unmap_memory() should be removed.
[Lv Zheng] 
One more thing is:
If you can't switch your driver to use acpi_os_unmap_memory() instead of early_acpi_os_unmap_memory(),
then it implies that your driver does have a defect.

There is an early bootup requirement in Linux.
Maps acquired during the early stage should be freed by the driver during the early stage.
And the driver should re-acquire the memory map after booting.

This is because, during early bootup stage, there are only limited slots available for drivers to map memory.
So by changing __init to __ref here, you probably will hide many such defects.
And solving issues in this way doesn't seem to be an improvement.

Thanks and best regards
-Lv

> 
> Thanks and best regards
> -Lv
> 
> >
> > Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> > ---
> >  drivers/acpi/osl.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> > index 67da6fb..8a552cd 100644
> > --- a/drivers/acpi/osl.c
> > +++ b/drivers/acpi/osl.c
> > @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> > acpi_size size)
> >  }
> >  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >
> > -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> size)
> > +/*
> > + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> > + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> > + */
> > +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> size)
> >  {
> >  	if (!acpi_gbl_permanent_mmap)
> >  		__acpi_unmap_table(virt, size);
> > --
> > 2.7.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-17  2:51       ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-17  2:51 UTC (permalink / raw)
  To: Zheng, Lv, Aleksey Makarov, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi,

> From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-
> owner@vger.kernel.org] On Behalf Of Zheng, Lv
> Subject: RE: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi,
> 
> > -----Original Message-----
> > From: linux-acpi-owner@vger.kernel.org [mailto:linux-acpi-
> > owner@vger.kernel.org] On Behalf Of Aleksey Makarov
> > Sent: Tuesday, February 16, 2016 2:05 AM
> > To: linux-acpi@vger.kernel.org
> > Cc: linux-serial@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm-
> > kernel@lists.infradead.org; Aleksey Makarov <aleksey.makarov@linaro.org>;
> > Russell King <linux@arm.linux.org.uk>; Greg Kroah-Hartman
> > <gregkh@linuxfoundation.org>; Rafael J . Wysocki <rjw@rjwysocki.net>; Leif
> > Lindholm <leif.lindholm@linaro.org>; Graeme Gregory
> > <graeme.gregory@linaro.org>; Al Stone <ahs3@redhat.com>; Christopher
> > Covington <cov@codeaurora.org>; Len Brown <lenb@kernel.org>
> > Subject: [PATCH v3 1/5] ACPI: change __init to __ref for
> > early_acpi_os_unmap_memory()
> >
> > early_acpi_os_unmap_memory() is marked as __init because it calls
> > __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not set.
> >
> > acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> > so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >
> > We need this function to be non-__init because we need access to
> > some tables at unpredictable time--it may be before or after
> > acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
> > Redirection) table is needed each time a new console is registered.
> > It can be quite early (console_initcall) or when a module is inserted.
> > When this table accessed before acpi_gbl_permanent_mmap is set,
> > the pointer should be unmapped.  This is exactly what this function
> > does.
> [Lv Zheng]
> Why don't you use another API instead of early_acpi_os_unmap_memory() in
> case you want to unmap things in any cases.
> acpi_os_unmap_memory() should be the one to match this purpose.
> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> And in fact early_acpi_os_unmap_memory() should be removed.
[Lv Zheng] 
One more thing is:
If you can't switch your driver to use acpi_os_unmap_memory() instead of early_acpi_os_unmap_memory(),
then it implies that your driver does have a defect.

There is an early bootup requirement in Linux.
Maps acquired during the early stage should be freed by the driver during the early stage.
And the driver should re-acquire the memory map after booting.

This is because, during early bootup stage, there are only limited slots available for drivers to map memory.
So by changing __init to __ref here, you probably will hide many such defects.
And solving issues in this way doesn't seem to be an improvement.

Thanks and best regards
-Lv

> 
> Thanks and best regards
> -Lv
> 
> >
> > Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> > ---
> >  drivers/acpi/osl.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> > index 67da6fb..8a552cd 100644
> > --- a/drivers/acpi/osl.c
> > +++ b/drivers/acpi/osl.c
> > @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> > acpi_size size)
> >  }
> >  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >
> > -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> size)
> > +/*
> > + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> > + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> > + */
> > +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> size)
> >  {
> >  	if (!acpi_gbl_permanent_mmap)
> >  		__acpi_unmap_table(virt, size);
> > --
> > 2.7.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-17  2:51       ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-17  2:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> From: linux-acpi-owner at vger.kernel.org [mailto:linux-acpi-
> owner at vger.kernel.org] On Behalf Of Zheng, Lv
> Subject: RE: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi,
> 
> > -----Original Message-----
> > From: linux-acpi-owner at vger.kernel.org [mailto:linux-acpi-
> > owner at vger.kernel.org] On Behalf Of Aleksey Makarov
> > Sent: Tuesday, February 16, 2016 2:05 AM
> > To: linux-acpi at vger.kernel.org
> > Cc: linux-serial at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> > kernel at lists.infradead.org; Aleksey Makarov <aleksey.makarov@linaro.org>;
> > Russell King <linux@arm.linux.org.uk>; Greg Kroah-Hartman
> > <gregkh@linuxfoundation.org>; Rafael J . Wysocki <rjw@rjwysocki.net>; Leif
> > Lindholm <leif.lindholm@linaro.org>; Graeme Gregory
> > <graeme.gregory@linaro.org>; Al Stone <ahs3@redhat.com>; Christopher
> > Covington <cov@codeaurora.org>; Len Brown <lenb@kernel.org>
> > Subject: [PATCH v3 1/5] ACPI: change __init to __ref for
> > early_acpi_os_unmap_memory()
> >
> > early_acpi_os_unmap_memory() is marked as __init because it calls
> > __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not set.
> >
> > acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> > so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >
> > We need this function to be non-__init because we need access to
> > some tables at unpredictable time--it may be before or after
> > acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
> > Redirection) table is needed each time a new console is registered.
> > It can be quite early (console_initcall) or when a module is inserted.
> > When this table accessed before acpi_gbl_permanent_mmap is set,
> > the pointer should be unmapped.  This is exactly what this function
> > does.
> [Lv Zheng]
> Why don't you use another API instead of early_acpi_os_unmap_memory() in
> case you want to unmap things in any cases.
> acpi_os_unmap_memory() should be the one to match this purpose.
> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> And in fact early_acpi_os_unmap_memory() should be removed.
[Lv Zheng] 
One more thing is:
If you can't switch your driver to use acpi_os_unmap_memory() instead of early_acpi_os_unmap_memory(),
then it implies that your driver does have a defect.

There is an early bootup requirement in Linux.
Maps acquired during the early stage should be freed by the driver during the early stage.
And the driver should re-acquire the memory map after booting.

This is because, during early bootup stage, there are only limited slots available for drivers to map memory.
So by changing __init to __ref here, you probably will hide many such defects.
And solving issues in this way doesn't seem to be an improvement.

Thanks and best regards
-Lv

> 
> Thanks and best regards
> -Lv
> 
> >
> > Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> > ---
> >  drivers/acpi/osl.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> > index 67da6fb..8a552cd 100644
> > --- a/drivers/acpi/osl.c
> > +++ b/drivers/acpi/osl.c
> > @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> > acpi_size size)
> >  }
> >  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >
> > -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> size)
> > +/*
> > + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> > + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> > + */
> > +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> size)
> >  {
> >  	if (!acpi_gbl_permanent_mmap)
> >  		__acpi_unmap_table(virt, size);
> > --
> > 2.7.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> > the body of a message to majordomo at vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-17  2:51       ` Zheng, Lv
  (?)
@ 2016-02-17 13:08         ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-17 13:08 UTC (permalink / raw)
  To: Zheng, Lv, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi Lv,

Thank you for review.

On 02/17/2016 05:51 AM, Zheng, Lv wrote:

[..]

>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not set.
>>>
>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>
>>> We need this function to be non-__init because we need access to
>>> some tables at unpredictable time--it may be before or after
>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>> Redirection) table is needed each time a new console is registered.
>>> It can be quite early (console_initcall) or when a module is inserted.
>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>> the pointer should be unmapped.  This is exactly what this function
>>> does.
>> [Lv Zheng]
>> Why don't you use another API instead of early_acpi_os_unmap_memory() in
>> case you want to unmap things in any cases.
>> acpi_os_unmap_memory() should be the one to match this purpose.
>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().

As far as I understand, there exist two steps in ACPI initialization:

1. Before acpi_gbl_permanent_mmap is set, tables received with acpi_get_table_with_size()
   are mapped by early_memremap().  If a subsystem gets such a pointer it should be unmapped.

2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped at all.

That exactly what early_acpi_os_unmap_memory() does--it checks acpi_gbl_permanent_mmap.
If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had been set,
it would have tried to free that pointer with an oops (actually, I checked that and got that oops).

So using acpi_os_unmap_memory() is not an option here, but early_acpi_os_unmap_memory()
match perfectly.

>> And in fact early_acpi_os_unmap_memory() should be removed.

I don't think so -- I have explained why.  It does different thing.
Probably it (and/or other functions in that api) should be renamed.

> [Lv Zheng] 
> One more thing is:
> If you can't switch your driver to use acpi_os_unmap_memory() instead of early_acpi_os_unmap_memory(),
> then it implies that your driver does have a defect.

I still don't understand what defect, sorry.

> There is an early bootup requirement in Linux.
> Maps acquired during the early stage should be freed by the driver during the early stage.
> And the driver should re-acquire the memory map after booting.

Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that that code can be
called *before* acpi_gbl_permanent_mmap is set (at early initialization of for example 8250 console)
or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that registers a console), 
We just can not tell if the received table pointer should or sould not be freed with early_memunmap()
(actually __acpi_unmap_table() or whatever) without checking acpi_gbl_permanent_mmap,
but that's all too low level.

Another option, as you describe, is to get this pointer early, don't free it untill
acpi_gbl_permanent_mmap is set, then free it (with early_acpi_os_unmap_memory(), that's 
ok because acpi_gbl_permanent_mmap is set in an init code), then get the persistent 
pointer to the table.  The problem with it is that we can not just watch acpi_gbl_permanent_mmap
to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is not good as it probably is 
an implementation detail (i. e. too lowlevel) of the ACPI code.
Or I probably miss what you are suggesting.

> This is because, during early bootup stage, there are only limited slots available for drivers to map memory.
> So by changing __init to __ref here, you probably will hide many such defects.

What defects?  This funcions checks acpi_gbl_permanent_mmap.
BTW, exactly the same thing is done in the beginning of acpi_os_unmap_memory() and than's ok, 
that function is __ref.

> And solving issues in this way doesn't seem to be an improvement.

Could you please tell me where I am wrong?  I still don't understand your point.

Thank you
Aleksey Makarov

> 
> Thanks and best regards
> -Lv
> 
>>
>> Thanks and best regards
>> -Lv
>>
>>>
>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>> ---
>>>  drivers/acpi/osl.c | 6 +++++-
>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>> index 67da6fb..8a552cd 100644
>>> --- a/drivers/acpi/osl.c
>>> +++ b/drivers/acpi/osl.c
>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>> acpi_size size)
>>>  }
>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>
>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>> size)
>>> +/*
>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>> + */
>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>> size)
>>>  {
>>>  	if (!acpi_gbl_permanent_mmap)
>>>  		__acpi_unmap_table(virt, size);
>>> --
>>> 2.7.1
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-17 13:08         ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-17 13:08 UTC (permalink / raw)
  To: Zheng, Lv, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi Lv,

Thank you for review.

On 02/17/2016 05:51 AM, Zheng, Lv wrote:

[..]

>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not set.
>>>
>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>
>>> We need this function to be non-__init because we need access to
>>> some tables at unpredictable time--it may be before or after
>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>> Redirection) table is needed each time a new console is registered.
>>> It can be quite early (console_initcall) or when a module is inserted.
>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>> the pointer should be unmapped.  This is exactly what this function
>>> does.
>> [Lv Zheng]
>> Why don't you use another API instead of early_acpi_os_unmap_memory() in
>> case you want to unmap things in any cases.
>> acpi_os_unmap_memory() should be the one to match this purpose.
>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().

As far as I understand, there exist two steps in ACPI initialization:

1. Before acpi_gbl_permanent_mmap is set, tables received with acpi_get_table_with_size()
   are mapped by early_memremap().  If a subsystem gets such a pointer it should be unmapped.

2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped at all.

That exactly what early_acpi_os_unmap_memory() does--it checks acpi_gbl_permanent_mmap.
If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had been set,
it would have tried to free that pointer with an oops (actually, I checked that and got that oops).

So using acpi_os_unmap_memory() is not an option here, but early_acpi_os_unmap_memory()
match perfectly.

>> And in fact early_acpi_os_unmap_memory() should be removed.

I don't think so -- I have explained why.  It does different thing.
Probably it (and/or other functions in that api) should be renamed.

> [Lv Zheng] 
> One more thing is:
> If you can't switch your driver to use acpi_os_unmap_memory() instead of early_acpi_os_unmap_memory(),
> then it implies that your driver does have a defect.

I still don't understand what defect, sorry.

> There is an early bootup requirement in Linux.
> Maps acquired during the early stage should be freed by the driver during the early stage.
> And the driver should re-acquire the memory map after booting.

Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that that code can be
called *before* acpi_gbl_permanent_mmap is set (at early initialization of for example 8250 console)
or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that registers a console), 
We just can not tell if the received table pointer should or sould not be freed with early_memunmap()
(actually __acpi_unmap_table() or whatever) without checking acpi_gbl_permanent_mmap,
but that's all too low level.

Another option, as you describe, is to get this pointer early, don't free it untill
acpi_gbl_permanent_mmap is set, then free it (with early_acpi_os_unmap_memory(), that's 
ok because acpi_gbl_permanent_mmap is set in an init code), then get the persistent 
pointer to the table.  The problem with it is that we can not just watch acpi_gbl_permanent_mmap
to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is not good as it probably is 
an implementation detail (i. e. too lowlevel) of the ACPI code.
Or I probably miss what you are suggesting.

> This is because, during early bootup stage, there are only limited slots available for drivers to map memory.
> So by changing __init to __ref here, you probably will hide many such defects.

What defects?  This funcions checks acpi_gbl_permanent_mmap.
BTW, exactly the same thing is done in the beginning of acpi_os_unmap_memory() and than's ok, 
that function is __ref.

> And solving issues in this way doesn't seem to be an improvement.

Could you please tell me where I am wrong?  I still don't understand your point.

Thank you
Aleksey Makarov

> 
> Thanks and best regards
> -Lv
> 
>>
>> Thanks and best regards
>> -Lv
>>
>>>
>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>> ---
>>>  drivers/acpi/osl.c | 6 +++++-
>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>> index 67da6fb..8a552cd 100644
>>> --- a/drivers/acpi/osl.c
>>> +++ b/drivers/acpi/osl.c
>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>> acpi_size size)
>>>  }
>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>
>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>> size)
>>> +/*
>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>> + */
>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>> size)
>>>  {
>>>  	if (!acpi_gbl_permanent_mmap)
>>>  		__acpi_unmap_table(virt, size);
>>> --
>>> 2.7.1
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-17 13:08         ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-17 13:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lv,

Thank you for review.

On 02/17/2016 05:51 AM, Zheng, Lv wrote:

[..]

>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not set.
>>>
>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>
>>> We need this function to be non-__init because we need access to
>>> some tables at unpredictable time--it may be before or after
>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>> Redirection) table is needed each time a new console is registered.
>>> It can be quite early (console_initcall) or when a module is inserted.
>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>> the pointer should be unmapped.  This is exactly what this function
>>> does.
>> [Lv Zheng]
>> Why don't you use another API instead of early_acpi_os_unmap_memory() in
>> case you want to unmap things in any cases.
>> acpi_os_unmap_memory() should be the one to match this purpose.
>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().

As far as I understand, there exist two steps in ACPI initialization:

1. Before acpi_gbl_permanent_mmap is set, tables received with acpi_get_table_with_size()
   are mapped by early_memremap().  If a subsystem gets such a pointer it should be unmapped.

2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped at all.

That exactly what early_acpi_os_unmap_memory() does--it checks acpi_gbl_permanent_mmap.
If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had been set,
it would have tried to free that pointer with an oops (actually, I checked that and got that oops).

So using acpi_os_unmap_memory() is not an option here, but early_acpi_os_unmap_memory()
match perfectly.

>> And in fact early_acpi_os_unmap_memory() should be removed.

I don't think so -- I have explained why.  It does different thing.
Probably it (and/or other functions in that api) should be renamed.

> [Lv Zheng] 
> One more thing is:
> If you can't switch your driver to use acpi_os_unmap_memory() instead of early_acpi_os_unmap_memory(),
> then it implies that your driver does have a defect.

I still don't understand what defect, sorry.

> There is an early bootup requirement in Linux.
> Maps acquired during the early stage should be freed by the driver during the early stage.
> And the driver should re-acquire the memory map after booting.

Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that that code can be
called *before* acpi_gbl_permanent_mmap is set (at early initialization of for example 8250 console)
or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that registers a console), 
We just can not tell if the received table pointer should or sould not be freed with early_memunmap()
(actually __acpi_unmap_table() or whatever) without checking acpi_gbl_permanent_mmap,
but that's all too low level.

Another option, as you describe, is to get this pointer early, don't free it untill
acpi_gbl_permanent_mmap is set, then free it (with early_acpi_os_unmap_memory(), that's 
ok because acpi_gbl_permanent_mmap is set in an init code), then get the persistent 
pointer to the table.  The problem with it is that we can not just watch acpi_gbl_permanent_mmap
to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is not good as it probably is 
an implementation detail (i. e. too lowlevel) of the ACPI code.
Or I probably miss what you are suggesting.

> This is because, during early bootup stage, there are only limited slots available for drivers to map memory.
> So by changing __init to __ref here, you probably will hide many such defects.

What defects?  This funcions checks acpi_gbl_permanent_mmap.
BTW, exactly the same thing is done in the beginning of acpi_os_unmap_memory() and than's ok, 
that function is __ref.

> And solving issues in this way doesn't seem to be an improvement.

Could you please tell me where I am wrong?  I still don't understand your point.

Thank you
Aleksey Makarov

> 
> Thanks and best regards
> -Lv
> 
>>
>> Thanks and best regards
>> -Lv
>>
>>>
>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>> ---
>>>  drivers/acpi/osl.c | 6 +++++-
>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>> index 67da6fb..8a552cd 100644
>>> --- a/drivers/acpi/osl.c
>>> +++ b/drivers/acpi/osl.c
>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>> acpi_size size)
>>>  }
>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>
>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>> size)
>>> +/*
>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>> + */
>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>> size)
>>>  {
>>>  	if (!acpi_gbl_permanent_mmap)
>>>  		__acpi_unmap_table(virt, size);
>>> --
>>> 2.7.1
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>> the body of a message to majordomo at vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-17 13:08         ` Aleksey Makarov
  (?)
@ 2016-02-18  3:36           ` Zheng, Lv
  -1 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-18  3:36 UTC (permalink / raw)
  To: Aleksey Makarov, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi,

> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi Lv,
> 
> Thank you for review.
> 
> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> 
> [..]
> 
> >>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
> set.
> >>>
> >>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>
> >>> We need this function to be non-__init because we need access to
> >>> some tables at unpredictable time--it may be before or after
> >>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
> >>> Redirection) table is needed each time a new console is registered.
> >>> It can be quite early (console_initcall) or when a module is inserted.
> >>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>> the pointer should be unmapped.  This is exactly what this function
> >>> does.
> >> [Lv Zheng]
> >> Why don't you use another API instead of early_acpi_os_unmap_memory()
> in
> >> case you want to unmap things in any cases.
> >> acpi_os_unmap_memory() should be the one to match this purpose.
> >> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> 
> As far as I understand, there exist two steps in ACPI initialization:
> 
> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> acpi_get_table_with_size()
>    are mapped by early_memremap().  If a subsystem gets such a pointer it
> should be unmapped.
> 
> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
> at all.
> 
[Lv Zheng] 
This statement is wrong, this should be:
As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
In fact, we have a series to introduce acpi_put_table() to achieve this.
So your argument is wrong from very first point.

> That exactly what early_acpi_os_unmap_memory() does--it checks
> acpi_gbl_permanent_mmap.
> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
> been set,
> it would have tried to free that pointer with an oops (actually, I checked that
> and got that oops).
> 
> So using acpi_os_unmap_memory() is not an option here, but
> early_acpi_os_unmap_memory()
> match perfectly.
[Lv Zheng] 
I don't think so.
For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
But for the data tables, OSPMs should use them in this way:
1. map the table
2. parse the table and convert it to OS specific structures
3. unmap the table
This helps to shrink virtual memory address space usages.

So from this point of view, all data tables should be unmapped right after being parsed.
Why do you need the map to be persistent in the kernel address space?
You can always map a small table, but what if the table size is very big?

> 
> >> And in fact early_acpi_os_unmap_memory() should be removed.
> 
> I don't think so -- I have explained why.  It does different thing.
> Probably it (and/or other functions in that api) should be renamed.
> 
[Lv Zheng] 
Just let me ask one more question.
eary_acpi_os_unmap_memory() is not used inside of ACPICA.
How ACPICA can work with just acpi_os_unmap_memory()?
You can check drivers/acpi/tbxxx.c.
Especially: acpi_tb_release_temp_table() and the code invoking it.

> > [Lv Zheng]
> > One more thing is:
> > If you can't switch your driver to use acpi_os_unmap_memory() instead of
> early_acpi_os_unmap_memory(),
> > then it implies that your driver does have a defect.
> 
> I still don't understand what defect, sorry.
[Lv Zheng] 
If you can't ensure this sequence for using the data tables:
1. map the table
2. parse the table and convert it to OS specific structure
3. unmap the table
It implies there is a bug in the driver or a bug in the ACPI subsystem core.

> 
> > There is an early bootup requirement in Linux.
> > Maps acquired during the early stage should be freed by the driver during the
> early stage.
> > And the driver should re-acquire the memory map after booting.
> 
> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
> that code can be
> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
> example 8250 console)
> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
> registers a console),
> We just can not tell if the received table pointer should or sould not be freed
> with early_memunmap()
> (actually __acpi_unmap_table() or whatever) without checking
> acpi_gbl_permanent_mmap,
> but that's all too low level.
[Lv Zheng] 
The driver should make sure that:
Map/unmap is paired during early stage.
For late stage, it should be another pair of map/unmap.

> 
> Another option, as you describe, is to get this pointer early, don't free it
[Lv Zheng] 
I mean you should free it early.

> untill acpi_gbl_permanent_mmap is set, then free it (with
> early_acpi_os_unmap_memory(), that's
> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
> persistent
> pointer to the table.  The problem with it is that we can not just watch
> acpi_gbl_permanent_mmap
> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
> not good as it probably is
> an implementation detail (i. e. too lowlevel) of the ACPI code.
> Or I probably miss what you are suggesting.
> 
[Lv Zheng] 
I mean, you should:
During early stage:
acpi_os_map_memory()
Parse the table.
acpi_os_unmap_memory().

> > This is because, during early bootup stage, there are only limited slots
> available for drivers to map memory.
> > So by changing __init to __ref here, you probably will hide many such defects.
> 
> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> BTW, exactly the same thing is done in the beginning of
> acpi_os_unmap_memory() and than's ok,
> that function is __ref.
> 
> > And solving issues in this way doesn't seem to be an improvement.
> 
> Could you please tell me where I am wrong?  I still don't understand your point.
[Lv Zheng] 
But anyway, the defect should be in ACPI subsystem core.
The cause should be the API itself - acpi_get_table().

So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.

Thanks and best regards
-Lv

> 
> Thank you
> Aleksey Makarov
> 
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >> Thanks and best regards
> >> -Lv
> >>
> >>>
> >>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>> ---
> >>>  drivers/acpi/osl.c | 6 +++++-
> >>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>> index 67da6fb..8a552cd 100644
> >>> --- a/drivers/acpi/osl.c
> >>> +++ b/drivers/acpi/osl.c
> >>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> >>> acpi_size size)
> >>>  }
> >>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>
> >>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> >> size)
> >>> +/*
> >>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>> + */
> >>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> >> size)
> >>>  {
> >>>  	if (!acpi_gbl_permanent_mmap)
> >>>  		__acpi_unmap_table(virt, size);
> >>> --
> >>> 2.7.1
> >>>
> >>> --
> >>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>> the body of a message to majordomo@vger.kernel.org
> >>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >> the body of a message to majordomo@vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-18  3:36           ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-18  3:36 UTC (permalink / raw)
  To: Aleksey Makarov, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi,

> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi Lv,
> 
> Thank you for review.
> 
> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> 
> [..]
> 
> >>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
> set.
> >>>
> >>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>
> >>> We need this function to be non-__init because we need access to
> >>> some tables at unpredictable time--it may be before or after
> >>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
> >>> Redirection) table is needed each time a new console is registered.
> >>> It can be quite early (console_initcall) or when a module is inserted.
> >>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>> the pointer should be unmapped.  This is exactly what this function
> >>> does.
> >> [Lv Zheng]
> >> Why don't you use another API instead of early_acpi_os_unmap_memory()
> in
> >> case you want to unmap things in any cases.
> >> acpi_os_unmap_memory() should be the one to match this purpose.
> >> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> 
> As far as I understand, there exist two steps in ACPI initialization:
> 
> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> acpi_get_table_with_size()
>    are mapped by early_memremap().  If a subsystem gets such a pointer it
> should be unmapped.
> 
> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
> at all.
> 
[Lv Zheng] 
This statement is wrong, this should be:
As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
In fact, we have a series to introduce acpi_put_table() to achieve this.
So your argument is wrong from very first point.

> That exactly what early_acpi_os_unmap_memory() does--it checks
> acpi_gbl_permanent_mmap.
> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
> been set,
> it would have tried to free that pointer with an oops (actually, I checked that
> and got that oops).
> 
> So using acpi_os_unmap_memory() is not an option here, but
> early_acpi_os_unmap_memory()
> match perfectly.
[Lv Zheng] 
I don't think so.
For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
But for the data tables, OSPMs should use them in this way:
1. map the table
2. parse the table and convert it to OS specific structures
3. unmap the table
This helps to shrink virtual memory address space usages.

So from this point of view, all data tables should be unmapped right after being parsed.
Why do you need the map to be persistent in the kernel address space?
You can always map a small table, but what if the table size is very big?

> 
> >> And in fact early_acpi_os_unmap_memory() should be removed.
> 
> I don't think so -- I have explained why.  It does different thing.
> Probably it (and/or other functions in that api) should be renamed.
> 
[Lv Zheng] 
Just let me ask one more question.
eary_acpi_os_unmap_memory() is not used inside of ACPICA.
How ACPICA can work with just acpi_os_unmap_memory()?
You can check drivers/acpi/tbxxx.c.
Especially: acpi_tb_release_temp_table() and the code invoking it.

> > [Lv Zheng]
> > One more thing is:
> > If you can't switch your driver to use acpi_os_unmap_memory() instead of
> early_acpi_os_unmap_memory(),
> > then it implies that your driver does have a defect.
> 
> I still don't understand what defect, sorry.
[Lv Zheng] 
If you can't ensure this sequence for using the data tables:
1. map the table
2. parse the table and convert it to OS specific structure
3. unmap the table
It implies there is a bug in the driver or a bug in the ACPI subsystem core.

> 
> > There is an early bootup requirement in Linux.
> > Maps acquired during the early stage should be freed by the driver during the
> early stage.
> > And the driver should re-acquire the memory map after booting.
> 
> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
> that code can be
> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
> example 8250 console)
> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
> registers a console),
> We just can not tell if the received table pointer should or sould not be freed
> with early_memunmap()
> (actually __acpi_unmap_table() or whatever) without checking
> acpi_gbl_permanent_mmap,
> but that's all too low level.
[Lv Zheng] 
The driver should make sure that:
Map/unmap is paired during early stage.
For late stage, it should be another pair of map/unmap.

> 
> Another option, as you describe, is to get this pointer early, don't free it
[Lv Zheng] 
I mean you should free it early.

> untill acpi_gbl_permanent_mmap is set, then free it (with
> early_acpi_os_unmap_memory(), that's
> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
> persistent
> pointer to the table.  The problem with it is that we can not just watch
> acpi_gbl_permanent_mmap
> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
> not good as it probably is
> an implementation detail (i. e. too lowlevel) of the ACPI code.
> Or I probably miss what you are suggesting.
> 
[Lv Zheng] 
I mean, you should:
During early stage:
acpi_os_map_memory()
Parse the table.
acpi_os_unmap_memory().

> > This is because, during early bootup stage, there are only limited slots
> available for drivers to map memory.
> > So by changing __init to __ref here, you probably will hide many such defects.
> 
> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> BTW, exactly the same thing is done in the beginning of
> acpi_os_unmap_memory() and than's ok,
> that function is __ref.
> 
> > And solving issues in this way doesn't seem to be an improvement.
> 
> Could you please tell me where I am wrong?  I still don't understand your point.
[Lv Zheng] 
But anyway, the defect should be in ACPI subsystem core.
The cause should be the API itself - acpi_get_table().

So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.

Thanks and best regards
-Lv

> 
> Thank you
> Aleksey Makarov
> 
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >> Thanks and best regards
> >> -Lv
> >>
> >>>
> >>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>> ---
> >>>  drivers/acpi/osl.c | 6 +++++-
> >>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>> index 67da6fb..8a552cd 100644
> >>> --- a/drivers/acpi/osl.c
> >>> +++ b/drivers/acpi/osl.c
> >>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> >>> acpi_size size)
> >>>  }
> >>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>
> >>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> >> size)
> >>> +/*
> >>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>> + */
> >>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> >> size)
> >>>  {
> >>>  	if (!acpi_gbl_permanent_mmap)
> >>>  		__acpi_unmap_table(virt, size);
> >>> --
> >>> 2.7.1
> >>>
> >>> --
> >>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>> the body of a message to majordomo@vger.kernel.org
> >>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >> the body of a message to majordomo@vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-18  3:36           ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-18  3:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi Lv,
> 
> Thank you for review.
> 
> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> 
> [..]
> 
> >>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
> set.
> >>>
> >>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>
> >>> We need this function to be non-__init because we need access to
> >>> some tables at unpredictable time--it may be before or after
> >>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
> >>> Redirection) table is needed each time a new console is registered.
> >>> It can be quite early (console_initcall) or when a module is inserted.
> >>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>> the pointer should be unmapped.  This is exactly what this function
> >>> does.
> >> [Lv Zheng]
> >> Why don't you use another API instead of early_acpi_os_unmap_memory()
> in
> >> case you want to unmap things in any cases.
> >> acpi_os_unmap_memory() should be the one to match this purpose.
> >> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> 
> As far as I understand, there exist two steps in ACPI initialization:
> 
> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> acpi_get_table_with_size()
>    are mapped by early_memremap().  If a subsystem gets such a pointer it
> should be unmapped.
> 
> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
> at all.
> 
[Lv Zheng] 
This statement is wrong, this should be:
As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
In fact, we have a series to introduce acpi_put_table() to achieve this.
So your argument is wrong from very first point.

> That exactly what early_acpi_os_unmap_memory() does--it checks
> acpi_gbl_permanent_mmap.
> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
> been set,
> it would have tried to free that pointer with an oops (actually, I checked that
> and got that oops).
> 
> So using acpi_os_unmap_memory() is not an option here, but
> early_acpi_os_unmap_memory()
> match perfectly.
[Lv Zheng] 
I don't think so.
For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
But for the data tables, OSPMs should use them in this way:
1. map the table
2. parse the table and convert it to OS specific structures
3. unmap the table
This helps to shrink virtual memory address space usages.

So from this point of view, all data tables should be unmapped right after being parsed.
Why do you need the map to be persistent in the kernel address space?
You can always map a small table, but what if the table size is very big?

> 
> >> And in fact early_acpi_os_unmap_memory() should be removed.
> 
> I don't think so -- I have explained why.  It does different thing.
> Probably it (and/or other functions in that api) should be renamed.
> 
[Lv Zheng] 
Just let me ask one more question.
eary_acpi_os_unmap_memory() is not used inside of ACPICA.
How ACPICA can work with just acpi_os_unmap_memory()?
You can check drivers/acpi/tbxxx.c.
Especially: acpi_tb_release_temp_table() and the code invoking it.

> > [Lv Zheng]
> > One more thing is:
> > If you can't switch your driver to use acpi_os_unmap_memory() instead of
> early_acpi_os_unmap_memory(),
> > then it implies that your driver does have a defect.
> 
> I still don't understand what defect, sorry.
[Lv Zheng] 
If you can't ensure this sequence for using the data tables:
1. map the table
2. parse the table and convert it to OS specific structure
3. unmap the table
It implies there is a bug in the driver or a bug in the ACPI subsystem core.

> 
> > There is an early bootup requirement in Linux.
> > Maps acquired during the early stage should be freed by the driver during the
> early stage.
> > And the driver should re-acquire the memory map after booting.
> 
> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
> that code can be
> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
> example 8250 console)
> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
> registers a console),
> We just can not tell if the received table pointer should or sould not be freed
> with early_memunmap()
> (actually __acpi_unmap_table() or whatever) without checking
> acpi_gbl_permanent_mmap,
> but that's all too low level.
[Lv Zheng] 
The driver should make sure that:
Map/unmap is paired during early stage.
For late stage, it should be another pair of map/unmap.

> 
> Another option, as you describe, is to get this pointer early, don't free it
[Lv Zheng] 
I mean you should free it early.

> untill acpi_gbl_permanent_mmap is set, then free it (with
> early_acpi_os_unmap_memory(), that's
> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
> persistent
> pointer to the table.  The problem with it is that we can not just watch
> acpi_gbl_permanent_mmap
> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
> not good as it probably is
> an implementation detail (i. e. too lowlevel) of the ACPI code.
> Or I probably miss what you are suggesting.
> 
[Lv Zheng] 
I mean, you should:
During early stage:
acpi_os_map_memory()
Parse the table.
acpi_os_unmap_memory().

> > This is because, during early bootup stage, there are only limited slots
> available for drivers to map memory.
> > So by changing __init to __ref here, you probably will hide many such defects.
> 
> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> BTW, exactly the same thing is done in the beginning of
> acpi_os_unmap_memory() and than's ok,
> that function is __ref.
> 
> > And solving issues in this way doesn't seem to be an improvement.
> 
> Could you please tell me where I am wrong?  I still don't understand your point.
[Lv Zheng] 
But anyway, the defect should be in ACPI subsystem core.
The cause should be the API itself - acpi_get_table().

So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.

Thanks and best regards
-Lv

> 
> Thank you
> Aleksey Makarov
> 
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >> Thanks and best regards
> >> -Lv
> >>
> >>>
> >>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>> ---
> >>>  drivers/acpi/osl.c | 6 +++++-
> >>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>> index 67da6fb..8a552cd 100644
> >>> --- a/drivers/acpi/osl.c
> >>> +++ b/drivers/acpi/osl.c
> >>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> >>> acpi_size size)
> >>>  }
> >>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>
> >>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> >> size)
> >>> +/*
> >>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>> + */
> >>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
> >> size)
> >>>  {
> >>>  	if (!acpi_gbl_permanent_mmap)
> >>>  		__acpi_unmap_table(virt, size);
> >>> --
> >>> 2.7.1
> >>>
> >>> --
> >>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>> the body of a message to majordomo at vger.kernel.org
> >>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >> the body of a message to majordomo at vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 0/5] ACPI: parse the SPCR table
  2016-02-15 18:05 ` Aleksey Makarov
@ 2016-02-18 21:15   ` Jeremy Linton
  -1 siblings, 0 replies; 86+ messages in thread
From: Jeremy Linton @ 2016-02-18 21:15 UTC (permalink / raw)
  To: Aleksey Makarov, linux-acpi
  Cc: Russell King, Graeme Gregory, Greg Kroah-Hartman,
	Rafael J . Wysocki, linux-kernel, Leif Lindholm,
	Christopher Covington, linux-serial, Al Stone, linux-arm-kernel

On 02/15/2016 12:05 PM, Aleksey Makarov wrote:
> This patchset is based on the patchset by Leif Lindholm [1]
>
> 'ARM Server Base Boot Requirements' [2] mentions SPCR (Serial Port
> Console Redirection Table) [3] as a mandatory ACPI table that
> specifies the configuration of serial console.
>
> SPCR support is included in QEMU's ARM mach-virt since 2.4 release.
>
> Introduce a new function acpi_console_check().  At the uart port
> registration, this function checks if the ACPI SPCR table specifies
> its argument of type struct uart_port to be a console
> and if so calls add_preferred_console().
>
> Use SPCR to tell if SBSA serial driver should use 32-bit access to registers.
>
> To be able to access SPCR table each time any console is registered
> change __init to __ref for early_acpi_os_unmap_memory().
>
> The patchset should be applied to tty-next.
(trimming)

This works on the JunoR2 with a new enough firmware to have the SPCR table.

Tested-by: Jeremy Linton <jeremy.linton@arm.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 0/5] ACPI: parse the SPCR table
@ 2016-02-18 21:15   ` Jeremy Linton
  0 siblings, 0 replies; 86+ messages in thread
From: Jeremy Linton @ 2016-02-18 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/15/2016 12:05 PM, Aleksey Makarov wrote:
> This patchset is based on the patchset by Leif Lindholm [1]
>
> 'ARM Server Base Boot Requirements' [2] mentions SPCR (Serial Port
> Console Redirection Table) [3] as a mandatory ACPI table that
> specifies the configuration of serial console.
>
> SPCR support is included in QEMU's ARM mach-virt since 2.4 release.
>
> Introduce a new function acpi_console_check().  At the uart port
> registration, this function checks if the ACPI SPCR table specifies
> its argument of type struct uart_port to be a console
> and if so calls add_preferred_console().
>
> Use SPCR to tell if SBSA serial driver should use 32-bit access to registers.
>
> To be able to access SPCR table each time any console is registered
> change __init to __ref for early_acpi_os_unmap_memory().
>
> The patchset should be applied to tty-next.
(trimming)

This works on the JunoR2 with a new enough firmware to have the SPCR table.

Tested-by: Jeremy Linton <jeremy.linton@arm.com>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-18  3:36           ` Zheng, Lv
  (?)
@ 2016-02-18 22:03             ` Peter Hurley
  -1 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-18 22:03 UTC (permalink / raw)
  To: Zheng, Lv, Aleksey Makarov, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> Hi,
> 
>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> Hi Lv,
>>
>> Thank you for review.
>>
>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>
>> [..]
>>
>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>> set.
>>>>>
>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>
>>>>> We need this function to be non-__init because we need access to
>>>>> some tables at unpredictable time--it may be before or after
>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>> Redirection) table is needed each time a new console is registered.
>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>> does.
>>>> [Lv Zheng]
>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>> in
>>>> case you want to unmap things in any cases.
>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>
>> As far as I understand, there exist two steps in ACPI initialization:
>>
>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>> acpi_get_table_with_size()
>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>> should be unmapped.
>>
>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>> at all.
>>
> [Lv Zheng] 
> This statement is wrong, this should be:
> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
> In fact, we have a series to introduce acpi_put_table() to achieve this.
> So your argument is wrong from very first point.
> 
>> That exactly what early_acpi_os_unmap_memory() does--it checks
>> acpi_gbl_permanent_mmap.
>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>> been set,
>> it would have tried to free that pointer with an oops (actually, I checked that
>> and got that oops).
>>
>> So using acpi_os_unmap_memory() is not an option here, but
>> early_acpi_os_unmap_memory()
>> match perfectly.
> [Lv Zheng] 
> I don't think so.
> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
> But for the data tables, OSPMs should use them in this way:
> 1. map the table
> 2. parse the table and convert it to OS specific structures
> 3. unmap the table
> This helps to shrink virtual memory address space usages.
> 
> So from this point of view, all data tables should be unmapped right after being parsed.
> Why do you need the map to be persistent in the kernel address space?
> You can always map a small table, but what if the table size is very big?
> 
>>
>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>
>> I don't think so -- I have explained why.  It does different thing.
>> Probably it (and/or other functions in that api) should be renamed.
>>
> [Lv Zheng] 
> Just let me ask one more question.
> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> How ACPICA can work with just acpi_os_unmap_memory()?
> You can check drivers/acpi/tbxxx.c.
> Especially: acpi_tb_release_temp_table() and the code invoking it.
> 
>>> [Lv Zheng]
>>> One more thing is:
>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>> early_acpi_os_unmap_memory(),
>>> then it implies that your driver does have a defect.
>>
>> I still don't understand what defect, sorry.
> [Lv Zheng] 
> If you can't ensure this sequence for using the data tables:
> 1. map the table
> 2. parse the table and convert it to OS specific structure
> 3. unmap the table
> It implies there is a bug in the driver or a bug in the ACPI subsystem core.

Exactly.

The central problem here is the way Aleksey is trying to hookup a console.

What should be happening in this series is:
1. early map SPCR
2. parse the SPCR table
3. call add_preferred_console() to add the SPCR console to the console table
4. unmap SPCR

This trivial and unobtrusive method would already have a 8250 console
running via SPCR. I've already pointed this out in previous reviews.

Further, the above method *will be required anyway* for the DBG2 table to
start an earlycon, which I've already pointed out in previous reviews.

Then to enable amba-pl011 console via ACPI, add a console match() method
similar to the 8250 console match() method, univ8250_console_match().

FWIW, PCI earlycon + console support was already submitted once before but
never picked up by GregKH. I think I'll just grab that and re-submit so
you would know what to emit for console options in the add_preferred_console().


Regards,
Peter Hurley


>>> There is an early bootup requirement in Linux.
>>> Maps acquired during the early stage should be freed by the driver during the
>> early stage.
>>> And the driver should re-acquire the memory map after booting.
>>
>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>> that code can be
>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>> example 8250 console)
>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>> registers a console),
>> We just can not tell if the received table pointer should or sould not be freed
>> with early_memunmap()
>> (actually __acpi_unmap_table() or whatever) without checking
>> acpi_gbl_permanent_mmap,
>> but that's all too low level.
> [Lv Zheng] 
> The driver should make sure that:
> Map/unmap is paired during early stage.
> For late stage, it should be another pair of map/unmap.
> 
>>
>> Another option, as you describe, is to get this pointer early, don't free it
> [Lv Zheng] 
> I mean you should free it early.
> 
>> untill acpi_gbl_permanent_mmap is set, then free it (with
>> early_acpi_os_unmap_memory(), that's
>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>> persistent
>> pointer to the table.  The problem with it is that we can not just watch
>> acpi_gbl_permanent_mmap
>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>> not good as it probably is
>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>> Or I probably miss what you are suggesting.
>>
> [Lv Zheng] 
> I mean, you should:
> During early stage:
> acpi_os_map_memory()
> Parse the table.
> acpi_os_unmap_memory().
> 
>>> This is because, during early bootup stage, there are only limited slots
>> available for drivers to map memory.
>>> So by changing __init to __ref here, you probably will hide many such defects.
>>
>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>> BTW, exactly the same thing is done in the beginning of
>> acpi_os_unmap_memory() and than's ok,
>> that function is __ref.
>>
>>> And solving issues in this way doesn't seem to be an improvement.
>>
>> Could you please tell me where I am wrong?  I still don't understand your point.
> [Lv Zheng] 
> But anyway, the defect should be in ACPI subsystem core.
> The cause should be the API itself - acpi_get_table().
> 
> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
> 
> Thanks and best regards
> -Lv
> 
>>
>> Thank you
>> Aleksey Makarov
>>
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>> Thanks and best regards
>>>> -Lv
>>>>
>>>>>
>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>> ---
>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>> index 67da6fb..8a552cd 100644
>>>>> --- a/drivers/acpi/osl.c
>>>>> +++ b/drivers/acpi/osl.c
>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>> acpi_size size)
>>>>>  }
>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>
>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>> size)
>>>>> +/*
>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>> + */
>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>> size)
>>>>>  {
>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>  		__acpi_unmap_table(virt, size);
>>>>> --
>>>>> 2.7.1
>>>>>
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-18 22:03             ` Peter Hurley
  0 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-18 22:03 UTC (permalink / raw)
  To: Zheng, Lv, Aleksey Makarov, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> Hi,
> 
>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> Hi Lv,
>>
>> Thank you for review.
>>
>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>
>> [..]
>>
>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>> set.
>>>>>
>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>
>>>>> We need this function to be non-__init because we need access to
>>>>> some tables at unpredictable time--it may be before or after
>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>> Redirection) table is needed each time a new console is registered.
>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>> does.
>>>> [Lv Zheng]
>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>> in
>>>> case you want to unmap things in any cases.
>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>
>> As far as I understand, there exist two steps in ACPI initialization:
>>
>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>> acpi_get_table_with_size()
>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>> should be unmapped.
>>
>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>> at all.
>>
> [Lv Zheng] 
> This statement is wrong, this should be:
> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
> In fact, we have a series to introduce acpi_put_table() to achieve this.
> So your argument is wrong from very first point.
> 
>> That exactly what early_acpi_os_unmap_memory() does--it checks
>> acpi_gbl_permanent_mmap.
>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>> been set,
>> it would have tried to free that pointer with an oops (actually, I checked that
>> and got that oops).
>>
>> So using acpi_os_unmap_memory() is not an option here, but
>> early_acpi_os_unmap_memory()
>> match perfectly.
> [Lv Zheng] 
> I don't think so.
> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
> But for the data tables, OSPMs should use them in this way:
> 1. map the table
> 2. parse the table and convert it to OS specific structures
> 3. unmap the table
> This helps to shrink virtual memory address space usages.
> 
> So from this point of view, all data tables should be unmapped right after being parsed.
> Why do you need the map to be persistent in the kernel address space?
> You can always map a small table, but what if the table size is very big?
> 
>>
>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>
>> I don't think so -- I have explained why.  It does different thing.
>> Probably it (and/or other functions in that api) should be renamed.
>>
> [Lv Zheng] 
> Just let me ask one more question.
> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> How ACPICA can work with just acpi_os_unmap_memory()?
> You can check drivers/acpi/tbxxx.c.
> Especially: acpi_tb_release_temp_table() and the code invoking it.
> 
>>> [Lv Zheng]
>>> One more thing is:
>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>> early_acpi_os_unmap_memory(),
>>> then it implies that your driver does have a defect.
>>
>> I still don't understand what defect, sorry.
> [Lv Zheng] 
> If you can't ensure this sequence for using the data tables:
> 1. map the table
> 2. parse the table and convert it to OS specific structure
> 3. unmap the table
> It implies there is a bug in the driver or a bug in the ACPI subsystem core.

Exactly.

The central problem here is the way Aleksey is trying to hookup a console.

What should be happening in this series is:
1. early map SPCR
2. parse the SPCR table
3. call add_preferred_console() to add the SPCR console to the console table
4. unmap SPCR

This trivial and unobtrusive method would already have a 8250 console
running via SPCR. I've already pointed this out in previous reviews.

Further, the above method *will be required anyway* for the DBG2 table to
start an earlycon, which I've already pointed out in previous reviews.

Then to enable amba-pl011 console via ACPI, add a console match() method
similar to the 8250 console match() method, univ8250_console_match().

FWIW, PCI earlycon + console support was already submitted once before but
never picked up by GregKH. I think I'll just grab that and re-submit so
you would know what to emit for console options in the add_preferred_console().


Regards,
Peter Hurley


>>> There is an early bootup requirement in Linux.
>>> Maps acquired during the early stage should be freed by the driver during the
>> early stage.
>>> And the driver should re-acquire the memory map after booting.
>>
>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>> that code can be
>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>> example 8250 console)
>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>> registers a console),
>> We just can not tell if the received table pointer should or sould not be freed
>> with early_memunmap()
>> (actually __acpi_unmap_table() or whatever) without checking
>> acpi_gbl_permanent_mmap,
>> but that's all too low level.
> [Lv Zheng] 
> The driver should make sure that:
> Map/unmap is paired during early stage.
> For late stage, it should be another pair of map/unmap.
> 
>>
>> Another option, as you describe, is to get this pointer early, don't free it
> [Lv Zheng] 
> I mean you should free it early.
> 
>> untill acpi_gbl_permanent_mmap is set, then free it (with
>> early_acpi_os_unmap_memory(), that's
>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>> persistent
>> pointer to the table.  The problem with it is that we can not just watch
>> acpi_gbl_permanent_mmap
>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>> not good as it probably is
>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>> Or I probably miss what you are suggesting.
>>
> [Lv Zheng] 
> I mean, you should:
> During early stage:
> acpi_os_map_memory()
> Parse the table.
> acpi_os_unmap_memory().
> 
>>> This is because, during early bootup stage, there are only limited slots
>> available for drivers to map memory.
>>> So by changing __init to __ref here, you probably will hide many such defects.
>>
>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>> BTW, exactly the same thing is done in the beginning of
>> acpi_os_unmap_memory() and than's ok,
>> that function is __ref.
>>
>>> And solving issues in this way doesn't seem to be an improvement.
>>
>> Could you please tell me where I am wrong?  I still don't understand your point.
> [Lv Zheng] 
> But anyway, the defect should be in ACPI subsystem core.
> The cause should be the API itself - acpi_get_table().
> 
> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
> 
> Thanks and best regards
> -Lv
> 
>>
>> Thank you
>> Aleksey Makarov
>>
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>> Thanks and best regards
>>>> -Lv
>>>>
>>>>>
>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>> ---
>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>> index 67da6fb..8a552cd 100644
>>>>> --- a/drivers/acpi/osl.c
>>>>> +++ b/drivers/acpi/osl.c
>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>> acpi_size size)
>>>>>  }
>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>
>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>> size)
>>>>> +/*
>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>> + */
>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>> size)
>>>>>  {
>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>  		__acpi_unmap_table(virt, size);
>>>>> --
>>>>> 2.7.1
>>>>>
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-18 22:03             ` Peter Hurley
  0 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-18 22:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> Hi,
> 
>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> Hi Lv,
>>
>> Thank you for review.
>>
>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>
>> [..]
>>
>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>> set.
>>>>>
>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>
>>>>> We need this function to be non-__init because we need access to
>>>>> some tables at unpredictable time--it may be before or after
>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>> Redirection) table is needed each time a new console is registered.
>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>> does.
>>>> [Lv Zheng]
>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>> in
>>>> case you want to unmap things in any cases.
>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>
>> As far as I understand, there exist two steps in ACPI initialization:
>>
>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>> acpi_get_table_with_size()
>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>> should be unmapped.
>>
>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>> at all.
>>
> [Lv Zheng] 
> This statement is wrong, this should be:
> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
> In fact, we have a series to introduce acpi_put_table() to achieve this.
> So your argument is wrong from very first point.
> 
>> That exactly what early_acpi_os_unmap_memory() does--it checks
>> acpi_gbl_permanent_mmap.
>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>> been set,
>> it would have tried to free that pointer with an oops (actually, I checked that
>> and got that oops).
>>
>> So using acpi_os_unmap_memory() is not an option here, but
>> early_acpi_os_unmap_memory()
>> match perfectly.
> [Lv Zheng] 
> I don't think so.
> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
> But for the data tables, OSPMs should use them in this way:
> 1. map the table
> 2. parse the table and convert it to OS specific structures
> 3. unmap the table
> This helps to shrink virtual memory address space usages.
> 
> So from this point of view, all data tables should be unmapped right after being parsed.
> Why do you need the map to be persistent in the kernel address space?
> You can always map a small table, but what if the table size is very big?
> 
>>
>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>
>> I don't think so -- I have explained why.  It does different thing.
>> Probably it (and/or other functions in that api) should be renamed.
>>
> [Lv Zheng] 
> Just let me ask one more question.
> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> How ACPICA can work with just acpi_os_unmap_memory()?
> You can check drivers/acpi/tbxxx.c.
> Especially: acpi_tb_release_temp_table() and the code invoking it.
> 
>>> [Lv Zheng]
>>> One more thing is:
>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>> early_acpi_os_unmap_memory(),
>>> then it implies that your driver does have a defect.
>>
>> I still don't understand what defect, sorry.
> [Lv Zheng] 
> If you can't ensure this sequence for using the data tables:
> 1. map the table
> 2. parse the table and convert it to OS specific structure
> 3. unmap the table
> It implies there is a bug in the driver or a bug in the ACPI subsystem core.

Exactly.

The central problem here is the way Aleksey is trying to hookup a console.

What should be happening in this series is:
1. early map SPCR
2. parse the SPCR table
3. call add_preferred_console() to add the SPCR console to the console table
4. unmap SPCR

This trivial and unobtrusive method would already have a 8250 console
running via SPCR. I've already pointed this out in previous reviews.

Further, the above method *will be required anyway* for the DBG2 table to
start an earlycon, which I've already pointed out in previous reviews.

Then to enable amba-pl011 console via ACPI, add a console match() method
similar to the 8250 console match() method, univ8250_console_match().

FWIW, PCI earlycon + console support was already submitted once before but
never picked up by GregKH. I think I'll just grab that and re-submit so
you would know what to emit for console options in the add_preferred_console().


Regards,
Peter Hurley


>>> There is an early bootup requirement in Linux.
>>> Maps acquired during the early stage should be freed by the driver during the
>> early stage.
>>> And the driver should re-acquire the memory map after booting.
>>
>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>> that code can be
>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>> example 8250 console)
>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>> registers a console),
>> We just can not tell if the received table pointer should or sould not be freed
>> with early_memunmap()
>> (actually __acpi_unmap_table() or whatever) without checking
>> acpi_gbl_permanent_mmap,
>> but that's all too low level.
> [Lv Zheng] 
> The driver should make sure that:
> Map/unmap is paired during early stage.
> For late stage, it should be another pair of map/unmap.
> 
>>
>> Another option, as you describe, is to get this pointer early, don't free it
> [Lv Zheng] 
> I mean you should free it early.
> 
>> untill acpi_gbl_permanent_mmap is set, then free it (with
>> early_acpi_os_unmap_memory(), that's
>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>> persistent
>> pointer to the table.  The problem with it is that we can not just watch
>> acpi_gbl_permanent_mmap
>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>> not good as it probably is
>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>> Or I probably miss what you are suggesting.
>>
> [Lv Zheng] 
> I mean, you should:
> During early stage:
> acpi_os_map_memory()
> Parse the table.
> acpi_os_unmap_memory().
> 
>>> This is because, during early bootup stage, there are only limited slots
>> available for drivers to map memory.
>>> So by changing __init to __ref here, you probably will hide many such defects.
>>
>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>> BTW, exactly the same thing is done in the beginning of
>> acpi_os_unmap_memory() and than's ok,
>> that function is __ref.
>>
>>> And solving issues in this way doesn't seem to be an improvement.
>>
>> Could you please tell me where I am wrong?  I still don't understand your point.
> [Lv Zheng] 
> But anyway, the defect should be in ACPI subsystem core.
> The cause should be the API itself - acpi_get_table().
> 
> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
> 
> Thanks and best regards
> -Lv
> 
>>
>> Thank you
>> Aleksey Makarov
>>
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>> Thanks and best regards
>>>> -Lv
>>>>
>>>>>
>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>> ---
>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>> index 67da6fb..8a552cd 100644
>>>>> --- a/drivers/acpi/osl.c
>>>>> +++ b/drivers/acpi/osl.c
>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>> acpi_size size)
>>>>>  }
>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>
>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>> size)
>>>>> +/*
>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>> + */
>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>> size)
>>>>>  {
>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>  		__acpi_unmap_table(virt, size);
>>>>> --
>>>>> 2.7.1
>>>>>
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>> the body of a message to majordomo at vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>> the body of a message to majordomo at vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
  2016-02-15 18:05   ` Aleksey Makarov
@ 2016-02-18 22:19     ` Peter Hurley
  -1 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-18 22:19 UTC (permalink / raw)
  To: Aleksey Makarov, linux-acpi
  Cc: Russell King, Graeme Gregory, Greg Kroah-Hartman,
	Rafael J . Wysocki, linux-kernel, Leif Lindholm,
	Christopher Covington, linux-serial, Jiri Slaby, Al Stone,
	linux-arm-kernel, Len Brown

On 02/15/2016 10:05 AM, Aleksey Makarov wrote:
> 'ARM Server Base Boot Requiremets' [1] mentions SPCR (Serial Port
> Console Redirection Table) [2] as a mandatory ACPI table that
> specifies the configuration of serial console.
> 
> Parse this table and check if any registered console match the
> description.  If it does, enable that console.
> 
> Introduce a new function acpi_console_check().  At the uart port
> registration, this function checks if the ACPI SPCR table specifies
> its argument of type struct uart_port to be a console
> and if so calls add_preferred_console().
> 
> [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
> [2] http://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx
> 
> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> ---
>  drivers/acpi/Kconfig             |  3 ++
>  drivers/acpi/Makefile            |  1 +
>  drivers/acpi/spcr.c              | 97 ++++++++++++++++++++++++++++++++++++++++
>  drivers/tty/serial/serial_core.c | 14 +++++-
>  include/linux/acpi.h             | 10 +++++
>  5 files changed, 123 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/acpi/spcr.c
> 
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 65fb483..5611eb6 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -77,6 +77,9 @@ config ACPI_DEBUGGER_USER
>  
>  endif
>  
> +config ACPI_SPCR_TABLE
> +	bool
> +
>  config ACPI_SLEEP
>  	bool
>  	depends on SUSPEND || HIBERNATION
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 346101c..708b143 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -81,6 +81,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
>  obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
> +obj-$(CONFIG_ACPI_SPCR_TABLE)	+= spcr.o
>  obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
>  
>  # processor has its own "processor." module_param namespace
> diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
> new file mode 100644
> index 0000000..a1eca91
> --- /dev/null
> +++ b/drivers/acpi/spcr.c
> @@ -0,0 +1,97 @@
> +/*
> + * Copyright (c) 2012, Intel Corporation
> + * Copyright (c) 2015, Red Hat, Inc.
> + * Copyright (c) 2015, 2016 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#define pr_fmt(fmt) "ACPI: SPCR: " fmt
> +
> +#include <linux/acpi.h>
> +#include <linux/console.h>
> +#include <linux/kernel.h>
> +#include <linux/serial_core.h>
> +
> +static int acpi_table_parse_spcr(int (*handler)(struct acpi_table_spcr *table,
> +						void *data), void *data)
> +{
> +	struct acpi_table_spcr *table = NULL;
> +	acpi_size table_size;
> +	acpi_status status;
> +	int err;
> +
> +	status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0,
> +					  (struct acpi_table_header **)&table,
> +					  &table_size);
> +
> +	if (ACPI_FAILURE(status))
> +		return -ENODEV;
> +
> +	err = handler(table, data);
> +
> +	early_acpi_os_unmap_memory(table, table_size);
> +
> +	return err;
> +}
> +
> +static int spcr_table_handler_check(struct acpi_table_spcr *table, void *data)
> +{
> +	struct uart_port *uport = data;
> +	char *options;
> +
> +	if (table->header.revision < 2)
> +		return -EOPNOTSUPP;
> +
> +	switch (table->baud_rate) {
> +	case 3:
> +		options = "9600";
> +		break;
> +	case 4:
> +		options = "19200";
> +		break;
> +	case 6:
> +		options = "57600";
> +		break;
> +	case 7:
> +		options = "115200";
> +		break;
> +	default:
> +		options = "";
> +		break;
> +	}
> +
> +	if ((table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY &&
> +	     table->serial_port.address == (u64)uport->mapbase) ||
> +	    (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_IO &&
> +	     table->serial_port.address == (u64)uport->iobase)) {
> +		pr_info("adding preferred console [%s%d]\n", uport->cons->name,
> +			uport->line);
> +		add_preferred_console(uport->cons->name, uport->line, options);
> +		return 1;
> +
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * acpi_console_check - Check if uart matches the console specified by SPCR.
> + *
> + * @uport:	uart port to check
> + *
> + * This function checks if the ACPI SPCR table specifies @uport to be a console
> + * and if so calls add_preferred_console()
> + *
> + * Return: a non-error value if the console matches.
> + */
> +bool acpi_console_check(struct uart_port *uport)
> +{
> +	if (acpi_disabled || console_set_on_cmdline)
> +		return false;
> +
> +	return acpi_table_parse_spcr(spcr_table_handler_check, uport) > 0;
> +}
> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> index a126a60..459ab54 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -34,6 +34,7 @@
>  #include <linux/serial_core.h>
>  #include <linux/delay.h>
>  #include <linux/mutex.h>
> +#include <linux/acpi.h>
>  
>  #include <asm/irq.h>
>  #include <asm/uaccess.h>
> @@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>  		spin_lock_init(&uport->lock);
>  		lockdep_set_class(&uport->lock, &port_lock_key);
>  	}
> -	if (uport->cons && uport->dev)
> -		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
> +
> +	/*
> +	 * Support both open FW and ACPI access to console definitions.
> +	 * Both of_console_check() and acpi_console_check() will call
> +	 * add_preferred_console() if a console definition is found.
> +	 */
> +	if (uport->cons && uport->dev) {
> +		if (!acpi_console_check(uport))
> +			of_console_check(uport->dev->of_node, uport->cons->name,
> +					 uport->line);

of_console_check() is not a good model for enabling a console.
It's a hack with several shortcomings (and bugs) that is tolerated here
because of its broad applicability to a wide range of platforms and drivers.

I specifically added console matching to enable exactly this kind of
console-selection-via-firmware. Please use that facility.

Regards,
Peter Hurley


> +	}
>  
>  	uart_configure_port(drv, state, uport);
>  
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 06ed7e5..ea0c297 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
>  #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
>  #endif
>  
> +struct uart_port;
> +#ifdef CONFIG_ACPI_SPCR_TABLE
> +bool acpi_console_check(struct uart_port *uport);
> +#else
> +static inline bool acpi_console_check(struct uart_port *uport)
> +{
> +	return FALSE;
> +}
> +#endif
> +
>  #endif	/*_LINUX_ACPI_H*/
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
@ 2016-02-18 22:19     ` Peter Hurley
  0 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-18 22:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/15/2016 10:05 AM, Aleksey Makarov wrote:
> 'ARM Server Base Boot Requiremets' [1] mentions SPCR (Serial Port
> Console Redirection Table) [2] as a mandatory ACPI table that
> specifies the configuration of serial console.
> 
> Parse this table and check if any registered console match the
> description.  If it does, enable that console.
> 
> Introduce a new function acpi_console_check().  At the uart port
> registration, this function checks if the ACPI SPCR table specifies
> its argument of type struct uart_port to be a console
> and if so calls add_preferred_console().
> 
> [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
> [2] http://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx
> 
> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> ---
>  drivers/acpi/Kconfig             |  3 ++
>  drivers/acpi/Makefile            |  1 +
>  drivers/acpi/spcr.c              | 97 ++++++++++++++++++++++++++++++++++++++++
>  drivers/tty/serial/serial_core.c | 14 +++++-
>  include/linux/acpi.h             | 10 +++++
>  5 files changed, 123 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/acpi/spcr.c
> 
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 65fb483..5611eb6 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -77,6 +77,9 @@ config ACPI_DEBUGGER_USER
>  
>  endif
>  
> +config ACPI_SPCR_TABLE
> +	bool
> +
>  config ACPI_SLEEP
>  	bool
>  	depends on SUSPEND || HIBERNATION
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 346101c..708b143 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -81,6 +81,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
>  obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
> +obj-$(CONFIG_ACPI_SPCR_TABLE)	+= spcr.o
>  obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
>  
>  # processor has its own "processor." module_param namespace
> diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
> new file mode 100644
> index 0000000..a1eca91
> --- /dev/null
> +++ b/drivers/acpi/spcr.c
> @@ -0,0 +1,97 @@
> +/*
> + * Copyright (c) 2012, Intel Corporation
> + * Copyright (c) 2015, Red Hat, Inc.
> + * Copyright (c) 2015, 2016 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#define pr_fmt(fmt) "ACPI: SPCR: " fmt
> +
> +#include <linux/acpi.h>
> +#include <linux/console.h>
> +#include <linux/kernel.h>
> +#include <linux/serial_core.h>
> +
> +static int acpi_table_parse_spcr(int (*handler)(struct acpi_table_spcr *table,
> +						void *data), void *data)
> +{
> +	struct acpi_table_spcr *table = NULL;
> +	acpi_size table_size;
> +	acpi_status status;
> +	int err;
> +
> +	status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0,
> +					  (struct acpi_table_header **)&table,
> +					  &table_size);
> +
> +	if (ACPI_FAILURE(status))
> +		return -ENODEV;
> +
> +	err = handler(table, data);
> +
> +	early_acpi_os_unmap_memory(table, table_size);
> +
> +	return err;
> +}
> +
> +static int spcr_table_handler_check(struct acpi_table_spcr *table, void *data)
> +{
> +	struct uart_port *uport = data;
> +	char *options;
> +
> +	if (table->header.revision < 2)
> +		return -EOPNOTSUPP;
> +
> +	switch (table->baud_rate) {
> +	case 3:
> +		options = "9600";
> +		break;
> +	case 4:
> +		options = "19200";
> +		break;
> +	case 6:
> +		options = "57600";
> +		break;
> +	case 7:
> +		options = "115200";
> +		break;
> +	default:
> +		options = "";
> +		break;
> +	}
> +
> +	if ((table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY &&
> +	     table->serial_port.address == (u64)uport->mapbase) ||
> +	    (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_IO &&
> +	     table->serial_port.address == (u64)uport->iobase)) {
> +		pr_info("adding preferred console [%s%d]\n", uport->cons->name,
> +			uport->line);
> +		add_preferred_console(uport->cons->name, uport->line, options);
> +		return 1;
> +
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * acpi_console_check - Check if uart matches the console specified by SPCR.
> + *
> + * @uport:	uart port to check
> + *
> + * This function checks if the ACPI SPCR table specifies @uport to be a console
> + * and if so calls add_preferred_console()
> + *
> + * Return: a non-error value if the console matches.
> + */
> +bool acpi_console_check(struct uart_port *uport)
> +{
> +	if (acpi_disabled || console_set_on_cmdline)
> +		return false;
> +
> +	return acpi_table_parse_spcr(spcr_table_handler_check, uport) > 0;
> +}
> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> index a126a60..459ab54 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -34,6 +34,7 @@
>  #include <linux/serial_core.h>
>  #include <linux/delay.h>
>  #include <linux/mutex.h>
> +#include <linux/acpi.h>
>  
>  #include <asm/irq.h>
>  #include <asm/uaccess.h>
> @@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>  		spin_lock_init(&uport->lock);
>  		lockdep_set_class(&uport->lock, &port_lock_key);
>  	}
> -	if (uport->cons && uport->dev)
> -		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
> +
> +	/*
> +	 * Support both open FW and ACPI access to console definitions.
> +	 * Both of_console_check() and acpi_console_check() will call
> +	 * add_preferred_console() if a console definition is found.
> +	 */
> +	if (uport->cons && uport->dev) {
> +		if (!acpi_console_check(uport))
> +			of_console_check(uport->dev->of_node, uport->cons->name,
> +					 uport->line);

of_console_check() is not a good model for enabling a console.
It's a hack with several shortcomings (and bugs) that is tolerated here
because of its broad applicability to a wide range of platforms and drivers.

I specifically added console matching to enable exactly this kind of
console-selection-via-firmware. Please use that facility.

Regards,
Peter Hurley


> +	}
>  
>  	uart_configure_port(drv, state, uport);
>  
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 06ed7e5..ea0c297 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
>  #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
>  #endif
>  
> +struct uart_port;
> +#ifdef CONFIG_ACPI_SPCR_TABLE
> +bool acpi_console_check(struct uart_port *uport);
> +#else
> +static inline bool acpi_console_check(struct uart_port *uport)
> +{
> +	return FALSE;
> +}
> +#endif
> +
>  #endif	/*_LINUX_ACPI_H*/
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-18 22:03             ` Peter Hurley
  (?)
@ 2016-02-19  2:58               ` Zheng, Lv
  -1 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-19  2:58 UTC (permalink / raw)
  To: Peter Hurley, Aleksey Makarov, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi,

> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> Hi Lv,
> >>
> >> Thank you for review.
> >>
> >> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>
> >> [..]
> >>
> >>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
> >> set.
> >>>>>
> >>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>
> >>>>> We need this function to be non-__init because we need access to
> >>>>> some tables at unpredictable time--it may be before or after
> >>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> Console
> >>>>> Redirection) table is needed each time a new console is registered.
> >>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>> does.
> >>>> [Lv Zheng]
> >>>> Why don't you use another API instead of
> early_acpi_os_unmap_memory()
> >> in
> >>>> case you want to unmap things in any cases.
> >>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>
> >> As far as I understand, there exist two steps in ACPI initialization:
> >>
> >> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >> acpi_get_table_with_size()
> >>    are mapped by early_memremap().  If a subsystem gets such a pointer it
> >> should be unmapped.
> >>
> >> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> unmapped
> >> at all.
> >>
> > [Lv Zheng]
> > This statement is wrong, this should be:
> > As long as there is a __reference__ to the mapped table, the pointer should
> not be unmapped.
> > In fact, we have a series to introduce acpi_put_table() to achieve this.
> > So your argument is wrong from very first point.
> >
> >> That exactly what early_acpi_os_unmap_memory() does--it checks
> >> acpi_gbl_permanent_mmap.
> >> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
> had
> >> been set,
> >> it would have tried to free that pointer with an oops (actually, I checked that
> >> and got that oops).
> >>
> >> So using acpi_os_unmap_memory() is not an option here, but
> >> early_acpi_os_unmap_memory()
> >> match perfectly.
> > [Lv Zheng]
> > I don't think so.
> > For definition block tables, we know for sure there will always be references,
> until "Unload" opcode is invoked by the AML interpreter.
> > But for the data tables, OSPMs should use them in this way:
> > 1. map the table
> > 2. parse the table and convert it to OS specific structures
> > 3. unmap the table
> > This helps to shrink virtual memory address space usages.
> >
> > So from this point of view, all data tables should be unmapped right after
> being parsed.
> > Why do you need the map to be persistent in the kernel address space?
> > You can always map a small table, but what if the table size is very big?
> >
> >>
> >>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>
> >> I don't think so -- I have explained why.  It does different thing.
> >> Probably it (and/or other functions in that api) should be renamed.
> >>
> > [Lv Zheng]
> > Just let me ask one more question.
> > eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> > How ACPICA can work with just acpi_os_unmap_memory()?
> > You can check drivers/acpi/tbxxx.c.
> > Especially: acpi_tb_release_temp_table() and the code invoking it.
> >
> >>> [Lv Zheng]
> >>> One more thing is:
> >>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
> >> early_acpi_os_unmap_memory(),
> >>> then it implies that your driver does have a defect.
> >>
> >> I still don't understand what defect, sorry.
> > [Lv Zheng]
> > If you can't ensure this sequence for using the data tables:
> > 1. map the table
> > 2. parse the table and convert it to OS specific structure
> > 3. unmap the table
> > It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> 
> Exactly.
[Lv Zheng] 
So it looks to me:
Changing __init to __ref here is entirely not acceptable.
This API should stay being invoked during early stage.
Otherwise, it may leave us untrackable code that maps tables during early stage and leaks maps to the late stage.
If Linux contains such kind of code, I'm afraid, it will become impossible to introduce acpi_put_table() to clean up the mappings.
Because when acpi_put_table() is called during the late stage to free a map acquired during the early stage, it then obviously will end up with panic.

Thanks and best regards
-Lv

> The central problem here is the way Aleksey is trying to hookup a console.
> 
> What should be happening in this series is:
> 1. early map SPCR
> 2. parse the SPCR table
> 3. call add_preferred_console() to add the SPCR console to the console table
> 4. unmap SPCR
> 
> This trivial and unobtrusive method would already have a 8250 console
> running via SPCR. I've already pointed this out in previous reviews.
> 
> Further, the above method *will be required anyway* for the DBG2 table to
> start an earlycon, which I've already pointed out in previous reviews.
> 
> Then to enable amba-pl011 console via ACPI, add a console match() method
> similar to the 8250 console match() method, univ8250_console_match().
> 
> FWIW, PCI earlycon + console support was already submitted once before but
> never picked up by GregKH. I think I'll just grab that and re-submit so
> you would know what to emit for console options in the
> add_preferred_console().
> 
> 
> Regards,
> Peter Hurley
> 
> 
> >>> There is an early bootup requirement in Linux.
> >>> Maps acquired during the early stage should be freed by the driver during
> the
> >> early stage.
> >>> And the driver should re-acquire the memory map after booting.
> >>
> >> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
> >> that code can be
> >> called *before* acpi_gbl_permanent_mmap is set (at early initialization of
> for
> >> example 8250 console)
> >> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
> >> registers a console),
> >> We just can not tell if the received table pointer should or sould not be freed
> >> with early_memunmap()
> >> (actually __acpi_unmap_table() or whatever) without checking
> >> acpi_gbl_permanent_mmap,
> >> but that's all too low level.
> > [Lv Zheng]
> > The driver should make sure that:
> > Map/unmap is paired during early stage.
> > For late stage, it should be another pair of map/unmap.
> >
> >>
> >> Another option, as you describe, is to get this pointer early, don't free it
> > [Lv Zheng]
> > I mean you should free it early.
> >
> >> untill acpi_gbl_permanent_mmap is set, then free it (with
> >> early_acpi_os_unmap_memory(), that's
> >> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
> >> persistent
> >> pointer to the table.  The problem with it is that we can not just watch
> >> acpi_gbl_permanent_mmap
> >> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap
> is
> >> not good as it probably is
> >> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >> Or I probably miss what you are suggesting.
> >>
> > [Lv Zheng]
> > I mean, you should:
> > During early stage:
> > acpi_os_map_memory()
> > Parse the table.
> > acpi_os_unmap_memory().
> >
> >>> This is because, during early bootup stage, there are only limited slots
> >> available for drivers to map memory.
> >>> So by changing __init to __ref here, you probably will hide many such
> defects.
> >>
> >> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >> BTW, exactly the same thing is done in the beginning of
> >> acpi_os_unmap_memory() and than's ok,
> >> that function is __ref.
> >>
> >>> And solving issues in this way doesn't seem to be an improvement.
> >>
> >> Could you please tell me where I am wrong?  I still don't understand your
> point.
> > [Lv Zheng]
> > But anyway, the defect should be in ACPI subsystem core.
> > The cause should be the API itself - acpi_get_table().
> >
> > So I agree you can use early_acpi_os_unmap_memory() during the period the
> root causes are not cleaned up.
> > But the bottom line is: the driver need to ensure that
> early_acpi_os_unmap_memory() is always invoked.
> > As long as you can ensure this, I don't have objections for deploying
> early_acpi_os_unmap_memory()  for now.
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >> Thank you
> >> Aleksey Makarov
> >>
> >>>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>>
> >>>> Thanks and best regards
> >>>> -Lv
> >>>>
> >>>>>
> >>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>> ---
> >>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>
> >>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>> index 67da6fb..8a552cd 100644
> >>>>> --- a/drivers/acpi/osl.c
> >>>>> +++ b/drivers/acpi/osl.c
> >>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> >>>>> acpi_size size)
> >>>>>  }
> >>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>
> >>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> acpi_size
> >>>> size)
> >>>>> +/*
> >>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>> + */
> >>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> acpi_size
> >>>> size)
> >>>>>  {
> >>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>  		__acpi_unmap_table(virt, size);
> >>>>> --
> >>>>> 2.7.1
> >>>>>
> >>>>> --
> >>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>> the body of a message to majordomo@vger.kernel.org
> >>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >>>> --
> >>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>> the body of a message to majordomo@vger.kernel.org
> >>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-19  2:58               ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-19  2:58 UTC (permalink / raw)
  To: Peter Hurley, Aleksey Makarov, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi,

> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> Hi Lv,
> >>
> >> Thank you for review.
> >>
> >> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>
> >> [..]
> >>
> >>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
> >> set.
> >>>>>
> >>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>
> >>>>> We need this function to be non-__init because we need access to
> >>>>> some tables at unpredictable time--it may be before or after
> >>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> Console
> >>>>> Redirection) table is needed each time a new console is registered.
> >>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>> does.
> >>>> [Lv Zheng]
> >>>> Why don't you use another API instead of
> early_acpi_os_unmap_memory()
> >> in
> >>>> case you want to unmap things in any cases.
> >>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>
> >> As far as I understand, there exist two steps in ACPI initialization:
> >>
> >> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >> acpi_get_table_with_size()
> >>    are mapped by early_memremap().  If a subsystem gets such a pointer it
> >> should be unmapped.
> >>
> >> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> unmapped
> >> at all.
> >>
> > [Lv Zheng]
> > This statement is wrong, this should be:
> > As long as there is a __reference__ to the mapped table, the pointer should
> not be unmapped.
> > In fact, we have a series to introduce acpi_put_table() to achieve this.
> > So your argument is wrong from very first point.
> >
> >> That exactly what early_acpi_os_unmap_memory() does--it checks
> >> acpi_gbl_permanent_mmap.
> >> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
> had
> >> been set,
> >> it would have tried to free that pointer with an oops (actually, I checked that
> >> and got that oops).
> >>
> >> So using acpi_os_unmap_memory() is not an option here, but
> >> early_acpi_os_unmap_memory()
> >> match perfectly.
> > [Lv Zheng]
> > I don't think so.
> > For definition block tables, we know for sure there will always be references,
> until "Unload" opcode is invoked by the AML interpreter.
> > But for the data tables, OSPMs should use them in this way:
> > 1. map the table
> > 2. parse the table and convert it to OS specific structures
> > 3. unmap the table
> > This helps to shrink virtual memory address space usages.
> >
> > So from this point of view, all data tables should be unmapped right after
> being parsed.
> > Why do you need the map to be persistent in the kernel address space?
> > You can always map a small table, but what if the table size is very big?
> >
> >>
> >>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>
> >> I don't think so -- I have explained why.  It does different thing.
> >> Probably it (and/or other functions in that api) should be renamed.
> >>
> > [Lv Zheng]
> > Just let me ask one more question.
> > eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> > How ACPICA can work with just acpi_os_unmap_memory()?
> > You can check drivers/acpi/tbxxx.c.
> > Especially: acpi_tb_release_temp_table() and the code invoking it.
> >
> >>> [Lv Zheng]
> >>> One more thing is:
> >>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
> >> early_acpi_os_unmap_memory(),
> >>> then it implies that your driver does have a defect.
> >>
> >> I still don't understand what defect, sorry.
> > [Lv Zheng]
> > If you can't ensure this sequence for using the data tables:
> > 1. map the table
> > 2. parse the table and convert it to OS specific structure
> > 3. unmap the table
> > It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> 
> Exactly.
[Lv Zheng] 
So it looks to me:
Changing __init to __ref here is entirely not acceptable.
This API should stay being invoked during early stage.
Otherwise, it may leave us untrackable code that maps tables during early stage and leaks maps to the late stage.
If Linux contains such kind of code, I'm afraid, it will become impossible to introduce acpi_put_table() to clean up the mappings.
Because when acpi_put_table() is called during the late stage to free a map acquired during the early stage, it then obviously will end up with panic.

Thanks and best regards
-Lv

> The central problem here is the way Aleksey is trying to hookup a console.
> 
> What should be happening in this series is:
> 1. early map SPCR
> 2. parse the SPCR table
> 3. call add_preferred_console() to add the SPCR console to the console table
> 4. unmap SPCR
> 
> This trivial and unobtrusive method would already have a 8250 console
> running via SPCR. I've already pointed this out in previous reviews.
> 
> Further, the above method *will be required anyway* for the DBG2 table to
> start an earlycon, which I've already pointed out in previous reviews.
> 
> Then to enable amba-pl011 console via ACPI, add a console match() method
> similar to the 8250 console match() method, univ8250_console_match().
> 
> FWIW, PCI earlycon + console support was already submitted once before but
> never picked up by GregKH. I think I'll just grab that and re-submit so
> you would know what to emit for console options in the
> add_preferred_console().
> 
> 
> Regards,
> Peter Hurley
> 
> 
> >>> There is an early bootup requirement in Linux.
> >>> Maps acquired during the early stage should be freed by the driver during
> the
> >> early stage.
> >>> And the driver should re-acquire the memory map after booting.
> >>
> >> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
> >> that code can be
> >> called *before* acpi_gbl_permanent_mmap is set (at early initialization of
> for
> >> example 8250 console)
> >> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
> >> registers a console),
> >> We just can not tell if the received table pointer should or sould not be freed
> >> with early_memunmap()
> >> (actually __acpi_unmap_table() or whatever) without checking
> >> acpi_gbl_permanent_mmap,
> >> but that's all too low level.
> > [Lv Zheng]
> > The driver should make sure that:
> > Map/unmap is paired during early stage.
> > For late stage, it should be another pair of map/unmap.
> >
> >>
> >> Another option, as you describe, is to get this pointer early, don't free it
> > [Lv Zheng]
> > I mean you should free it early.
> >
> >> untill acpi_gbl_permanent_mmap is set, then free it (with
> >> early_acpi_os_unmap_memory(), that's
> >> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
> >> persistent
> >> pointer to the table.  The problem with it is that we can not just watch
> >> acpi_gbl_permanent_mmap
> >> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap
> is
> >> not good as it probably is
> >> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >> Or I probably miss what you are suggesting.
> >>
> > [Lv Zheng]
> > I mean, you should:
> > During early stage:
> > acpi_os_map_memory()
> > Parse the table.
> > acpi_os_unmap_memory().
> >
> >>> This is because, during early bootup stage, there are only limited slots
> >> available for drivers to map memory.
> >>> So by changing __init to __ref here, you probably will hide many such
> defects.
> >>
> >> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >> BTW, exactly the same thing is done in the beginning of
> >> acpi_os_unmap_memory() and than's ok,
> >> that function is __ref.
> >>
> >>> And solving issues in this way doesn't seem to be an improvement.
> >>
> >> Could you please tell me where I am wrong?  I still don't understand your
> point.
> > [Lv Zheng]
> > But anyway, the defect should be in ACPI subsystem core.
> > The cause should be the API itself - acpi_get_table().
> >
> > So I agree you can use early_acpi_os_unmap_memory() during the period the
> root causes are not cleaned up.
> > But the bottom line is: the driver need to ensure that
> early_acpi_os_unmap_memory() is always invoked.
> > As long as you can ensure this, I don't have objections for deploying
> early_acpi_os_unmap_memory()  for now.
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >> Thank you
> >> Aleksey Makarov
> >>
> >>>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>>
> >>>> Thanks and best regards
> >>>> -Lv
> >>>>
> >>>>>
> >>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>> ---
> >>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>
> >>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>> index 67da6fb..8a552cd 100644
> >>>>> --- a/drivers/acpi/osl.c
> >>>>> +++ b/drivers/acpi/osl.c
> >>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> >>>>> acpi_size size)
> >>>>>  }
> >>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>
> >>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> acpi_size
> >>>> size)
> >>>>> +/*
> >>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>> + */
> >>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> acpi_size
> >>>> size)
> >>>>>  {
> >>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>  		__acpi_unmap_table(virt, size);
> >>>>> --
> >>>>> 2.7.1
> >>>>>
> >>>>> --
> >>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>> the body of a message to majordomo@vger.kernel.org
> >>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >>>> --
> >>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>> the body of a message to majordomo@vger.kernel.org
> >>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-19  2:58               ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-19  2:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> Hi Lv,
> >>
> >> Thank you for review.
> >>
> >> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>
> >> [..]
> >>
> >>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
> >> set.
> >>>>>
> >>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>
> >>>>> We need this function to be non-__init because we need access to
> >>>>> some tables at unpredictable time--it may be before or after
> >>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> Console
> >>>>> Redirection) table is needed each time a new console is registered.
> >>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>> does.
> >>>> [Lv Zheng]
> >>>> Why don't you use another API instead of
> early_acpi_os_unmap_memory()
> >> in
> >>>> case you want to unmap things in any cases.
> >>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>
> >> As far as I understand, there exist two steps in ACPI initialization:
> >>
> >> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >> acpi_get_table_with_size()
> >>    are mapped by early_memremap().  If a subsystem gets such a pointer it
> >> should be unmapped.
> >>
> >> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> unmapped
> >> at all.
> >>
> > [Lv Zheng]
> > This statement is wrong, this should be:
> > As long as there is a __reference__ to the mapped table, the pointer should
> not be unmapped.
> > In fact, we have a series to introduce acpi_put_table() to achieve this.
> > So your argument is wrong from very first point.
> >
> >> That exactly what early_acpi_os_unmap_memory() does--it checks
> >> acpi_gbl_permanent_mmap.
> >> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
> had
> >> been set,
> >> it would have tried to free that pointer with an oops (actually, I checked that
> >> and got that oops).
> >>
> >> So using acpi_os_unmap_memory() is not an option here, but
> >> early_acpi_os_unmap_memory()
> >> match perfectly.
> > [Lv Zheng]
> > I don't think so.
> > For definition block tables, we know for sure there will always be references,
> until "Unload" opcode is invoked by the AML interpreter.
> > But for the data tables, OSPMs should use them in this way:
> > 1. map the table
> > 2. parse the table and convert it to OS specific structures
> > 3. unmap the table
> > This helps to shrink virtual memory address space usages.
> >
> > So from this point of view, all data tables should be unmapped right after
> being parsed.
> > Why do you need the map to be persistent in the kernel address space?
> > You can always map a small table, but what if the table size is very big?
> >
> >>
> >>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>
> >> I don't think so -- I have explained why.  It does different thing.
> >> Probably it (and/or other functions in that api) should be renamed.
> >>
> > [Lv Zheng]
> > Just let me ask one more question.
> > eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> > How ACPICA can work with just acpi_os_unmap_memory()?
> > You can check drivers/acpi/tbxxx.c.
> > Especially: acpi_tb_release_temp_table() and the code invoking it.
> >
> >>> [Lv Zheng]
> >>> One more thing is:
> >>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
> >> early_acpi_os_unmap_memory(),
> >>> then it implies that your driver does have a defect.
> >>
> >> I still don't understand what defect, sorry.
> > [Lv Zheng]
> > If you can't ensure this sequence for using the data tables:
> > 1. map the table
> > 2. parse the table and convert it to OS specific structure
> > 3. unmap the table
> > It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> 
> Exactly.
[Lv Zheng] 
So it looks to me:
Changing __init to __ref here is entirely not acceptable.
This API should stay being invoked during early stage.
Otherwise, it may leave us untrackable code that maps tables during early stage and leaks maps to the late stage.
If Linux contains such kind of code, I'm afraid, it will become impossible to introduce acpi_put_table() to clean up the mappings.
Because when acpi_put_table() is called during the late stage to free a map acquired during the early stage, it then obviously will end up with panic.

Thanks and best regards
-Lv

> The central problem here is the way Aleksey is trying to hookup a console.
> 
> What should be happening in this series is:
> 1. early map SPCR
> 2. parse the SPCR table
> 3. call add_preferred_console() to add the SPCR console to the console table
> 4. unmap SPCR
> 
> This trivial and unobtrusive method would already have a 8250 console
> running via SPCR. I've already pointed this out in previous reviews.
> 
> Further, the above method *will be required anyway* for the DBG2 table to
> start an earlycon, which I've already pointed out in previous reviews.
> 
> Then to enable amba-pl011 console via ACPI, add a console match() method
> similar to the 8250 console match() method, univ8250_console_match().
> 
> FWIW, PCI earlycon + console support was already submitted once before but
> never picked up by GregKH. I think I'll just grab that and re-submit so
> you would know what to emit for console options in the
> add_preferred_console().
> 
> 
> Regards,
> Peter Hurley
> 
> 
> >>> There is an early bootup requirement in Linux.
> >>> Maps acquired during the early stage should be freed by the driver during
> the
> >> early stage.
> >>> And the driver should re-acquire the memory map after booting.
> >>
> >> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
> >> that code can be
> >> called *before* acpi_gbl_permanent_mmap is set (at early initialization of
> for
> >> example 8250 console)
> >> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
> >> registers a console),
> >> We just can not tell if the received table pointer should or sould not be freed
> >> with early_memunmap()
> >> (actually __acpi_unmap_table() or whatever) without checking
> >> acpi_gbl_permanent_mmap,
> >> but that's all too low level.
> > [Lv Zheng]
> > The driver should make sure that:
> > Map/unmap is paired during early stage.
> > For late stage, it should be another pair of map/unmap.
> >
> >>
> >> Another option, as you describe, is to get this pointer early, don't free it
> > [Lv Zheng]
> > I mean you should free it early.
> >
> >> untill acpi_gbl_permanent_mmap is set, then free it (with
> >> early_acpi_os_unmap_memory(), that's
> >> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
> >> persistent
> >> pointer to the table.  The problem with it is that we can not just watch
> >> acpi_gbl_permanent_mmap
> >> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap
> is
> >> not good as it probably is
> >> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >> Or I probably miss what you are suggesting.
> >>
> > [Lv Zheng]
> > I mean, you should:
> > During early stage:
> > acpi_os_map_memory()
> > Parse the table.
> > acpi_os_unmap_memory().
> >
> >>> This is because, during early bootup stage, there are only limited slots
> >> available for drivers to map memory.
> >>> So by changing __init to __ref here, you probably will hide many such
> defects.
> >>
> >> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >> BTW, exactly the same thing is done in the beginning of
> >> acpi_os_unmap_memory() and than's ok,
> >> that function is __ref.
> >>
> >>> And solving issues in this way doesn't seem to be an improvement.
> >>
> >> Could you please tell me where I am wrong?  I still don't understand your
> point.
> > [Lv Zheng]
> > But anyway, the defect should be in ACPI subsystem core.
> > The cause should be the API itself - acpi_get_table().
> >
> > So I agree you can use early_acpi_os_unmap_memory() during the period the
> root causes are not cleaned up.
> > But the bottom line is: the driver need to ensure that
> early_acpi_os_unmap_memory() is always invoked.
> > As long as you can ensure this, I don't have objections for deploying
> early_acpi_os_unmap_memory()  for now.
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >> Thank you
> >> Aleksey Makarov
> >>
> >>>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>>
> >>>> Thanks and best regards
> >>>> -Lv
> >>>>
> >>>>>
> >>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>> ---
> >>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>
> >>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>> index 67da6fb..8a552cd 100644
> >>>>> --- a/drivers/acpi/osl.c
> >>>>> +++ b/drivers/acpi/osl.c
> >>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
> >>>>> acpi_size size)
> >>>>>  }
> >>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>
> >>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> acpi_size
> >>>> size)
> >>>>> +/*
> >>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>> + */
> >>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> acpi_size
> >>>> size)
> >>>>>  {
> >>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>  		__acpi_unmap_table(virt, size);
> >>>>> --
> >>>>> 2.7.1
> >>>>>
> >>>>> --
> >>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>> the body of a message to majordomo at vger.kernel.org
> >>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >>>> --
> >>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>> the body of a message to majordomo at vger.kernel.org
> >>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-18 22:03             ` Peter Hurley
  (?)
@ 2016-02-19 10:42               ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-19 10:42 UTC (permalink / raw)
  To: Peter Hurley, Zheng, Lv, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi Peter,

Thank you for review.

On 02/19/2016 01:03 AM, Peter Hurley wrote:
> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>> Hi,
>>
>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>> early_acpi_os_unmap_memory()
>>>
>>> Hi Lv,
>>>
>>> Thank you for review.
>>>
>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>
>>> [..]
>>>
>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>> set.
>>>>>>
>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>
>>>>>> We need this function to be non-__init because we need access to
>>>>>> some tables at unpredictable time--it may be before or after
>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>> does.
>>>>> [Lv Zheng]
>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>> in
>>>>> case you want to unmap things in any cases.
>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>
>>> As far as I understand, there exist two steps in ACPI initialization:
>>>
>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>> acpi_get_table_with_size()
>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>> should be unmapped.
>>>
>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>> at all.
>>>
>> [Lv Zheng] 
>> This statement is wrong, this should be:
>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>> So your argument is wrong from very first point.
>>
>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>> acpi_gbl_permanent_mmap.
>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>> been set,
>>> it would have tried to free that pointer with an oops (actually, I checked that
>>> and got that oops).
>>>
>>> So using acpi_os_unmap_memory() is not an option here, but
>>> early_acpi_os_unmap_memory()
>>> match perfectly.
>> [Lv Zheng] 
>> I don't think so.
>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>> But for the data tables, OSPMs should use them in this way:
>> 1. map the table
>> 2. parse the table and convert it to OS specific structures
>> 3. unmap the table
>> This helps to shrink virtual memory address space usages.
>>
>> So from this point of view, all data tables should be unmapped right after being parsed.
>> Why do you need the map to be persistent in the kernel address space?
>> You can always map a small table, but what if the table size is very big?
>>
>>>
>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>
>>> I don't think so -- I have explained why.  It does different thing.
>>> Probably it (and/or other functions in that api) should be renamed.
>>>
>> [Lv Zheng] 
>> Just let me ask one more question.
>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>> How ACPICA can work with just acpi_os_unmap_memory()?
>> You can check drivers/acpi/tbxxx.c.
>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>
>>>> [Lv Zheng]
>>>> One more thing is:
>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>> early_acpi_os_unmap_memory(),
>>>> then it implies that your driver does have a defect.
>>>
>>> I still don't understand what defect, sorry.
>> [Lv Zheng] 
>> If you can't ensure this sequence for using the data tables:
>> 1. map the table
>> 2. parse the table and convert it to OS specific structure
>> 3. unmap the table
>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> 
> Exactly.
> 
> The central problem here is the way Aleksey is trying to hookup a console.
> 
> What should be happening in this series is:
> 1. early map SPCR
> 2. parse the SPCR table
> 3. call add_preferred_console() to add the SPCR console to the console table
> 4. unmap SPCR

This does not work.  

SPCR specifies address of the console, but add_preferred_console() accepts
name of console and its index.  There are no general method to translate address
to name at such an early stage.

There is another reason why I prefer to parse SPCR each time a console is registered.
Some consoles can be registered very early in the initialization process and
we have to be sure add_preferred_console() is called before that.

Of course, I could just parse it once and cache the results, but
this still requires accessing SPCR before acpi_gbl_permanent_mmap
is set *or* after that.

> This trivial and unobtrusive method would already have a 8250 console
> running via SPCR. I've already pointed this out in previous reviews.
> 
> Further, the above method *will be required anyway* for the DBG2 table to
> start an earlycon, which I've already pointed out in previous reviews.
> 
> Then to enable amba-pl011 console via ACPI, add a console match() method
> similar to the 8250 console match() method, univ8250_console_match().

So are you suggesting a separate method for each possible console?
This is not acceptable.

Do you suggest making up separate new name (like "uart" for 8250) for each type
of conosole SPCR can specify?

> FWIW, PCI earlycon + console support was already submitted once before but
> never picked up by GregKH. I think I'll just grab that and re-submit so
> you would know what to emit for console options in the add_preferred_console().

Please do.  Or just send a link to to that submission.

Do you mean the Leif Lindholm's patches:

https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm@linaro.org

He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
(I just match SPCR against data that struct uart_port already has)
2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
And that's why his submission is RFC: he had troubles with the order of initialization.

Thank you
Aleksey Makarov

> Regards,
> Peter Hurley
> 
> 
>>>> There is an early bootup requirement in Linux.
>>>> Maps acquired during the early stage should be freed by the driver during the
>>> early stage.
>>>> And the driver should re-acquire the memory map after booting.
>>>
>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>> that code can be
>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>> example 8250 console)
>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>> registers a console),
>>> We just can not tell if the received table pointer should or sould not be freed
>>> with early_memunmap()
>>> (actually __acpi_unmap_table() or whatever) without checking
>>> acpi_gbl_permanent_mmap,
>>> but that's all too low level.
>> [Lv Zheng] 
>> The driver should make sure that:
>> Map/unmap is paired during early stage.
>> For late stage, it should be another pair of map/unmap.
>>
>>>
>>> Another option, as you describe, is to get this pointer early, don't free it
>> [Lv Zheng] 
>> I mean you should free it early.
>>
>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>> early_acpi_os_unmap_memory(), that's
>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>> persistent
>>> pointer to the table.  The problem with it is that we can not just watch
>>> acpi_gbl_permanent_mmap
>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>> not good as it probably is
>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>> Or I probably miss what you are suggesting.
>>>
>> [Lv Zheng] 
>> I mean, you should:
>> During early stage:
>> acpi_os_map_memory()
>> Parse the table.
>> acpi_os_unmap_memory().
>>
>>>> This is because, during early bootup stage, there are only limited slots
>>> available for drivers to map memory.
>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>
>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>> BTW, exactly the same thing is done in the beginning of
>>> acpi_os_unmap_memory() and than's ok,
>>> that function is __ref.
>>>
>>>> And solving issues in this way doesn't seem to be an improvement.
>>>
>>> Could you please tell me where I am wrong?  I still don't understand your point.
>> [Lv Zheng] 
>> But anyway, the defect should be in ACPI subsystem core.
>> The cause should be the API itself - acpi_get_table().
>>
>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>
>> Thanks and best regards
>> -Lv
>>
>>>
>>> Thank you
>>> Aleksey Makarov
>>>
>>>>
>>>> Thanks and best regards
>>>> -Lv
>>>>
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>> ---
>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>> index 67da6fb..8a552cd 100644
>>>>>> --- a/drivers/acpi/osl.c
>>>>>> +++ b/drivers/acpi/osl.c
>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>> acpi_size size)
>>>>>>  }
>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>
>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>> size)
>>>>>> +/*
>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>> + */
>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>> size)
>>>>>>  {
>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>> --
>>>>>> 2.7.1
>>>>>>
>>>>>> --
>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-19 10:42               ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-19 10:42 UTC (permalink / raw)
  To: Peter Hurley, Zheng, Lv, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi Peter,

Thank you for review.

On 02/19/2016 01:03 AM, Peter Hurley wrote:
> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>> Hi,
>>
>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>> early_acpi_os_unmap_memory()
>>>
>>> Hi Lv,
>>>
>>> Thank you for review.
>>>
>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>
>>> [..]
>>>
>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>> set.
>>>>>>
>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>
>>>>>> We need this function to be non-__init because we need access to
>>>>>> some tables at unpredictable time--it may be before or after
>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>> does.
>>>>> [Lv Zheng]
>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>> in
>>>>> case you want to unmap things in any cases.
>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>
>>> As far as I understand, there exist two steps in ACPI initialization:
>>>
>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>> acpi_get_table_with_size()
>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>> should be unmapped.
>>>
>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>> at all.
>>>
>> [Lv Zheng] 
>> This statement is wrong, this should be:
>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>> So your argument is wrong from very first point.
>>
>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>> acpi_gbl_permanent_mmap.
>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>> been set,
>>> it would have tried to free that pointer with an oops (actually, I checked that
>>> and got that oops).
>>>
>>> So using acpi_os_unmap_memory() is not an option here, but
>>> early_acpi_os_unmap_memory()
>>> match perfectly.
>> [Lv Zheng] 
>> I don't think so.
>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>> But for the data tables, OSPMs should use them in this way:
>> 1. map the table
>> 2. parse the table and convert it to OS specific structures
>> 3. unmap the table
>> This helps to shrink virtual memory address space usages.
>>
>> So from this point of view, all data tables should be unmapped right after being parsed.
>> Why do you need the map to be persistent in the kernel address space?
>> You can always map a small table, but what if the table size is very big?
>>
>>>
>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>
>>> I don't think so -- I have explained why.  It does different thing.
>>> Probably it (and/or other functions in that api) should be renamed.
>>>
>> [Lv Zheng] 
>> Just let me ask one more question.
>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>> How ACPICA can work with just acpi_os_unmap_memory()?
>> You can check drivers/acpi/tbxxx.c.
>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>
>>>> [Lv Zheng]
>>>> One more thing is:
>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>> early_acpi_os_unmap_memory(),
>>>> then it implies that your driver does have a defect.
>>>
>>> I still don't understand what defect, sorry.
>> [Lv Zheng] 
>> If you can't ensure this sequence for using the data tables:
>> 1. map the table
>> 2. parse the table and convert it to OS specific structure
>> 3. unmap the table
>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> 
> Exactly.
> 
> The central problem here is the way Aleksey is trying to hookup a console.
> 
> What should be happening in this series is:
> 1. early map SPCR
> 2. parse the SPCR table
> 3. call add_preferred_console() to add the SPCR console to the console table
> 4. unmap SPCR

This does not work.  

SPCR specifies address of the console, but add_preferred_console() accepts
name of console and its index.  There are no general method to translate address
to name at such an early stage.

There is another reason why I prefer to parse SPCR each time a console is registered.
Some consoles can be registered very early in the initialization process and
we have to be sure add_preferred_console() is called before that.

Of course, I could just parse it once and cache the results, but
this still requires accessing SPCR before acpi_gbl_permanent_mmap
is set *or* after that.

> This trivial and unobtrusive method would already have a 8250 console
> running via SPCR. I've already pointed this out in previous reviews.
> 
> Further, the above method *will be required anyway* for the DBG2 table to
> start an earlycon, which I've already pointed out in previous reviews.
> 
> Then to enable amba-pl011 console via ACPI, add a console match() method
> similar to the 8250 console match() method, univ8250_console_match().

So are you suggesting a separate method for each possible console?
This is not acceptable.

Do you suggest making up separate new name (like "uart" for 8250) for each type
of conosole SPCR can specify?

> FWIW, PCI earlycon + console support was already submitted once before but
> never picked up by GregKH. I think I'll just grab that and re-submit so
> you would know what to emit for console options in the add_preferred_console().

Please do.  Or just send a link to to that submission.

Do you mean the Leif Lindholm's patches:

https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm@linaro.org

He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
(I just match SPCR against data that struct uart_port already has)
2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
And that's why his submission is RFC: he had troubles with the order of initialization.

Thank you
Aleksey Makarov

> Regards,
> Peter Hurley
> 
> 
>>>> There is an early bootup requirement in Linux.
>>>> Maps acquired during the early stage should be freed by the driver during the
>>> early stage.
>>>> And the driver should re-acquire the memory map after booting.
>>>
>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>> that code can be
>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>> example 8250 console)
>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>> registers a console),
>>> We just can not tell if the received table pointer should or sould not be freed
>>> with early_memunmap()
>>> (actually __acpi_unmap_table() or whatever) without checking
>>> acpi_gbl_permanent_mmap,
>>> but that's all too low level.
>> [Lv Zheng] 
>> The driver should make sure that:
>> Map/unmap is paired during early stage.
>> For late stage, it should be another pair of map/unmap.
>>
>>>
>>> Another option, as you describe, is to get this pointer early, don't free it
>> [Lv Zheng] 
>> I mean you should free it early.
>>
>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>> early_acpi_os_unmap_memory(), that's
>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>> persistent
>>> pointer to the table.  The problem with it is that we can not just watch
>>> acpi_gbl_permanent_mmap
>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>> not good as it probably is
>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>> Or I probably miss what you are suggesting.
>>>
>> [Lv Zheng] 
>> I mean, you should:
>> During early stage:
>> acpi_os_map_memory()
>> Parse the table.
>> acpi_os_unmap_memory().
>>
>>>> This is because, during early bootup stage, there are only limited slots
>>> available for drivers to map memory.
>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>
>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>> BTW, exactly the same thing is done in the beginning of
>>> acpi_os_unmap_memory() and than's ok,
>>> that function is __ref.
>>>
>>>> And solving issues in this way doesn't seem to be an improvement.
>>>
>>> Could you please tell me where I am wrong?  I still don't understand your point.
>> [Lv Zheng] 
>> But anyway, the defect should be in ACPI subsystem core.
>> The cause should be the API itself - acpi_get_table().
>>
>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>
>> Thanks and best regards
>> -Lv
>>
>>>
>>> Thank you
>>> Aleksey Makarov
>>>
>>>>
>>>> Thanks and best regards
>>>> -Lv
>>>>
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>> ---
>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>> index 67da6fb..8a552cd 100644
>>>>>> --- a/drivers/acpi/osl.c
>>>>>> +++ b/drivers/acpi/osl.c
>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>> acpi_size size)
>>>>>>  }
>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>
>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>> size)
>>>>>> +/*
>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>> + */
>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>> size)
>>>>>>  {
>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>> --
>>>>>> 2.7.1
>>>>>>
>>>>>> --
>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-19 10:42               ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-19 10:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Peter,

Thank you for review.

On 02/19/2016 01:03 AM, Peter Hurley wrote:
> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>> Hi,
>>
>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>> early_acpi_os_unmap_memory()
>>>
>>> Hi Lv,
>>>
>>> Thank you for review.
>>>
>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>
>>> [..]
>>>
>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>> set.
>>>>>>
>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>
>>>>>> We need this function to be non-__init because we need access to
>>>>>> some tables at unpredictable time--it may be before or after
>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>> does.
>>>>> [Lv Zheng]
>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>> in
>>>>> case you want to unmap things in any cases.
>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>
>>> As far as I understand, there exist two steps in ACPI initialization:
>>>
>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>> acpi_get_table_with_size()
>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>> should be unmapped.
>>>
>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>> at all.
>>>
>> [Lv Zheng] 
>> This statement is wrong, this should be:
>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>> So your argument is wrong from very first point.
>>
>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>> acpi_gbl_permanent_mmap.
>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>> been set,
>>> it would have tried to free that pointer with an oops (actually, I checked that
>>> and got that oops).
>>>
>>> So using acpi_os_unmap_memory() is not an option here, but
>>> early_acpi_os_unmap_memory()
>>> match perfectly.
>> [Lv Zheng] 
>> I don't think so.
>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>> But for the data tables, OSPMs should use them in this way:
>> 1. map the table
>> 2. parse the table and convert it to OS specific structures
>> 3. unmap the table
>> This helps to shrink virtual memory address space usages.
>>
>> So from this point of view, all data tables should be unmapped right after being parsed.
>> Why do you need the map to be persistent in the kernel address space?
>> You can always map a small table, but what if the table size is very big?
>>
>>>
>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>
>>> I don't think so -- I have explained why.  It does different thing.
>>> Probably it (and/or other functions in that api) should be renamed.
>>>
>> [Lv Zheng] 
>> Just let me ask one more question.
>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>> How ACPICA can work with just acpi_os_unmap_memory()?
>> You can check drivers/acpi/tbxxx.c.
>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>
>>>> [Lv Zheng]
>>>> One more thing is:
>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>> early_acpi_os_unmap_memory(),
>>>> then it implies that your driver does have a defect.
>>>
>>> I still don't understand what defect, sorry.
>> [Lv Zheng] 
>> If you can't ensure this sequence for using the data tables:
>> 1. map the table
>> 2. parse the table and convert it to OS specific structure
>> 3. unmap the table
>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> 
> Exactly.
> 
> The central problem here is the way Aleksey is trying to hookup a console.
> 
> What should be happening in this series is:
> 1. early map SPCR
> 2. parse the SPCR table
> 3. call add_preferred_console() to add the SPCR console to the console table
> 4. unmap SPCR

This does not work.  

SPCR specifies address of the console, but add_preferred_console() accepts
name of console and its index.  There are no general method to translate address
to name at such an early stage.

There is another reason why I prefer to parse SPCR each time a console is registered.
Some consoles can be registered very early in the initialization process and
we have to be sure add_preferred_console() is called before that.

Of course, I could just parse it once and cache the results, but
this still requires accessing SPCR before acpi_gbl_permanent_mmap
is set *or* after that.

> This trivial and unobtrusive method would already have a 8250 console
> running via SPCR. I've already pointed this out in previous reviews.
> 
> Further, the above method *will be required anyway* for the DBG2 table to
> start an earlycon, which I've already pointed out in previous reviews.
> 
> Then to enable amba-pl011 console via ACPI, add a console match() method
> similar to the 8250 console match() method, univ8250_console_match().

So are you suggesting a separate method for each possible console?
This is not acceptable.

Do you suggest making up separate new name (like "uart" for 8250) for each type
of conosole SPCR can specify?

> FWIW, PCI earlycon + console support was already submitted once before but
> never picked up by GregKH. I think I'll just grab that and re-submit so
> you would know what to emit for console options in the add_preferred_console().

Please do.  Or just send a link to to that submission.

Do you mean the Leif Lindholm's patches:

https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm at linaro.org

He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
(I just match SPCR against data that struct uart_port already has)
2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
And that's why his submission is RFC: he had troubles with the order of initialization.

Thank you
Aleksey Makarov

> Regards,
> Peter Hurley
> 
> 
>>>> There is an early bootup requirement in Linux.
>>>> Maps acquired during the early stage should be freed by the driver during the
>>> early stage.
>>>> And the driver should re-acquire the memory map after booting.
>>>
>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>> that code can be
>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>> example 8250 console)
>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>> registers a console),
>>> We just can not tell if the received table pointer should or sould not be freed
>>> with early_memunmap()
>>> (actually __acpi_unmap_table() or whatever) without checking
>>> acpi_gbl_permanent_mmap,
>>> but that's all too low level.
>> [Lv Zheng] 
>> The driver should make sure that:
>> Map/unmap is paired during early stage.
>> For late stage, it should be another pair of map/unmap.
>>
>>>
>>> Another option, as you describe, is to get this pointer early, don't free it
>> [Lv Zheng] 
>> I mean you should free it early.
>>
>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>> early_acpi_os_unmap_memory(), that's
>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>> persistent
>>> pointer to the table.  The problem with it is that we can not just watch
>>> acpi_gbl_permanent_mmap
>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>> not good as it probably is
>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>> Or I probably miss what you are suggesting.
>>>
>> [Lv Zheng] 
>> I mean, you should:
>> During early stage:
>> acpi_os_map_memory()
>> Parse the table.
>> acpi_os_unmap_memory().
>>
>>>> This is because, during early bootup stage, there are only limited slots
>>> available for drivers to map memory.
>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>
>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>> BTW, exactly the same thing is done in the beginning of
>>> acpi_os_unmap_memory() and than's ok,
>>> that function is __ref.
>>>
>>>> And solving issues in this way doesn't seem to be an improvement.
>>>
>>> Could you please tell me where I am wrong?  I still don't understand your point.
>> [Lv Zheng] 
>> But anyway, the defect should be in ACPI subsystem core.
>> The cause should be the API itself - acpi_get_table().
>>
>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>
>> Thanks and best regards
>> -Lv
>>
>>>
>>> Thank you
>>> Aleksey Makarov
>>>
>>>>
>>>> Thanks and best regards
>>>> -Lv
>>>>
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>> ---
>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>> index 67da6fb..8a552cd 100644
>>>>>> --- a/drivers/acpi/osl.c
>>>>>> +++ b/drivers/acpi/osl.c
>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>> acpi_size size)
>>>>>>  }
>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>
>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>> size)
>>>>>> +/*
>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>> + */
>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>> size)
>>>>>>  {
>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>> --
>>>>>> 2.7.1
>>>>>>
>>>>>> --
>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>> the body of a message to majordomo at vger.kernel.org
>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>> the body of a message to majordomo at vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
  2016-02-18 22:19     ` Peter Hurley
@ 2016-02-19 10:47       ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-19 10:47 UTC (permalink / raw)
  To: Peter Hurley, linux-acpi
  Cc: Russell King, Graeme Gregory, Greg Kroah-Hartman,
	Rafael J . Wysocki, linux-kernel, Leif Lindholm,
	Christopher Covington, linux-serial, Jiri Slaby, Al Stone,
	linux-arm-kernel, Len Brown

Hi Peter,

Thank you for review.

On 02/19/2016 01:19 AM, Peter Hurley wrote:
> On 02/15/2016 10:05 AM, Aleksey Makarov wrote:

[..]

>> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
>> index a126a60..459ab54 100644
>> --- a/drivers/tty/serial/serial_core.c
>> +++ b/drivers/tty/serial/serial_core.c
>> @@ -34,6 +34,7 @@
>>  #include <linux/serial_core.h>
>>  #include <linux/delay.h>
>>  #include <linux/mutex.h>
>> +#include <linux/acpi.h>
>>  
>>  #include <asm/irq.h>
>>  #include <asm/uaccess.h>
>> @@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>>  		spin_lock_init(&uport->lock);
>>  		lockdep_set_class(&uport->lock, &port_lock_key);
>>  	}
>> -	if (uport->cons && uport->dev)
>> -		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
>> +
>> +	/*
>> +	 * Support both open FW and ACPI access to console definitions.
>> +	 * Both of_console_check() and acpi_console_check() will call
>> +	 * add_preferred_console() if a console definition is found.
>> +	 */
>> +	if (uport->cons && uport->dev) {
>> +		if (!acpi_console_check(uport))
>> +			of_console_check(uport->dev->of_node, uport->cons->name,
>> +					 uport->line);
> 
> of_console_check() is not a good model for enabling a console.
> It's a hack with several shortcomings (and bugs) that is tolerated here
> because of its broad applicability to a wide range of platforms and drivers.

It's definitely not the best code I saw but there is no bugs.

> I specifically added console matching to enable exactly this kind of
> console-selection-via-firmware. Please use that facility.

I described why this does not work (except you insist on having 
new made up names for all types of SPCR consoles) in the reply to another your message.

Thank you
Aleksey Makarov

> Regards,
> Peter Hurley
> 
> 
>> +	}
>>  
>>  	uart_configure_port(drv, state, uport);
>>  
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 06ed7e5..ea0c297 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
>>  #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
>>  #endif
>>  
>> +struct uart_port;
>> +#ifdef CONFIG_ACPI_SPCR_TABLE
>> +bool acpi_console_check(struct uart_port *uport);
>> +#else
>> +static inline bool acpi_console_check(struct uart_port *uport)
>> +{
>> +	return FALSE;
>> +}
>> +#endif
>> +
>>  #endif	/*_LINUX_ACPI_H*/
>>
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
@ 2016-02-19 10:47       ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-19 10:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Peter,

Thank you for review.

On 02/19/2016 01:19 AM, Peter Hurley wrote:
> On 02/15/2016 10:05 AM, Aleksey Makarov wrote:

[..]

>> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
>> index a126a60..459ab54 100644
>> --- a/drivers/tty/serial/serial_core.c
>> +++ b/drivers/tty/serial/serial_core.c
>> @@ -34,6 +34,7 @@
>>  #include <linux/serial_core.h>
>>  #include <linux/delay.h>
>>  #include <linux/mutex.h>
>> +#include <linux/acpi.h>
>>  
>>  #include <asm/irq.h>
>>  #include <asm/uaccess.h>
>> @@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>>  		spin_lock_init(&uport->lock);
>>  		lockdep_set_class(&uport->lock, &port_lock_key);
>>  	}
>> -	if (uport->cons && uport->dev)
>> -		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
>> +
>> +	/*
>> +	 * Support both open FW and ACPI access to console definitions.
>> +	 * Both of_console_check() and acpi_console_check() will call
>> +	 * add_preferred_console() if a console definition is found.
>> +	 */
>> +	if (uport->cons && uport->dev) {
>> +		if (!acpi_console_check(uport))
>> +			of_console_check(uport->dev->of_node, uport->cons->name,
>> +					 uport->line);
> 
> of_console_check() is not a good model for enabling a console.
> It's a hack with several shortcomings (and bugs) that is tolerated here
> because of its broad applicability to a wide range of platforms and drivers.

It's definitely not the best code I saw but there is no bugs.

> I specifically added console matching to enable exactly this kind of
> console-selection-via-firmware. Please use that facility.

I described why this does not work (except you insist on having 
new made up names for all types of SPCR consoles) in the reply to another your message.

Thank you
Aleksey Makarov

> Regards,
> Peter Hurley
> 
> 
>> +	}
>>  
>>  	uart_configure_port(drv, state, uport);
>>  
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 06ed7e5..ea0c297 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
>>  #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
>>  #endif
>>  
>> +struct uart_port;
>> +#ifdef CONFIG_ACPI_SPCR_TABLE
>> +bool acpi_console_check(struct uart_port *uport);
>> +#else
>> +static inline bool acpi_console_check(struct uart_port *uport)
>> +{
>> +	return FALSE;
>> +}
>> +#endif
>> +
>>  #endif	/*_LINUX_ACPI_H*/
>>
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-19  2:58               ` Zheng, Lv
  (?)
@ 2016-02-19 11:02                 ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-19 11:02 UTC (permalink / raw)
  To: Zheng, Lv, Peter Hurley, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi Lv,

On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> Hi,
> 
>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> Hi Lv,
>>>>
>>>> Thank you for review.
>>>>
>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>
>>>> [..]
>>>>
>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>> set.
>>>>>>>
>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>
>>>>>>> We need this function to be non-__init because we need access to
>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>> Console
>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>> does.
>>>>>> [Lv Zheng]
>>>>>> Why don't you use another API instead of
>> early_acpi_os_unmap_memory()
>>>> in
>>>>>> case you want to unmap things in any cases.
>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>
>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>
>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>> acpi_get_table_with_size()
>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>> should be unmapped.
>>>>
>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>> unmapped
>>>> at all.
>>>>
>>> [Lv Zheng]
>>> This statement is wrong, this should be:
>>> As long as there is a __reference__ to the mapped table, the pointer should
>> not be unmapped.
>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>> So your argument is wrong from very first point.
>>>
>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>> acpi_gbl_permanent_mmap.
>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>> had
>>>> been set,
>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>> and got that oops).
>>>>
>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>> early_acpi_os_unmap_memory()
>>>> match perfectly.
>>> [Lv Zheng]
>>> I don't think so.
>>> For definition block tables, we know for sure there will always be references,
>> until "Unload" opcode is invoked by the AML interpreter.
>>> But for the data tables, OSPMs should use them in this way:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structures
>>> 3. unmap the table
>>> This helps to shrink virtual memory address space usages.
>>>
>>> So from this point of view, all data tables should be unmapped right after
>> being parsed.
>>> Why do you need the map to be persistent in the kernel address space?
>>> You can always map a small table, but what if the table size is very big?
>>>
>>>>
>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>
>>>> I don't think so -- I have explained why.  It does different thing.
>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>
>>> [Lv Zheng]
>>> Just let me ask one more question.
>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>> You can check drivers/acpi/tbxxx.c.
>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>
>>>>> [Lv Zheng]
>>>>> One more thing is:
>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>> early_acpi_os_unmap_memory(),
>>>>> then it implies that your driver does have a defect.
>>>>
>>>> I still don't understand what defect, sorry.
>>> [Lv Zheng]
>>> If you can't ensure this sequence for using the data tables:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structure
>>> 3. unmap the table
>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>
>> Exactly.
> [Lv Zheng] 
> So it looks to me:
> Changing __init to __ref here is entirely not acceptable.
> This API should stay being invoked during early stage.
> Otherwise, it may leave us untrackable code that maps tables during early stage and leaks maps to the late stage.
> If Linux contains such kind of code, I'm afraid, it will become impossible to introduce acpi_put_table() to clean up the mappings.
> Because when acpi_put_table() is called during the late stage to free a map acquired during the early stage, it then obviously will end up with panic.

Can you please sugggest a common method to access ACPI tables that
works both before *and* after acpi_gbl_permanent_mmap is set and __init code
is removed?

> Thanks and best regards
> -Lv
> 
>> The central problem here is the way Aleksey is trying to hookup a console.
>>
>> What should be happening in this series is:
>> 1. early map SPCR
>> 2. parse the SPCR table
>> 3. call add_preferred_console() to add the SPCR console to the console table
>> 4. unmap SPCR
>>
>> This trivial and unobtrusive method would already have a 8250 console
>> running via SPCR. I've already pointed this out in previous reviews.
>>
>> Further, the above method *will be required anyway* for the DBG2 table to
>> start an earlycon, which I've already pointed out in previous reviews.
>>
>> Then to enable amba-pl011 console via ACPI, add a console match() method
>> similar to the 8250 console match() method, univ8250_console_match().
>>
>> FWIW, PCI earlycon + console support was already submitted once before but
>> never picked up by GregKH. I think I'll just grab that and re-submit so
>> you would know what to emit for console options in the
>> add_preferred_console().
>>
>>
>> Regards,
>> Peter Hurley
>>
>>
>>>>> There is an early bootup requirement in Linux.
>>>>> Maps acquired during the early stage should be freed by the driver during
>> the
>>>> early stage.
>>>>> And the driver should re-acquire the memory map after booting.
>>>>
>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>> that code can be
>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of
>> for
>>>> example 8250 console)
>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>> registers a console),
>>>> We just can not tell if the received table pointer should or sould not be freed
>>>> with early_memunmap()
>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>> acpi_gbl_permanent_mmap,
>>>> but that's all too low level.
>>> [Lv Zheng]
>>> The driver should make sure that:
>>> Map/unmap is paired during early stage.
>>> For late stage, it should be another pair of map/unmap.
>>>
>>>>
>>>> Another option, as you describe, is to get this pointer early, don't free it
>>> [Lv Zheng]
>>> I mean you should free it early.
>>>
>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>> early_acpi_os_unmap_memory(), that's
>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>> persistent
>>>> pointer to the table.  The problem with it is that we can not just watch
>>>> acpi_gbl_permanent_mmap
>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap
>> is
>>>> not good as it probably is
>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>> Or I probably miss what you are suggesting.
>>>>
>>> [Lv Zheng]
>>> I mean, you should:
>>> During early stage:
>>> acpi_os_map_memory()
>>> Parse the table.
>>> acpi_os_unmap_memory().
>>>
>>>>> This is because, during early bootup stage, there are only limited slots
>>>> available for drivers to map memory.
>>>>> So by changing __init to __ref here, you probably will hide many such
>> defects.
>>>>
>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>> BTW, exactly the same thing is done in the beginning of
>>>> acpi_os_unmap_memory() and than's ok,
>>>> that function is __ref.
>>>>
>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>
>>>> Could you please tell me where I am wrong?  I still don't understand your
>> point.
>>> [Lv Zheng]
>>> But anyway, the defect should be in ACPI subsystem core.
>>> The cause should be the API itself - acpi_get_table().
>>>
>>> So I agree you can use early_acpi_os_unmap_memory() during the period the
>> root causes are not cleaned up.
>>> But the bottom line is: the driver need to ensure that
>> early_acpi_os_unmap_memory() is always invoked.
>>> As long as you can ensure this, I don't have objections for deploying
>> early_acpi_os_unmap_memory()  for now.
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>> Thank you
>>>> Aleksey Makarov
>>>>
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thanks and best regards
>>>>>> -Lv
>>>>>>
>>>>>>>
>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>> ---
>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>
>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>> acpi_size size)
>>>>>>>  }
>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>
>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
>> acpi_size
>>>>>> size)
>>>>>>> +/*
>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>> + */
>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
>> acpi_size
>>>>>> size)
>>>>>>>  {
>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>> --
>>>>>>> 2.7.1
>>>>>>>
>>>>>>> --
>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>>> --
>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-19 11:02                 ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-19 11:02 UTC (permalink / raw)
  To: Zheng, Lv, Peter Hurley, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi Lv,

On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> Hi,
> 
>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> Hi Lv,
>>>>
>>>> Thank you for review.
>>>>
>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>
>>>> [..]
>>>>
>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>> set.
>>>>>>>
>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>
>>>>>>> We need this function to be non-__init because we need access to
>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>> Console
>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>> does.
>>>>>> [Lv Zheng]
>>>>>> Why don't you use another API instead of
>> early_acpi_os_unmap_memory()
>>>> in
>>>>>> case you want to unmap things in any cases.
>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>
>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>
>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>> acpi_get_table_with_size()
>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>> should be unmapped.
>>>>
>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>> unmapped
>>>> at all.
>>>>
>>> [Lv Zheng]
>>> This statement is wrong, this should be:
>>> As long as there is a __reference__ to the mapped table, the pointer should
>> not be unmapped.
>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>> So your argument is wrong from very first point.
>>>
>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>> acpi_gbl_permanent_mmap.
>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>> had
>>>> been set,
>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>> and got that oops).
>>>>
>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>> early_acpi_os_unmap_memory()
>>>> match perfectly.
>>> [Lv Zheng]
>>> I don't think so.
>>> For definition block tables, we know for sure there will always be references,
>> until "Unload" opcode is invoked by the AML interpreter.
>>> But for the data tables, OSPMs should use them in this way:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structures
>>> 3. unmap the table
>>> This helps to shrink virtual memory address space usages.
>>>
>>> So from this point of view, all data tables should be unmapped right after
>> being parsed.
>>> Why do you need the map to be persistent in the kernel address space?
>>> You can always map a small table, but what if the table size is very big?
>>>
>>>>
>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>
>>>> I don't think so -- I have explained why.  It does different thing.
>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>
>>> [Lv Zheng]
>>> Just let me ask one more question.
>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>> You can check drivers/acpi/tbxxx.c.
>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>
>>>>> [Lv Zheng]
>>>>> One more thing is:
>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>> early_acpi_os_unmap_memory(),
>>>>> then it implies that your driver does have a defect.
>>>>
>>>> I still don't understand what defect, sorry.
>>> [Lv Zheng]
>>> If you can't ensure this sequence for using the data tables:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structure
>>> 3. unmap the table
>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>
>> Exactly.
> [Lv Zheng] 
> So it looks to me:
> Changing __init to __ref here is entirely not acceptable.
> This API should stay being invoked during early stage.
> Otherwise, it may leave us untrackable code that maps tables during early stage and leaks maps to the late stage.
> If Linux contains such kind of code, I'm afraid, it will become impossible to introduce acpi_put_table() to clean up the mappings.
> Because when acpi_put_table() is called during the late stage to free a map acquired during the early stage, it then obviously will end up with panic.

Can you please sugggest a common method to access ACPI tables that
works both before *and* after acpi_gbl_permanent_mmap is set and __init code
is removed?

> Thanks and best regards
> -Lv
> 
>> The central problem here is the way Aleksey is trying to hookup a console.
>>
>> What should be happening in this series is:
>> 1. early map SPCR
>> 2. parse the SPCR table
>> 3. call add_preferred_console() to add the SPCR console to the console table
>> 4. unmap SPCR
>>
>> This trivial and unobtrusive method would already have a 8250 console
>> running via SPCR. I've already pointed this out in previous reviews.
>>
>> Further, the above method *will be required anyway* for the DBG2 table to
>> start an earlycon, which I've already pointed out in previous reviews.
>>
>> Then to enable amba-pl011 console via ACPI, add a console match() method
>> similar to the 8250 console match() method, univ8250_console_match().
>>
>> FWIW, PCI earlycon + console support was already submitted once before but
>> never picked up by GregKH. I think I'll just grab that and re-submit so
>> you would know what to emit for console options in the
>> add_preferred_console().
>>
>>
>> Regards,
>> Peter Hurley
>>
>>
>>>>> There is an early bootup requirement in Linux.
>>>>> Maps acquired during the early stage should be freed by the driver during
>> the
>>>> early stage.
>>>>> And the driver should re-acquire the memory map after booting.
>>>>
>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>> that code can be
>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of
>> for
>>>> example 8250 console)
>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>> registers a console),
>>>> We just can not tell if the received table pointer should or sould not be freed
>>>> with early_memunmap()
>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>> acpi_gbl_permanent_mmap,
>>>> but that's all too low level.
>>> [Lv Zheng]
>>> The driver should make sure that:
>>> Map/unmap is paired during early stage.
>>> For late stage, it should be another pair of map/unmap.
>>>
>>>>
>>>> Another option, as you describe, is to get this pointer early, don't free it
>>> [Lv Zheng]
>>> I mean you should free it early.
>>>
>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>> early_acpi_os_unmap_memory(), that's
>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>> persistent
>>>> pointer to the table.  The problem with it is that we can not just watch
>>>> acpi_gbl_permanent_mmap
>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap
>> is
>>>> not good as it probably is
>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>> Or I probably miss what you are suggesting.
>>>>
>>> [Lv Zheng]
>>> I mean, you should:
>>> During early stage:
>>> acpi_os_map_memory()
>>> Parse the table.
>>> acpi_os_unmap_memory().
>>>
>>>>> This is because, during early bootup stage, there are only limited slots
>>>> available for drivers to map memory.
>>>>> So by changing __init to __ref here, you probably will hide many such
>> defects.
>>>>
>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>> BTW, exactly the same thing is done in the beginning of
>>>> acpi_os_unmap_memory() and than's ok,
>>>> that function is __ref.
>>>>
>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>
>>>> Could you please tell me where I am wrong?  I still don't understand your
>> point.
>>> [Lv Zheng]
>>> But anyway, the defect should be in ACPI subsystem core.
>>> The cause should be the API itself - acpi_get_table().
>>>
>>> So I agree you can use early_acpi_os_unmap_memory() during the period the
>> root causes are not cleaned up.
>>> But the bottom line is: the driver need to ensure that
>> early_acpi_os_unmap_memory() is always invoked.
>>> As long as you can ensure this, I don't have objections for deploying
>> early_acpi_os_unmap_memory()  for now.
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>> Thank you
>>>> Aleksey Makarov
>>>>
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thanks and best regards
>>>>>> -Lv
>>>>>>
>>>>>>>
>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>> ---
>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>
>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>> acpi_size size)
>>>>>>>  }
>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>
>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
>> acpi_size
>>>>>> size)
>>>>>>> +/*
>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>> + */
>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
>> acpi_size
>>>>>> size)
>>>>>>>  {
>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>> --
>>>>>>> 2.7.1
>>>>>>>
>>>>>>> --
>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>>> --
>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-19 11:02                 ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-19 11:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lv,

On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> Hi,
> 
>> From: Peter Hurley [mailto:peter at hurleysoftware.com]
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> Hi Lv,
>>>>
>>>> Thank you for review.
>>>>
>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>
>>>> [..]
>>>>
>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>> set.
>>>>>>>
>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>
>>>>>>> We need this function to be non-__init because we need access to
>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>> Console
>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>> does.
>>>>>> [Lv Zheng]
>>>>>> Why don't you use another API instead of
>> early_acpi_os_unmap_memory()
>>>> in
>>>>>> case you want to unmap things in any cases.
>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>
>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>
>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>> acpi_get_table_with_size()
>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>> should be unmapped.
>>>>
>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>> unmapped
>>>> at all.
>>>>
>>> [Lv Zheng]
>>> This statement is wrong, this should be:
>>> As long as there is a __reference__ to the mapped table, the pointer should
>> not be unmapped.
>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>> So your argument is wrong from very first point.
>>>
>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>> acpi_gbl_permanent_mmap.
>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>> had
>>>> been set,
>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>> and got that oops).
>>>>
>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>> early_acpi_os_unmap_memory()
>>>> match perfectly.
>>> [Lv Zheng]
>>> I don't think so.
>>> For definition block tables, we know for sure there will always be references,
>> until "Unload" opcode is invoked by the AML interpreter.
>>> But for the data tables, OSPMs should use them in this way:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structures
>>> 3. unmap the table
>>> This helps to shrink virtual memory address space usages.
>>>
>>> So from this point of view, all data tables should be unmapped right after
>> being parsed.
>>> Why do you need the map to be persistent in the kernel address space?
>>> You can always map a small table, but what if the table size is very big?
>>>
>>>>
>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>
>>>> I don't think so -- I have explained why.  It does different thing.
>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>
>>> [Lv Zheng]
>>> Just let me ask one more question.
>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>> You can check drivers/acpi/tbxxx.c.
>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>
>>>>> [Lv Zheng]
>>>>> One more thing is:
>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>> early_acpi_os_unmap_memory(),
>>>>> then it implies that your driver does have a defect.
>>>>
>>>> I still don't understand what defect, sorry.
>>> [Lv Zheng]
>>> If you can't ensure this sequence for using the data tables:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structure
>>> 3. unmap the table
>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>
>> Exactly.
> [Lv Zheng] 
> So it looks to me:
> Changing __init to __ref here is entirely not acceptable.
> This API should stay being invoked during early stage.
> Otherwise, it may leave us untrackable code that maps tables during early stage and leaks maps to the late stage.
> If Linux contains such kind of code, I'm afraid, it will become impossible to introduce acpi_put_table() to clean up the mappings.
> Because when acpi_put_table() is called during the late stage to free a map acquired during the early stage, it then obviously will end up with panic.

Can you please sugggest a common method to access ACPI tables that
works both before *and* after acpi_gbl_permanent_mmap is set and __init code
is removed?

> Thanks and best regards
> -Lv
> 
>> The central problem here is the way Aleksey is trying to hookup a console.
>>
>> What should be happening in this series is:
>> 1. early map SPCR
>> 2. parse the SPCR table
>> 3. call add_preferred_console() to add the SPCR console to the console table
>> 4. unmap SPCR
>>
>> This trivial and unobtrusive method would already have a 8250 console
>> running via SPCR. I've already pointed this out in previous reviews.
>>
>> Further, the above method *will be required anyway* for the DBG2 table to
>> start an earlycon, which I've already pointed out in previous reviews.
>>
>> Then to enable amba-pl011 console via ACPI, add a console match() method
>> similar to the 8250 console match() method, univ8250_console_match().
>>
>> FWIW, PCI earlycon + console support was already submitted once before but
>> never picked up by GregKH. I think I'll just grab that and re-submit so
>> you would know what to emit for console options in the
>> add_preferred_console().
>>
>>
>> Regards,
>> Peter Hurley
>>
>>
>>>>> There is an early bootup requirement in Linux.
>>>>> Maps acquired during the early stage should be freed by the driver during
>> the
>>>> early stage.
>>>>> And the driver should re-acquire the memory map after booting.
>>>>
>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>> that code can be
>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of
>> for
>>>> example 8250 console)
>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>> registers a console),
>>>> We just can not tell if the received table pointer should or sould not be freed
>>>> with early_memunmap()
>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>> acpi_gbl_permanent_mmap,
>>>> but that's all too low level.
>>> [Lv Zheng]
>>> The driver should make sure that:
>>> Map/unmap is paired during early stage.
>>> For late stage, it should be another pair of map/unmap.
>>>
>>>>
>>>> Another option, as you describe, is to get this pointer early, don't free it
>>> [Lv Zheng]
>>> I mean you should free it early.
>>>
>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>> early_acpi_os_unmap_memory(), that's
>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>> persistent
>>>> pointer to the table.  The problem with it is that we can not just watch
>>>> acpi_gbl_permanent_mmap
>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap
>> is
>>>> not good as it probably is
>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>> Or I probably miss what you are suggesting.
>>>>
>>> [Lv Zheng]
>>> I mean, you should:
>>> During early stage:
>>> acpi_os_map_memory()
>>> Parse the table.
>>> acpi_os_unmap_memory().
>>>
>>>>> This is because, during early bootup stage, there are only limited slots
>>>> available for drivers to map memory.
>>>>> So by changing __init to __ref here, you probably will hide many such
>> defects.
>>>>
>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>> BTW, exactly the same thing is done in the beginning of
>>>> acpi_os_unmap_memory() and than's ok,
>>>> that function is __ref.
>>>>
>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>
>>>> Could you please tell me where I am wrong?  I still don't understand your
>> point.
>>> [Lv Zheng]
>>> But anyway, the defect should be in ACPI subsystem core.
>>> The cause should be the API itself - acpi_get_table().
>>>
>>> So I agree you can use early_acpi_os_unmap_memory() during the period the
>> root causes are not cleaned up.
>>> But the bottom line is: the driver need to ensure that
>> early_acpi_os_unmap_memory() is always invoked.
>>> As long as you can ensure this, I don't have objections for deploying
>> early_acpi_os_unmap_memory()  for now.
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>> Thank you
>>>> Aleksey Makarov
>>>>
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thanks and best regards
>>>>>> -Lv
>>>>>>
>>>>>>>
>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>> ---
>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>
>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>> acpi_size size)
>>>>>>>  }
>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>
>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
>> acpi_size
>>>>>> size)
>>>>>>> +/*
>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>> + */
>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
>> acpi_size
>>>>>> size)
>>>>>>>  {
>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>> --
>>>>>>> 2.7.1
>>>>>>>
>>>>>>> --
>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>> the body of a message to majordomo at vger.kernel.org
>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>>> --
>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>> the body of a message to majordomo at vger.kernel.org
>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-19 10:42               ` Aleksey Makarov
  (?)
@ 2016-02-19 15:25                 ` Peter Hurley
  -1 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-19 15:25 UTC (permalink / raw)
  To: Aleksey Makarov, Zheng, Lv, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
> Hi Peter,
> 
> Thank you for review.
> 
> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> Hi Lv,
>>>>
>>>> Thank you for review.
>>>>
>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>
>>>> [..]
>>>>
>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>> set.
>>>>>>>
>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>
>>>>>>> We need this function to be non-__init because we need access to
>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>> does.
>>>>>> [Lv Zheng]
>>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>>> in
>>>>>> case you want to unmap things in any cases.
>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>
>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>
>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>> acpi_get_table_with_size()
>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>> should be unmapped.
>>>>
>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>>> at all.
>>>>
>>> [Lv Zheng] 
>>> This statement is wrong, this should be:
>>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>> So your argument is wrong from very first point.
>>>
>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>> acpi_gbl_permanent_mmap.
>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>>> been set,
>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>> and got that oops).
>>>>
>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>> early_acpi_os_unmap_memory()
>>>> match perfectly.
>>> [Lv Zheng] 
>>> I don't think so.
>>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>>> But for the data tables, OSPMs should use them in this way:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structures
>>> 3. unmap the table
>>> This helps to shrink virtual memory address space usages.
>>>
>>> So from this point of view, all data tables should be unmapped right after being parsed.
>>> Why do you need the map to be persistent in the kernel address space?
>>> You can always map a small table, but what if the table size is very big?
>>>
>>>>
>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>
>>>> I don't think so -- I have explained why.  It does different thing.
>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>
>>> [Lv Zheng] 
>>> Just let me ask one more question.
>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>> You can check drivers/acpi/tbxxx.c.
>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>
>>>>> [Lv Zheng]
>>>>> One more thing is:
>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>> early_acpi_os_unmap_memory(),
>>>>> then it implies that your driver does have a defect.
>>>>
>>>> I still don't understand what defect, sorry.
>>> [Lv Zheng] 
>>> If you can't ensure this sequence for using the data tables:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structure
>>> 3. unmap the table
>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>
>> Exactly.
>>
>> The central problem here is the way Aleksey is trying to hookup a console.
>>
>> What should be happening in this series is:
>> 1. early map SPCR
>> 2. parse the SPCR table
>> 3. call add_preferred_console() to add the SPCR console to the console table
>> 4. unmap SPCR
> 
> This does not work.  
> 
> SPCR specifies address of the console, but add_preferred_console() accepts
> name of console and its index.  There are no general method to translate address
> to name at such an early stage.


	add_preferred_console(uart, 0, "io,0x3f8,115200");

This will start a console with the 8250 driver. I've already pointed
this out to you in an earlier review. This is what existing firmware
already does.

This is also the method you will use to start an earlycon from the
DBG2 table, by additionally calling setup_earlycon().


> There is another reason why I prefer to parse SPCR each time a console is registered.
> Some consoles can be registered very early in the initialization process and
> we have to be sure add_preferred_console() is called before that.

However, since you're not adding a preferred console until uart driver
loads, there may already be a preferred console selected and running.

This leads to weird issues like duplicated output on the serial console
when an earlycon is disabled by the dummy VGA/FB console then the
serial console starts and reprints the entire boot log on the same
terminal the earlycon already printed.

Better just to parse both the DBG2 and SPCR tables before or at
early param, and add_preferred_consoles then.


> Of course, I could just parse it once and cache the results, but
> this still requires accessing SPCR before acpi_gbl_permanent_mmap
> is set *or* after that.
> 
>> This trivial and unobtrusive method would already have a 8250 console
>> running via SPCR. I've already pointed this out in previous reviews.
>>
>> Further, the above method *will be required anyway* for the DBG2 table to
>> start an earlycon, which I've already pointed out in previous reviews.
>>
>> Then to enable amba-pl011 console via ACPI, add a console match() method
>> similar to the 8250 console match() method, univ8250_console_match().
> 
> So are you suggesting a separate method for each possible console?
> This is not acceptable.

All 1 of them???

The 8250 driver already does this, so no work for you there.

That leaves you needing to write a trivial match() method for just
the amba-pl011 driver.


> Do you suggest making up separate new name (like "uart" for 8250) for each type
> of conosole SPCR can specify?

These are the documented names of the earlycons, which you'll be using
when you add the DGB2 table parsing.


>> FWIW, PCI earlycon + console support was already submitted once before but
>> never picked up by GregKH. I think I'll just grab that and re-submit so
>> you would know what to emit for console options in the add_preferred_console().
> 
> Please do.  Or just send a link to to that submission.

Ok, will dig through and find it.

> Do you mean the Leif Lindholm's patches:

No.

> https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm@linaro.org
> 
> He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
> (I just match SPCR against data that struct uart_port already has)
> 2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
> And that's why his submission is RFC: he had troubles with the order of initialization.
> 
> Thank you
> Aleksey Makarov
> 
>> Regards,
>> Peter Hurley
>>
>>
>>>>> There is an early bootup requirement in Linux.
>>>>> Maps acquired during the early stage should be freed by the driver during the
>>>> early stage.
>>>>> And the driver should re-acquire the memory map after booting.
>>>>
>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>> that code can be
>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>>> example 8250 console)
>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>> registers a console),
>>>> We just can not tell if the received table pointer should or sould not be freed
>>>> with early_memunmap()
>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>> acpi_gbl_permanent_mmap,
>>>> but that's all too low level.
>>> [Lv Zheng] 
>>> The driver should make sure that:
>>> Map/unmap is paired during early stage.
>>> For late stage, it should be another pair of map/unmap.
>>>
>>>>
>>>> Another option, as you describe, is to get this pointer early, don't free it
>>> [Lv Zheng] 
>>> I mean you should free it early.
>>>
>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>> early_acpi_os_unmap_memory(), that's
>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>> persistent
>>>> pointer to the table.  The problem with it is that we can not just watch
>>>> acpi_gbl_permanent_mmap
>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>>> not good as it probably is
>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>> Or I probably miss what you are suggesting.
>>>>
>>> [Lv Zheng] 
>>> I mean, you should:
>>> During early stage:
>>> acpi_os_map_memory()
>>> Parse the table.
>>> acpi_os_unmap_memory().
>>>
>>>>> This is because, during early bootup stage, there are only limited slots
>>>> available for drivers to map memory.
>>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>>
>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>> BTW, exactly the same thing is done in the beginning of
>>>> acpi_os_unmap_memory() and than's ok,
>>>> that function is __ref.
>>>>
>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>
>>>> Could you please tell me where I am wrong?  I still don't understand your point.
>>> [Lv Zheng] 
>>> But anyway, the defect should be in ACPI subsystem core.
>>> The cause should be the API itself - acpi_get_table().
>>>
>>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>> Thank you
>>>> Aleksey Makarov
>>>>
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thanks and best regards
>>>>>> -Lv
>>>>>>
>>>>>>>
>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>> ---
>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>
>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>> acpi_size size)
>>>>>>>  }
>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>
>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>> size)
>>>>>>> +/*
>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>> + */
>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>> size)
>>>>>>>  {
>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>> --
>>>>>>> 2.7.1



^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-19 15:25                 ` Peter Hurley
  0 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-19 15:25 UTC (permalink / raw)
  To: Aleksey Makarov, Zheng, Lv, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
> Hi Peter,
> 
> Thank you for review.
> 
> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> Hi Lv,
>>>>
>>>> Thank you for review.
>>>>
>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>
>>>> [..]
>>>>
>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>> set.
>>>>>>>
>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>
>>>>>>> We need this function to be non-__init because we need access to
>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>> does.
>>>>>> [Lv Zheng]
>>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>>> in
>>>>>> case you want to unmap things in any cases.
>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>
>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>
>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>> acpi_get_table_with_size()
>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>> should be unmapped.
>>>>
>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>>> at all.
>>>>
>>> [Lv Zheng] 
>>> This statement is wrong, this should be:
>>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>> So your argument is wrong from very first point.
>>>
>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>> acpi_gbl_permanent_mmap.
>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>>> been set,
>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>> and got that oops).
>>>>
>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>> early_acpi_os_unmap_memory()
>>>> match perfectly.
>>> [Lv Zheng] 
>>> I don't think so.
>>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>>> But for the data tables, OSPMs should use them in this way:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structures
>>> 3. unmap the table
>>> This helps to shrink virtual memory address space usages.
>>>
>>> So from this point of view, all data tables should be unmapped right after being parsed.
>>> Why do you need the map to be persistent in the kernel address space?
>>> You can always map a small table, but what if the table size is very big?
>>>
>>>>
>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>
>>>> I don't think so -- I have explained why.  It does different thing.
>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>
>>> [Lv Zheng] 
>>> Just let me ask one more question.
>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>> You can check drivers/acpi/tbxxx.c.
>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>
>>>>> [Lv Zheng]
>>>>> One more thing is:
>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>> early_acpi_os_unmap_memory(),
>>>>> then it implies that your driver does have a defect.
>>>>
>>>> I still don't understand what defect, sorry.
>>> [Lv Zheng] 
>>> If you can't ensure this sequence for using the data tables:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structure
>>> 3. unmap the table
>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>
>> Exactly.
>>
>> The central problem here is the way Aleksey is trying to hookup a console.
>>
>> What should be happening in this series is:
>> 1. early map SPCR
>> 2. parse the SPCR table
>> 3. call add_preferred_console() to add the SPCR console to the console table
>> 4. unmap SPCR
> 
> This does not work.  
> 
> SPCR specifies address of the console, but add_preferred_console() accepts
> name of console and its index.  There are no general method to translate address
> to name at such an early stage.


	add_preferred_console(uart, 0, "io,0x3f8,115200");

This will start a console with the 8250 driver. I've already pointed
this out to you in an earlier review. This is what existing firmware
already does.

This is also the method you will use to start an earlycon from the
DBG2 table, by additionally calling setup_earlycon().


> There is another reason why I prefer to parse SPCR each time a console is registered.
> Some consoles can be registered very early in the initialization process and
> we have to be sure add_preferred_console() is called before that.

However, since you're not adding a preferred console until uart driver
loads, there may already be a preferred console selected and running.

This leads to weird issues like duplicated output on the serial console
when an earlycon is disabled by the dummy VGA/FB console then the
serial console starts and reprints the entire boot log on the same
terminal the earlycon already printed.

Better just to parse both the DBG2 and SPCR tables before or at
early param, and add_preferred_consoles then.


> Of course, I could just parse it once and cache the results, but
> this still requires accessing SPCR before acpi_gbl_permanent_mmap
> is set *or* after that.
> 
>> This trivial and unobtrusive method would already have a 8250 console
>> running via SPCR. I've already pointed this out in previous reviews.
>>
>> Further, the above method *will be required anyway* for the DBG2 table to
>> start an earlycon, which I've already pointed out in previous reviews.
>>
>> Then to enable amba-pl011 console via ACPI, add a console match() method
>> similar to the 8250 console match() method, univ8250_console_match().
> 
> So are you suggesting a separate method for each possible console?
> This is not acceptable.

All 1 of them???

The 8250 driver already does this, so no work for you there.

That leaves you needing to write a trivial match() method for just
the amba-pl011 driver.


> Do you suggest making up separate new name (like "uart" for 8250) for each type
> of conosole SPCR can specify?

These are the documented names of the earlycons, which you'll be using
when you add the DGB2 table parsing.


>> FWIW, PCI earlycon + console support was already submitted once before but
>> never picked up by GregKH. I think I'll just grab that and re-submit so
>> you would know what to emit for console options in the add_preferred_console().
> 
> Please do.  Or just send a link to to that submission.

Ok, will dig through and find it.

> Do you mean the Leif Lindholm's patches:

No.

> https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm@linaro.org
> 
> He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
> (I just match SPCR against data that struct uart_port already has)
> 2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
> And that's why his submission is RFC: he had troubles with the order of initialization.
> 
> Thank you
> Aleksey Makarov
> 
>> Regards,
>> Peter Hurley
>>
>>
>>>>> There is an early bootup requirement in Linux.
>>>>> Maps acquired during the early stage should be freed by the driver during the
>>>> early stage.
>>>>> And the driver should re-acquire the memory map after booting.
>>>>
>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>> that code can be
>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>>> example 8250 console)
>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>> registers a console),
>>>> We just can not tell if the received table pointer should or sould not be freed
>>>> with early_memunmap()
>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>> acpi_gbl_permanent_mmap,
>>>> but that's all too low level.
>>> [Lv Zheng] 
>>> The driver should make sure that:
>>> Map/unmap is paired during early stage.
>>> For late stage, it should be another pair of map/unmap.
>>>
>>>>
>>>> Another option, as you describe, is to get this pointer early, don't free it
>>> [Lv Zheng] 
>>> I mean you should free it early.
>>>
>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>> early_acpi_os_unmap_memory(), that's
>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>> persistent
>>>> pointer to the table.  The problem with it is that we can not just watch
>>>> acpi_gbl_permanent_mmap
>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>>> not good as it probably is
>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>> Or I probably miss what you are suggesting.
>>>>
>>> [Lv Zheng] 
>>> I mean, you should:
>>> During early stage:
>>> acpi_os_map_memory()
>>> Parse the table.
>>> acpi_os_unmap_memory().
>>>
>>>>> This is because, during early bootup stage, there are only limited slots
>>>> available for drivers to map memory.
>>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>>
>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>> BTW, exactly the same thing is done in the beginning of
>>>> acpi_os_unmap_memory() and than's ok,
>>>> that function is __ref.
>>>>
>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>
>>>> Could you please tell me where I am wrong?  I still don't understand your point.
>>> [Lv Zheng] 
>>> But anyway, the defect should be in ACPI subsystem core.
>>> The cause should be the API itself - acpi_get_table().
>>>
>>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>> Thank you
>>>> Aleksey Makarov
>>>>
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thanks and best regards
>>>>>> -Lv
>>>>>>
>>>>>>>
>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>> ---
>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>
>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>> acpi_size size)
>>>>>>>  }
>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>
>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>> size)
>>>>>>> +/*
>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>> + */
>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>> size)
>>>>>>>  {
>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>> --
>>>>>>> 2.7.1

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-19 15:25                 ` Peter Hurley
  0 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-19 15:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
> Hi Peter,
> 
> Thank you for review.
> 
> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> Hi Lv,
>>>>
>>>> Thank you for review.
>>>>
>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>
>>>> [..]
>>>>
>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>> set.
>>>>>>>
>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>
>>>>>>> We need this function to be non-__init because we need access to
>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>> does.
>>>>>> [Lv Zheng]
>>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>>> in
>>>>>> case you want to unmap things in any cases.
>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>
>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>
>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>> acpi_get_table_with_size()
>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>> should be unmapped.
>>>>
>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>>> at all.
>>>>
>>> [Lv Zheng] 
>>> This statement is wrong, this should be:
>>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>> So your argument is wrong from very first point.
>>>
>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>> acpi_gbl_permanent_mmap.
>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>>> been set,
>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>> and got that oops).
>>>>
>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>> early_acpi_os_unmap_memory()
>>>> match perfectly.
>>> [Lv Zheng] 
>>> I don't think so.
>>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>>> But for the data tables, OSPMs should use them in this way:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structures
>>> 3. unmap the table
>>> This helps to shrink virtual memory address space usages.
>>>
>>> So from this point of view, all data tables should be unmapped right after being parsed.
>>> Why do you need the map to be persistent in the kernel address space?
>>> You can always map a small table, but what if the table size is very big?
>>>
>>>>
>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>
>>>> I don't think so -- I have explained why.  It does different thing.
>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>
>>> [Lv Zheng] 
>>> Just let me ask one more question.
>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>> You can check drivers/acpi/tbxxx.c.
>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>
>>>>> [Lv Zheng]
>>>>> One more thing is:
>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>> early_acpi_os_unmap_memory(),
>>>>> then it implies that your driver does have a defect.
>>>>
>>>> I still don't understand what defect, sorry.
>>> [Lv Zheng] 
>>> If you can't ensure this sequence for using the data tables:
>>> 1. map the table
>>> 2. parse the table and convert it to OS specific structure
>>> 3. unmap the table
>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>
>> Exactly.
>>
>> The central problem here is the way Aleksey is trying to hookup a console.
>>
>> What should be happening in this series is:
>> 1. early map SPCR
>> 2. parse the SPCR table
>> 3. call add_preferred_console() to add the SPCR console to the console table
>> 4. unmap SPCR
> 
> This does not work.  
> 
> SPCR specifies address of the console, but add_preferred_console() accepts
> name of console and its index.  There are no general method to translate address
> to name at such an early stage.


	add_preferred_console(uart, 0, "io,0x3f8,115200");

This will start a console with the 8250 driver. I've already pointed
this out to you in an earlier review. This is what existing firmware
already does.

This is also the method you will use to start an earlycon from the
DBG2 table, by additionally calling setup_earlycon().


> There is another reason why I prefer to parse SPCR each time a console is registered.
> Some consoles can be registered very early in the initialization process and
> we have to be sure add_preferred_console() is called before that.

However, since you're not adding a preferred console until uart driver
loads, there may already be a preferred console selected and running.

This leads to weird issues like duplicated output on the serial console
when an earlycon is disabled by the dummy VGA/FB console then the
serial console starts and reprints the entire boot log on the same
terminal the earlycon already printed.

Better just to parse both the DBG2 and SPCR tables before or at
early param, and add_preferred_consoles then.


> Of course, I could just parse it once and cache the results, but
> this still requires accessing SPCR before acpi_gbl_permanent_mmap
> is set *or* after that.
> 
>> This trivial and unobtrusive method would already have a 8250 console
>> running via SPCR. I've already pointed this out in previous reviews.
>>
>> Further, the above method *will be required anyway* for the DBG2 table to
>> start an earlycon, which I've already pointed out in previous reviews.
>>
>> Then to enable amba-pl011 console via ACPI, add a console match() method
>> similar to the 8250 console match() method, univ8250_console_match().
> 
> So are you suggesting a separate method for each possible console?
> This is not acceptable.

All 1 of them???

The 8250 driver already does this, so no work for you there.

That leaves you needing to write a trivial match() method for just
the amba-pl011 driver.


> Do you suggest making up separate new name (like "uart" for 8250) for each type
> of conosole SPCR can specify?

These are the documented names of the earlycons, which you'll be using
when you add the DGB2 table parsing.


>> FWIW, PCI earlycon + console support was already submitted once before but
>> never picked up by GregKH. I think I'll just grab that and re-submit so
>> you would know what to emit for console options in the add_preferred_console().
> 
> Please do.  Or just send a link to to that submission.

Ok, will dig through and find it.

> Do you mean the Leif Lindholm's patches:

No.

> https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm at linaro.org
> 
> He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
> (I just match SPCR against data that struct uart_port already has)
> 2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
> And that's why his submission is RFC: he had troubles with the order of initialization.
> 
> Thank you
> Aleksey Makarov
> 
>> Regards,
>> Peter Hurley
>>
>>
>>>>> There is an early bootup requirement in Linux.
>>>>> Maps acquired during the early stage should be freed by the driver during the
>>>> early stage.
>>>>> And the driver should re-acquire the memory map after booting.
>>>>
>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>> that code can be
>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>>> example 8250 console)
>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>> registers a console),
>>>> We just can not tell if the received table pointer should or sould not be freed
>>>> with early_memunmap()
>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>> acpi_gbl_permanent_mmap,
>>>> but that's all too low level.
>>> [Lv Zheng] 
>>> The driver should make sure that:
>>> Map/unmap is paired during early stage.
>>> For late stage, it should be another pair of map/unmap.
>>>
>>>>
>>>> Another option, as you describe, is to get this pointer early, don't free it
>>> [Lv Zheng] 
>>> I mean you should free it early.
>>>
>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>> early_acpi_os_unmap_memory(), that's
>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>> persistent
>>>> pointer to the table.  The problem with it is that we can not just watch
>>>> acpi_gbl_permanent_mmap
>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>>> not good as it probably is
>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>> Or I probably miss what you are suggesting.
>>>>
>>> [Lv Zheng] 
>>> I mean, you should:
>>> During early stage:
>>> acpi_os_map_memory()
>>> Parse the table.
>>> acpi_os_unmap_memory().
>>>
>>>>> This is because, during early bootup stage, there are only limited slots
>>>> available for drivers to map memory.
>>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>>
>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>> BTW, exactly the same thing is done in the beginning of
>>>> acpi_os_unmap_memory() and than's ok,
>>>> that function is __ref.
>>>>
>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>
>>>> Could you please tell me where I am wrong?  I still don't understand your point.
>>> [Lv Zheng] 
>>> But anyway, the defect should be in ACPI subsystem core.
>>> The cause should be the API itself - acpi_get_table().
>>>
>>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>> Thank you
>>>> Aleksey Makarov
>>>>
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thanks and best regards
>>>>>> -Lv
>>>>>>
>>>>>>>
>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>> ---
>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>
>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>> acpi_size size)
>>>>>>>  }
>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>
>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>> size)
>>>>>>> +/*
>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>> + */
>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>> size)
>>>>>>>  {
>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>> --
>>>>>>> 2.7.1

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
  2016-02-19 10:47       ` Aleksey Makarov
@ 2016-02-19 16:13         ` Peter Hurley
  -1 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-19 16:13 UTC (permalink / raw)
  To: Aleksey Makarov, linux-acpi
  Cc: Russell King, Graeme Gregory, Greg Kroah-Hartman,
	Rafael J . Wysocki, linux-kernel, Leif Lindholm,
	Christopher Covington, linux-serial, Jiri Slaby, Al Stone,
	linux-arm-kernel, Len Brown

On 02/19/2016 02:47 AM, Aleksey Makarov wrote:
> Hi Peter,
> 
> Thank you for review.
> 
> On 02/19/2016 01:19 AM, Peter Hurley wrote:
>> On 02/15/2016 10:05 AM, Aleksey Makarov wrote:
> 
> [..]
> 
>>> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
>>> index a126a60..459ab54 100644
>>> --- a/drivers/tty/serial/serial_core.c
>>> +++ b/drivers/tty/serial/serial_core.c
>>> @@ -34,6 +34,7 @@
>>>  #include <linux/serial_core.h>
>>>  #include <linux/delay.h>
>>>  #include <linux/mutex.h>
>>> +#include <linux/acpi.h>
>>>  
>>>  #include <asm/irq.h>
>>>  #include <asm/uaccess.h>
>>> @@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>>>  		spin_lock_init(&uport->lock);
>>>  		lockdep_set_class(&uport->lock, &port_lock_key);
>>>  	}
>>> -	if (uport->cons && uport->dev)
>>> -		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
>>> +
>>> +	/*
>>> +	 * Support both open FW and ACPI access to console definitions.
>>> +	 * Both of_console_check() and acpi_console_check() will call
>>> +	 * add_preferred_console() if a console definition is found.
>>> +	 */
>>> +	if (uport->cons && uport->dev) {
>>> +		if (!acpi_console_check(uport))
>>> +			of_console_check(uport->dev->of_node, uport->cons->name,
>>> +					 uport->line);
>>
>> of_console_check() is not a good model for enabling a console.
>> It's a hack with several shortcomings (and bugs) that is tolerated here
>> because of its broad applicability to a wide range of platforms and drivers.
> 
> It's definitely not the best code I saw 

> but there is no bugs.

I pointed out just one of the problems with adding a preferred console
late in the boot cycle (eg, at uart driver load) in the other patch review.


>> I specifically added console matching to enable exactly this kind of
>> console-selection-via-firmware. Please use that facility.
> 
> I described why this does not work (except you insist on having 
> new made up names for all types of SPCR consoles) in the reply to another your message.

They're not "new made up names".

They're the documented names of earlycons, which you'd know if you
researched how you're going to start an earlycon with the DBG2 table
like I suggested in previous reviews.

And I explained in the other patch review exactly how it works.

Regards,
Peter Hurley


>>> +	}
>>>  
>>>  	uart_configure_port(drv, state, uport);
>>>  
>>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>>> index 06ed7e5..ea0c297 100644
>>> --- a/include/linux/acpi.h
>>> +++ b/include/linux/acpi.h
>>> @@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
>>>  #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
>>>  #endif
>>>  
>>> +struct uart_port;
>>> +#ifdef CONFIG_ACPI_SPCR_TABLE
>>> +bool acpi_console_check(struct uart_port *uport);
>>> +#else
>>> +static inline bool acpi_console_check(struct uart_port *uport)
>>> +{
>>> +	return FALSE;
>>> +}
>>> +#endif
>>> +
>>>  #endif	/*_LINUX_ACPI_H*/
>>>
>>


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
@ 2016-02-19 16:13         ` Peter Hurley
  0 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-19 16:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/19/2016 02:47 AM, Aleksey Makarov wrote:
> Hi Peter,
> 
> Thank you for review.
> 
> On 02/19/2016 01:19 AM, Peter Hurley wrote:
>> On 02/15/2016 10:05 AM, Aleksey Makarov wrote:
> 
> [..]
> 
>>> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
>>> index a126a60..459ab54 100644
>>> --- a/drivers/tty/serial/serial_core.c
>>> +++ b/drivers/tty/serial/serial_core.c
>>> @@ -34,6 +34,7 @@
>>>  #include <linux/serial_core.h>
>>>  #include <linux/delay.h>
>>>  #include <linux/mutex.h>
>>> +#include <linux/acpi.h>
>>>  
>>>  #include <asm/irq.h>
>>>  #include <asm/uaccess.h>
>>> @@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>>>  		spin_lock_init(&uport->lock);
>>>  		lockdep_set_class(&uport->lock, &port_lock_key);
>>>  	}
>>> -	if (uport->cons && uport->dev)
>>> -		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
>>> +
>>> +	/*
>>> +	 * Support both open FW and ACPI access to console definitions.
>>> +	 * Both of_console_check() and acpi_console_check() will call
>>> +	 * add_preferred_console() if a console definition is found.
>>> +	 */
>>> +	if (uport->cons && uport->dev) {
>>> +		if (!acpi_console_check(uport))
>>> +			of_console_check(uport->dev->of_node, uport->cons->name,
>>> +					 uport->line);
>>
>> of_console_check() is not a good model for enabling a console.
>> It's a hack with several shortcomings (and bugs) that is tolerated here
>> because of its broad applicability to a wide range of platforms and drivers.
> 
> It's definitely not the best code I saw 

> but there is no bugs.

I pointed out just one of the problems with adding a preferred console
late in the boot cycle (eg, at uart driver load) in the other patch review.


>> I specifically added console matching to enable exactly this kind of
>> console-selection-via-firmware. Please use that facility.
> 
> I described why this does not work (except you insist on having 
> new made up names for all types of SPCR consoles) in the reply to another your message.

They're not "new made up names".

They're the documented names of earlycons, which you'd know if you
researched how you're going to start an earlycon with the DBG2 table
like I suggested in previous reviews.

And I explained in the other patch review exactly how it works.

Regards,
Peter Hurley


>>> +	}
>>>  
>>>  	uart_configure_port(drv, state, uport);
>>>  
>>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>>> index 06ed7e5..ea0c297 100644
>>> --- a/include/linux/acpi.h
>>> +++ b/include/linux/acpi.h
>>> @@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
>>>  #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
>>>  #endif
>>>  
>>> +struct uart_port;
>>> +#ifdef CONFIG_ACPI_SPCR_TABLE
>>> +bool acpi_console_check(struct uart_port *uport);
>>> +#else
>>> +static inline bool acpi_console_check(struct uart_port *uport)
>>> +{
>>> +	return FALSE;
>>> +}
>>> +#endif
>>> +
>>>  #endif	/*_LINUX_ACPI_H*/
>>>
>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-19 15:25                 ` Peter Hurley
  (?)
@ 2016-02-19 17:20                   ` Christopher Covington
  -1 siblings, 0 replies; 86+ messages in thread
From: Christopher Covington @ 2016-02-19 17:20 UTC (permalink / raw)
  To: Peter Hurley, Aleksey Makarov, Zheng, Lv, linux-acpi, harba
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Len Brown



On February 19, 2016 10:25:50 AM EST, Peter Hurley <peter@hurleysoftware.com> wrote:
>On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>> Hi Peter,
>> 
>> Thank you for review.
>> 
>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>> Hi,
>>>>
>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>> early_acpi_os_unmap_memory()
>>>>>
>>>>> Hi Lv,
>>>>>
>>>>> Thank you for review.
>>>>>
>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>
>>>>> [..]
>>>>>
>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it
>calls
>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>not
>>>>> set.
>>>>>>>>
>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from
>anywhere
>>>>>>>>
>>>>>>>> We need this function to be non-__init because we need access
>to
>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>Console
>>>>>>>> Redirection) table is needed each time a new console is
>registered.
>>>>>>>> It can be quite early (console_initcall) or when a module is
>inserted.
>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>> the pointer should be unmapped.  This is exactly what this
>function
>>>>>>>> does.
>>>>>>> [Lv Zheng]
>>>>>>> Why don't you use another API instead of
>early_acpi_os_unmap_memory()
>>>>> in
>>>>>>> case you want to unmap things in any cases.
>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>
>>>>> As far as I understand, there exist two steps in ACPI
>initialization:
>>>>>
>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>> acpi_get_table_with_size()
>>>>>    are mapped by early_memremap().  If a subsystem gets such a
>pointer it
>>>>> should be unmapped.
>>>>>
>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>unmapped
>>>>> at all.
>>>>>
>>>> [Lv Zheng] 
>>>> This statement is wrong, this should be:
>>>> As long as there is a __reference__ to the mapped table, the
>pointer should not be unmapped.
>>>> In fact, we have a series to introduce acpi_put_table() to achieve
>this.
>>>> So your argument is wrong from very first point.
>>>>
>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>> acpi_gbl_permanent_mmap.
>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>had
>>>>> been set,
>>>>> it would have tried to free that pointer with an oops (actually, I
>checked that
>>>>> and got that oops).
>>>>>
>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>> early_acpi_os_unmap_memory()
>>>>> match perfectly.
>>>> [Lv Zheng] 
>>>> I don't think so.
>>>> For definition block tables, we know for sure there will always be
>references, until "Unload" opcode is invoked by the AML interpreter.
>>>> But for the data tables, OSPMs should use them in this way:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structures
>>>> 3. unmap the table
>>>> This helps to shrink virtual memory address space usages.
>>>>
>>>> So from this point of view, all data tables should be unmapped
>right after being parsed.
>>>> Why do you need the map to be persistent in the kernel address
>space?
>>>> You can always map a small table, but what if the table size is
>very big?
>>>>
>>>>>
>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>
>>>>> I don't think so -- I have explained why.  It does different
>thing.
>>>>> Probably it (and/or other functions in that api) should be
>renamed.
>>>>>
>>>> [Lv Zheng] 
>>>> Just let me ask one more question.
>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>> You can check drivers/acpi/tbxxx.c.
>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>
>>>>>> [Lv Zheng]
>>>>>> One more thing is:
>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>instead of
>>>>> early_acpi_os_unmap_memory(),
>>>>>> then it implies that your driver does have a defect.
>>>>>
>>>>> I still don't understand what defect, sorry.
>>>> [Lv Zheng] 
>>>> If you can't ensure this sequence for using the data tables:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structure
>>>> 3. unmap the table
>>>> It implies there is a bug in the driver or a bug in the ACPI
>subsystem core.
>>>
>>> Exactly.
>>>
>>> The central problem here is the way Aleksey is trying to hookup a
>console.
>>>
>>> What should be happening in this series is:
>>> 1. early map SPCR
>>> 2. parse the SPCR table
>>> 3. call add_preferred_console() to add the SPCR console to the
>console table
>>> 4. unmap SPCR
>> 
>> This does not work.  
>> 
>> SPCR specifies address of the console, but add_preferred_console()
>accepts
>> name of console and its index.  There are no general method to
>translate address
>> to name at such an early stage.
>
>
>	add_preferred_console(uart, 0, "io,0x3f8,115200");
>
>This will start a console with the 8250 driver. I've already pointed
>this out to you in an earlier review. This is what existing firmware
>already does.
>
>This is also the method you will use to start an earlycon from the
>DBG2 table, by additionally calling setup_earlycon().

Can the device specified in DBG2 be used for both earlycon and KGDB? If it can only be used for one, let's make sure the choice of earlycon vs KGDB is intentional rather than accidental.

Thanks,
Christopher Covington

-- 
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

Sent from my Snapdragon powered Android device with K-9 Mail. Please excuse my brevity.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-19 17:20                   ` Christopher Covington
  0 siblings, 0 replies; 86+ messages in thread
From: Christopher Covington @ 2016-02-19 17:20 UTC (permalink / raw)
  To: Peter Hurley, Aleksey Makarov, Zheng, Lv, linux-acpi, harba
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Len Brown



On February 19, 2016 10:25:50 AM EST, Peter Hurley <peter@hurleysoftware.com> wrote:
>On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>> Hi Peter,
>> 
>> Thank you for review.
>> 
>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>> Hi,
>>>>
>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>> early_acpi_os_unmap_memory()
>>>>>
>>>>> Hi Lv,
>>>>>
>>>>> Thank you for review.
>>>>>
>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>
>>>>> [..]
>>>>>
>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it
>calls
>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>not
>>>>> set.
>>>>>>>>
>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from
>anywhere
>>>>>>>>
>>>>>>>> We need this function to be non-__init because we need access
>to
>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>Console
>>>>>>>> Redirection) table is needed each time a new console is
>registered.
>>>>>>>> It can be quite early (console_initcall) or when a module is
>inserted.
>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>> the pointer should be unmapped.  This is exactly what this
>function
>>>>>>>> does.
>>>>>>> [Lv Zheng]
>>>>>>> Why don't you use another API instead of
>early_acpi_os_unmap_memory()
>>>>> in
>>>>>>> case you want to unmap things in any cases.
>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>
>>>>> As far as I understand, there exist two steps in ACPI
>initialization:
>>>>>
>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>> acpi_get_table_with_size()
>>>>>    are mapped by early_memremap().  If a subsystem gets such a
>pointer it
>>>>> should be unmapped.
>>>>>
>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>unmapped
>>>>> at all.
>>>>>
>>>> [Lv Zheng] 
>>>> This statement is wrong, this should be:
>>>> As long as there is a __reference__ to the mapped table, the
>pointer should not be unmapped.
>>>> In fact, we have a series to introduce acpi_put_table() to achieve
>this.
>>>> So your argument is wrong from very first point.
>>>>
>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>> acpi_gbl_permanent_mmap.
>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>had
>>>>> been set,
>>>>> it would have tried to free that pointer with an oops (actually, I
>checked that
>>>>> and got that oops).
>>>>>
>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>> early_acpi_os_unmap_memory()
>>>>> match perfectly.
>>>> [Lv Zheng] 
>>>> I don't think so.
>>>> For definition block tables, we know for sure there will always be
>references, until "Unload" opcode is invoked by the AML interpreter.
>>>> But for the data tables, OSPMs should use them in this way:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structures
>>>> 3. unmap the table
>>>> This helps to shrink virtual memory address space usages.
>>>>
>>>> So from this point of view, all data tables should be unmapped
>right after being parsed.
>>>> Why do you need the map to be persistent in the kernel address
>space?
>>>> You can always map a small table, but what if the table size is
>very big?
>>>>
>>>>>
>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>
>>>>> I don't think so -- I have explained why.  It does different
>thing.
>>>>> Probably it (and/or other functions in that api) should be
>renamed.
>>>>>
>>>> [Lv Zheng] 
>>>> Just let me ask one more question.
>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>> You can check drivers/acpi/tbxxx.c.
>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>
>>>>>> [Lv Zheng]
>>>>>> One more thing is:
>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>instead of
>>>>> early_acpi_os_unmap_memory(),
>>>>>> then it implies that your driver does have a defect.
>>>>>
>>>>> I still don't understand what defect, sorry.
>>>> [Lv Zheng] 
>>>> If you can't ensure this sequence for using the data tables:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structure
>>>> 3. unmap the table
>>>> It implies there is a bug in the driver or a bug in the ACPI
>subsystem core.
>>>
>>> Exactly.
>>>
>>> The central problem here is the way Aleksey is trying to hookup a
>console.
>>>
>>> What should be happening in this series is:
>>> 1. early map SPCR
>>> 2. parse the SPCR table
>>> 3. call add_preferred_console() to add the SPCR console to the
>console table
>>> 4. unmap SPCR
>> 
>> This does not work.  
>> 
>> SPCR specifies address of the console, but add_preferred_console()
>accepts
>> name of console and its index.  There are no general method to
>translate address
>> to name at such an early stage.
>
>
>	add_preferred_console(uart, 0, "io,0x3f8,115200");
>
>This will start a console with the 8250 driver. I've already pointed
>this out to you in an earlier review. This is what existing firmware
>already does.
>
>This is also the method you will use to start an earlycon from the
>DBG2 table, by additionally calling setup_earlycon().

Can the device specified in DBG2 be used for both earlycon and KGDB? If it can only be used for one, let's make sure the choice of earlycon vs KGDB is intentional rather than accidental.

Thanks,
Christopher Covington

-- 
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

Sent from my Snapdragon powered Android device with K-9 Mail. Please excuse my brevity.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-19 17:20                   ` Christopher Covington
  0 siblings, 0 replies; 86+ messages in thread
From: Christopher Covington @ 2016-02-19 17:20 UTC (permalink / raw)
  To: linux-arm-kernel



On February 19, 2016 10:25:50 AM EST, Peter Hurley <peter@hurleysoftware.com> wrote:
>On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>> Hi Peter,
>> 
>> Thank you for review.
>> 
>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>> Hi,
>>>>
>>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>> early_acpi_os_unmap_memory()
>>>>>
>>>>> Hi Lv,
>>>>>
>>>>> Thank you for review.
>>>>>
>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>
>>>>> [..]
>>>>>
>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it
>calls
>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>not
>>>>> set.
>>>>>>>>
>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from
>anywhere
>>>>>>>>
>>>>>>>> We need this function to be non-__init because we need access
>to
>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>Console
>>>>>>>> Redirection) table is needed each time a new console is
>registered.
>>>>>>>> It can be quite early (console_initcall) or when a module is
>inserted.
>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>> the pointer should be unmapped.  This is exactly what this
>function
>>>>>>>> does.
>>>>>>> [Lv Zheng]
>>>>>>> Why don't you use another API instead of
>early_acpi_os_unmap_memory()
>>>>> in
>>>>>>> case you want to unmap things in any cases.
>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>
>>>>> As far as I understand, there exist two steps in ACPI
>initialization:
>>>>>
>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>> acpi_get_table_with_size()
>>>>>    are mapped by early_memremap().  If a subsystem gets such a
>pointer it
>>>>> should be unmapped.
>>>>>
>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>unmapped
>>>>> at all.
>>>>>
>>>> [Lv Zheng] 
>>>> This statement is wrong, this should be:
>>>> As long as there is a __reference__ to the mapped table, the
>pointer should not be unmapped.
>>>> In fact, we have a series to introduce acpi_put_table() to achieve
>this.
>>>> So your argument is wrong from very first point.
>>>>
>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>> acpi_gbl_permanent_mmap.
>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>had
>>>>> been set,
>>>>> it would have tried to free that pointer with an oops (actually, I
>checked that
>>>>> and got that oops).
>>>>>
>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>> early_acpi_os_unmap_memory()
>>>>> match perfectly.
>>>> [Lv Zheng] 
>>>> I don't think so.
>>>> For definition block tables, we know for sure there will always be
>references, until "Unload" opcode is invoked by the AML interpreter.
>>>> But for the data tables, OSPMs should use them in this way:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structures
>>>> 3. unmap the table
>>>> This helps to shrink virtual memory address space usages.
>>>>
>>>> So from this point of view, all data tables should be unmapped
>right after being parsed.
>>>> Why do you need the map to be persistent in the kernel address
>space?
>>>> You can always map a small table, but what if the table size is
>very big?
>>>>
>>>>>
>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>
>>>>> I don't think so -- I have explained why.  It does different
>thing.
>>>>> Probably it (and/or other functions in that api) should be
>renamed.
>>>>>
>>>> [Lv Zheng] 
>>>> Just let me ask one more question.
>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>> You can check drivers/acpi/tbxxx.c.
>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>
>>>>>> [Lv Zheng]
>>>>>> One more thing is:
>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>instead of
>>>>> early_acpi_os_unmap_memory(),
>>>>>> then it implies that your driver does have a defect.
>>>>>
>>>>> I still don't understand what defect, sorry.
>>>> [Lv Zheng] 
>>>> If you can't ensure this sequence for using the data tables:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structure
>>>> 3. unmap the table
>>>> It implies there is a bug in the driver or a bug in the ACPI
>subsystem core.
>>>
>>> Exactly.
>>>
>>> The central problem here is the way Aleksey is trying to hookup a
>console.
>>>
>>> What should be happening in this series is:
>>> 1. early map SPCR
>>> 2. parse the SPCR table
>>> 3. call add_preferred_console() to add the SPCR console to the
>console table
>>> 4. unmap SPCR
>> 
>> This does not work.  
>> 
>> SPCR specifies address of the console, but add_preferred_console()
>accepts
>> name of console and its index.  There are no general method to
>translate address
>> to name at such an early stage.
>
>
>	add_preferred_console(uart, 0, "io,0x3f8,115200");
>
>This will start a console with the 8250 driver. I've already pointed
>this out to you in an earlier review. This is what existing firmware
>already does.
>
>This is also the method you will use to start an earlycon from the
>DBG2 table, by additionally calling setup_earlycon().

Can the device specified in DBG2 be used for both earlycon and KGDB? If it can only be used for one, let's make sure the choice of earlycon vs KGDB is intentional rather than accidental.

Thanks,
Christopher Covington

-- 
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

Sent from my Snapdragon powered Android device with K-9 Mail. Please excuse my brevity.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
  2016-02-15 18:05   ` Aleksey Makarov
  (?)
@ 2016-02-21  9:42     ` Yury Norov
  -1 siblings, 0 replies; 86+ messages in thread
From: Yury Norov @ 2016-02-21  9:42 UTC (permalink / raw)
  To: Aleksey Makarov
  Cc: Russell King, Graeme Gregory, Greg Kroah-Hartman,
	Rafael J . Wysocki, linux-kernel, Leif Lindholm, linux-acpi,
	Christopher Covington, linux-serial, Jiri Slaby, Al Stone,
	linux-arm-kernel, Len Brown

On Mon, Feb 15, 2016 at 09:05:26PM +0300, Aleksey Makarov wrote:
> 'ARM Server Base Boot Requiremets' [1] mentions SPCR (Serial Port
> Console Redirection Table) [2] as a mandatory ACPI table that
> specifies the configuration of serial console.
> 
> Parse this table and check if any registered console match the
> description.  If it does, enable that console.
> 
> Introduce a new function acpi_console_check().  At the uart port
> registration, this function checks if the ACPI SPCR table specifies
> its argument of type struct uart_port to be a console
> and if so calls add_preferred_console().
> 
> [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
> [2] http://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx
> 
> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> ---
>  drivers/acpi/Kconfig             |  3 ++
>  drivers/acpi/Makefile            |  1 +
>  drivers/acpi/spcr.c              | 97 ++++++++++++++++++++++++++++++++++++++++
>  drivers/tty/serial/serial_core.c | 14 +++++-
>  include/linux/acpi.h             | 10 +++++
>  5 files changed, 123 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/acpi/spcr.c
> 
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 65fb483..5611eb6 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -77,6 +77,9 @@ config ACPI_DEBUGGER_USER
>  
>  endif
>  
> +config ACPI_SPCR_TABLE
> +	bool
> +
>  config ACPI_SLEEP
>  	bool
>  	depends on SUSPEND || HIBERNATION
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 346101c..708b143 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -81,6 +81,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
>  obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
> +obj-$(CONFIG_ACPI_SPCR_TABLE)	+= spcr.o
>  obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
>  
>  # processor has its own "processor." module_param namespace
> diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
> new file mode 100644
> index 0000000..a1eca91
> --- /dev/null
> +++ b/drivers/acpi/spcr.c
> @@ -0,0 +1,97 @@
> +/*
> + * Copyright (c) 2012, Intel Corporation
> + * Copyright (c) 2015, Red Hat, Inc.
> + * Copyright (c) 2015, 2016 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#define pr_fmt(fmt) "ACPI: SPCR: " fmt
> +
> +#include <linux/acpi.h>
> +#include <linux/console.h>
> +#include <linux/kernel.h>
> +#include <linux/serial_core.h>
> +
> +static int acpi_table_parse_spcr(int (*handler)(struct acpi_table_spcr *table,
> +						void *data), void *data)
> +{
> +	struct acpi_table_spcr *table = NULL;
Hi Alexey,

Few minor comments...

Are you sure you need thin initialization?

> +	acpi_size table_size;
> +	acpi_status status;
> +	int err;
> +
> +	status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0,
> +					  (struct acpi_table_header **)&table,
> +					  &table_size);
> +
> +	if (ACPI_FAILURE(status))
> +		return -ENODEV;
> +
> +	err = handler(table, data);
> +
> +	early_acpi_os_unmap_memory(table, table_size);
> +
> +	return err;
> +}
> +
> +static int spcr_table_handler_check(struct acpi_table_spcr *table, void *data)

The name of function is not clear for me.
You're not only checking here, but also
adding console. 

> +{
> +	struct uart_port *uport = data;
> +	char *options;
> +
> +	if (table->header.revision < 2)
> +		return -EOPNOTSUPP;
> +
> +	switch (table->baud_rate) {

You don't need 'options' if your big condition returns false,
so you can evaluate it inside conditional block.

> +	case 3:
> +		options = "9600";
> +		break;
> +	case 4:
> +		options = "19200";
> +		break;
> +	case 6:
> +		options = "57600";
> +		break;
> +	case 7:
> +		options = "115200";
> +		break;
> +	default:
> +		options = "";
> +		break;

'break' isnot needed here

> +	}
> +
> +	if ((table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY &&

Nitpick: just for better readability, I'd split it onto a set of
separated checks:

        foo() {
                if (!cond1)
                        return 0;

                if (!cond2)
                        return 0;
                ...

                switch () {
                case 1:
                        ...
                case 2:
                        ...
                case 3:
                        ...
                default:
                        ...
                }
                
                return 1;
        }

> +	     table->serial_port.address == (u64)uport->mapbase) ||
> +	    (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_IO &&
> +	     table->serial_port.address == (u64)uport->iobase)) {
> +		pr_info("adding preferred console [%s%d]\n", uport->cons->name,
> +			uport->line);
> +		add_preferred_console(uport->cons->name, uport->line, options);
> +		return 1;
> +
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * acpi_console_check - Check if uart matches the console specified by SPCR.
> + *
> + * @uport:	uart port to check
> + *
> + * This function checks if the ACPI SPCR table specifies @uport to be a console
> + * and if so calls add_preferred_console()
> + *
> + * Return: a non-error value if the console matches.
> + */
> +bool acpi_console_check(struct uart_port *uport)
> +{
> +	if (acpi_disabled || console_set_on_cmdline)
> +		return false;
> +
> +	return acpi_table_parse_spcr(spcr_table_handler_check, uport) > 0;
> +}
> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> index a126a60..459ab54 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -34,6 +34,7 @@
>  #include <linux/serial_core.h>
>  #include <linux/delay.h>
>  #include <linux/mutex.h>
> +#include <linux/acpi.h>
>  
>  #include <asm/irq.h>
>  #include <asm/uaccess.h>
> @@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>  		spin_lock_init(&uport->lock);
>  		lockdep_set_class(&uport->lock, &port_lock_key);
>  	}
> -	if (uport->cons && uport->dev)
> -		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
> +
> +	/*
> +	 * Support both open FW and ACPI access to console definitions.
> +	 * Both of_console_check() and acpi_console_check() will call
> +	 * add_preferred_console() if a console definition is found.
> +	 */
> +	if (uport->cons && uport->dev) {
> +		if (!acpi_console_check(uport))
> +			of_console_check(uport->dev->of_node, uport->cons->name,
> +					 uport->line);
> +	}
>  
>  	uart_configure_port(drv, state, uport);
>  
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 06ed7e5..ea0c297 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
>  #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
>  #endif
>  
> +struct uart_port;
> +#ifdef CONFIG_ACPI_SPCR_TABLE
> +bool acpi_console_check(struct uart_port *uport);
> +#else
> +static inline bool acpi_console_check(struct uart_port *uport)
> +{
> +	return FALSE;
> +}
> +#endif
> +
>  #endif	/*_LINUX_ACPI_H*/
> -- 
> 2.7.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
@ 2016-02-21  9:42     ` Yury Norov
  0 siblings, 0 replies; 86+ messages in thread
From: Yury Norov @ 2016-02-21  9:42 UTC (permalink / raw)
  To: Aleksey Makarov
  Cc: linux-acpi, Russell King, Graeme Gregory, Greg Kroah-Hartman,
	Rafael J . Wysocki, linux-kernel, Leif Lindholm,
	Christopher Covington, linux-serial, Jiri Slaby, Al Stone,
	linux-arm-kernel, Len Brown

On Mon, Feb 15, 2016 at 09:05:26PM +0300, Aleksey Makarov wrote:
> 'ARM Server Base Boot Requiremets' [1] mentions SPCR (Serial Port
> Console Redirection Table) [2] as a mandatory ACPI table that
> specifies the configuration of serial console.
> 
> Parse this table and check if any registered console match the
> description.  If it does, enable that console.
> 
> Introduce a new function acpi_console_check().  At the uart port
> registration, this function checks if the ACPI SPCR table specifies
> its argument of type struct uart_port to be a console
> and if so calls add_preferred_console().
> 
> [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
> [2] http://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx
> 
> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> ---
>  drivers/acpi/Kconfig             |  3 ++
>  drivers/acpi/Makefile            |  1 +
>  drivers/acpi/spcr.c              | 97 ++++++++++++++++++++++++++++++++++++++++
>  drivers/tty/serial/serial_core.c | 14 +++++-
>  include/linux/acpi.h             | 10 +++++
>  5 files changed, 123 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/acpi/spcr.c
> 
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 65fb483..5611eb6 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -77,6 +77,9 @@ config ACPI_DEBUGGER_USER
>  
>  endif
>  
> +config ACPI_SPCR_TABLE
> +	bool
> +
>  config ACPI_SLEEP
>  	bool
>  	depends on SUSPEND || HIBERNATION
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 346101c..708b143 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -81,6 +81,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
>  obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
> +obj-$(CONFIG_ACPI_SPCR_TABLE)	+= spcr.o
>  obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
>  
>  # processor has its own "processor." module_param namespace
> diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
> new file mode 100644
> index 0000000..a1eca91
> --- /dev/null
> +++ b/drivers/acpi/spcr.c
> @@ -0,0 +1,97 @@
> +/*
> + * Copyright (c) 2012, Intel Corporation
> + * Copyright (c) 2015, Red Hat, Inc.
> + * Copyright (c) 2015, 2016 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#define pr_fmt(fmt) "ACPI: SPCR: " fmt
> +
> +#include <linux/acpi.h>
> +#include <linux/console.h>
> +#include <linux/kernel.h>
> +#include <linux/serial_core.h>
> +
> +static int acpi_table_parse_spcr(int (*handler)(struct acpi_table_spcr *table,
> +						void *data), void *data)
> +{
> +	struct acpi_table_spcr *table = NULL;
Hi Alexey,

Few minor comments...

Are you sure you need thin initialization?

> +	acpi_size table_size;
> +	acpi_status status;
> +	int err;
> +
> +	status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0,
> +					  (struct acpi_table_header **)&table,
> +					  &table_size);
> +
> +	if (ACPI_FAILURE(status))
> +		return -ENODEV;
> +
> +	err = handler(table, data);
> +
> +	early_acpi_os_unmap_memory(table, table_size);
> +
> +	return err;
> +}
> +
> +static int spcr_table_handler_check(struct acpi_table_spcr *table, void *data)

The name of function is not clear for me.
You're not only checking here, but also
adding console. 

> +{
> +	struct uart_port *uport = data;
> +	char *options;
> +
> +	if (table->header.revision < 2)
> +		return -EOPNOTSUPP;
> +
> +	switch (table->baud_rate) {

You don't need 'options' if your big condition returns false,
so you can evaluate it inside conditional block.

> +	case 3:
> +		options = "9600";
> +		break;
> +	case 4:
> +		options = "19200";
> +		break;
> +	case 6:
> +		options = "57600";
> +		break;
> +	case 7:
> +		options = "115200";
> +		break;
> +	default:
> +		options = "";
> +		break;

'break' isnot needed here

> +	}
> +
> +	if ((table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY &&

Nitpick: just for better readability, I'd split it onto a set of
separated checks:

        foo() {
                if (!cond1)
                        return 0;

                if (!cond2)
                        return 0;
                ...

                switch () {
                case 1:
                        ...
                case 2:
                        ...
                case 3:
                        ...
                default:
                        ...
                }
                
                return 1;
        }

> +	     table->serial_port.address == (u64)uport->mapbase) ||
> +	    (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_IO &&
> +	     table->serial_port.address == (u64)uport->iobase)) {
> +		pr_info("adding preferred console [%s%d]\n", uport->cons->name,
> +			uport->line);
> +		add_preferred_console(uport->cons->name, uport->line, options);
> +		return 1;
> +
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * acpi_console_check - Check if uart matches the console specified by SPCR.
> + *
> + * @uport:	uart port to check
> + *
> + * This function checks if the ACPI SPCR table specifies @uport to be a console
> + * and if so calls add_preferred_console()
> + *
> + * Return: a non-error value if the console matches.
> + */
> +bool acpi_console_check(struct uart_port *uport)
> +{
> +	if (acpi_disabled || console_set_on_cmdline)
> +		return false;
> +
> +	return acpi_table_parse_spcr(spcr_table_handler_check, uport) > 0;
> +}
> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> index a126a60..459ab54 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -34,6 +34,7 @@
>  #include <linux/serial_core.h>
>  #include <linux/delay.h>
>  #include <linux/mutex.h>
> +#include <linux/acpi.h>
>  
>  #include <asm/irq.h>
>  #include <asm/uaccess.h>
> @@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>  		spin_lock_init(&uport->lock);
>  		lockdep_set_class(&uport->lock, &port_lock_key);
>  	}
> -	if (uport->cons && uport->dev)
> -		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
> +
> +	/*
> +	 * Support both open FW and ACPI access to console definitions.
> +	 * Both of_console_check() and acpi_console_check() will call
> +	 * add_preferred_console() if a console definition is found.
> +	 */
> +	if (uport->cons && uport->dev) {
> +		if (!acpi_console_check(uport))
> +			of_console_check(uport->dev->of_node, uport->cons->name,
> +					 uport->line);
> +	}
>  
>  	uart_configure_port(drv, state, uport);
>  
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 06ed7e5..ea0c297 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
>  #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
>  #endif
>  
> +struct uart_port;
> +#ifdef CONFIG_ACPI_SPCR_TABLE
> +bool acpi_console_check(struct uart_port *uport);
> +#else
> +static inline bool acpi_console_check(struct uart_port *uport)
> +{
> +	return FALSE;
> +}
> +#endif
> +
>  #endif	/*_LINUX_ACPI_H*/
> -- 
> 2.7.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
@ 2016-02-21  9:42     ` Yury Norov
  0 siblings, 0 replies; 86+ messages in thread
From: Yury Norov @ 2016-02-21  9:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Feb 15, 2016 at 09:05:26PM +0300, Aleksey Makarov wrote:
> 'ARM Server Base Boot Requiremets' [1] mentions SPCR (Serial Port
> Console Redirection Table) [2] as a mandatory ACPI table that
> specifies the configuration of serial console.
> 
> Parse this table and check if any registered console match the
> description.  If it does, enable that console.
> 
> Introduce a new function acpi_console_check().  At the uart port
> registration, this function checks if the ACPI SPCR table specifies
> its argument of type struct uart_port to be a console
> and if so calls add_preferred_console().
> 
> [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
> [2] http://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx
> 
> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> ---
>  drivers/acpi/Kconfig             |  3 ++
>  drivers/acpi/Makefile            |  1 +
>  drivers/acpi/spcr.c              | 97 ++++++++++++++++++++++++++++++++++++++++
>  drivers/tty/serial/serial_core.c | 14 +++++-
>  include/linux/acpi.h             | 10 +++++
>  5 files changed, 123 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/acpi/spcr.c
> 
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 65fb483..5611eb6 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -77,6 +77,9 @@ config ACPI_DEBUGGER_USER
>  
>  endif
>  
> +config ACPI_SPCR_TABLE
> +	bool
> +
>  config ACPI_SLEEP
>  	bool
>  	depends on SUSPEND || HIBERNATION
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 346101c..708b143 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -81,6 +81,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
>  obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
> +obj-$(CONFIG_ACPI_SPCR_TABLE)	+= spcr.o
>  obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
>  
>  # processor has its own "processor." module_param namespace
> diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
> new file mode 100644
> index 0000000..a1eca91
> --- /dev/null
> +++ b/drivers/acpi/spcr.c
> @@ -0,0 +1,97 @@
> +/*
> + * Copyright (c) 2012, Intel Corporation
> + * Copyright (c) 2015, Red Hat, Inc.
> + * Copyright (c) 2015, 2016 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#define pr_fmt(fmt) "ACPI: SPCR: " fmt
> +
> +#include <linux/acpi.h>
> +#include <linux/console.h>
> +#include <linux/kernel.h>
> +#include <linux/serial_core.h>
> +
> +static int acpi_table_parse_spcr(int (*handler)(struct acpi_table_spcr *table,
> +						void *data), void *data)
> +{
> +	struct acpi_table_spcr *table = NULL;
Hi Alexey,

Few minor comments...

Are you sure you need thin initialization?

> +	acpi_size table_size;
> +	acpi_status status;
> +	int err;
> +
> +	status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0,
> +					  (struct acpi_table_header **)&table,
> +					  &table_size);
> +
> +	if (ACPI_FAILURE(status))
> +		return -ENODEV;
> +
> +	err = handler(table, data);
> +
> +	early_acpi_os_unmap_memory(table, table_size);
> +
> +	return err;
> +}
> +
> +static int spcr_table_handler_check(struct acpi_table_spcr *table, void *data)

The name of function is not clear for me.
You're not only checking here, but also
adding console. 

> +{
> +	struct uart_port *uport = data;
> +	char *options;
> +
> +	if (table->header.revision < 2)
> +		return -EOPNOTSUPP;
> +
> +	switch (table->baud_rate) {

You don't need 'options' if your big condition returns false,
so you can evaluate it inside conditional block.

> +	case 3:
> +		options = "9600";
> +		break;
> +	case 4:
> +		options = "19200";
> +		break;
> +	case 6:
> +		options = "57600";
> +		break;
> +	case 7:
> +		options = "115200";
> +		break;
> +	default:
> +		options = "";
> +		break;

'break' isnot needed here

> +	}
> +
> +	if ((table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY &&

Nitpick: just for better readability, I'd split it onto a set of
separated checks:

        foo() {
                if (!cond1)
                        return 0;

                if (!cond2)
                        return 0;
                ...

                switch () {
                case 1:
                        ...
                case 2:
                        ...
                case 3:
                        ...
                default:
                        ...
                }
                
                return 1;
        }

> +	     table->serial_port.address == (u64)uport->mapbase) ||
> +	    (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_IO &&
> +	     table->serial_port.address == (u64)uport->iobase)) {
> +		pr_info("adding preferred console [%s%d]\n", uport->cons->name,
> +			uport->line);
> +		add_preferred_console(uport->cons->name, uport->line, options);
> +		return 1;
> +
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * acpi_console_check - Check if uart matches the console specified by SPCR.
> + *
> + * @uport:	uart port to check
> + *
> + * This function checks if the ACPI SPCR table specifies @uport to be a console
> + * and if so calls add_preferred_console()
> + *
> + * Return: a non-error value if the console matches.
> + */
> +bool acpi_console_check(struct uart_port *uport)
> +{
> +	if (acpi_disabled || console_set_on_cmdline)
> +		return false;
> +
> +	return acpi_table_parse_spcr(spcr_table_handler_check, uport) > 0;
> +}
> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> index a126a60..459ab54 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -34,6 +34,7 @@
>  #include <linux/serial_core.h>
>  #include <linux/delay.h>
>  #include <linux/mutex.h>
> +#include <linux/acpi.h>
>  
>  #include <asm/irq.h>
>  #include <asm/uaccess.h>
> @@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>  		spin_lock_init(&uport->lock);
>  		lockdep_set_class(&uport->lock, &port_lock_key);
>  	}
> -	if (uport->cons && uport->dev)
> -		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
> +
> +	/*
> +	 * Support both open FW and ACPI access to console definitions.
> +	 * Both of_console_check() and acpi_console_check() will call
> +	 * add_preferred_console() if a console definition is found.
> +	 */
> +	if (uport->cons && uport->dev) {
> +		if (!acpi_console_check(uport))
> +			of_console_check(uport->dev->of_node, uport->cons->name,
> +					 uport->line);
> +	}
>  
>  	uart_configure_port(drv, state, uport);
>  
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 06ed7e5..ea0c297 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
>  #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
>  #endif
>  
> +struct uart_port;
> +#ifdef CONFIG_ACPI_SPCR_TABLE
> +bool acpi_console_check(struct uart_port *uport);
> +#else
> +static inline bool acpi_console_check(struct uart_port *uport)
> +{
> +	return FALSE;
> +}
> +#endif
> +
>  #endif	/*_LINUX_ACPI_H*/
> -- 
> 2.7.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-19 11:02                 ` Aleksey Makarov
  (?)
@ 2016-02-22  2:24                   ` Zheng, Lv
  -1 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-22  2:24 UTC (permalink / raw)
  To: Aleksey Makarov, Peter Hurley, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi,

> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi Lv,
> 
> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>> early_acpi_os_unmap_memory()
> >>>>
> >>>> Hi Lv,
> >>>>
> >>>> Thank you for review.
> >>>>
> >>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>>>
> >>>> [..]
> >>>>
> >>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
> not
> >>>> set.
> >>>>>>>
> >>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>>>
> >>>>>>> We need this function to be non-__init because we need access to
> >>>>>>> some tables at unpredictable time--it may be before or after
> >>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> >> Console
> >>>>>>> Redirection) table is needed each time a new console is registered.
> >>>>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>>>> does.
> >>>>>> [Lv Zheng]
> >>>>>> Why don't you use another API instead of
> >> early_acpi_os_unmap_memory()
> >>>> in
> >>>>>> case you want to unmap things in any cases.
> >>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>>>
> >>>> As far as I understand, there exist two steps in ACPI initialization:
> >>>>
> >>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >>>> acpi_get_table_with_size()
> >>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
> >>>> should be unmapped.
> >>>>
> >>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> >> unmapped
> >>>> at all.
> >>>>
> >>> [Lv Zheng]
> >>> This statement is wrong, this should be:
> >>> As long as there is a __reference__ to the mapped table, the pointer should
> >> not be unmapped.
> >>> In fact, we have a series to introduce acpi_put_table() to achieve this.
> >>> So your argument is wrong from very first point.
> >>>
> >>>> That exactly what early_acpi_os_unmap_memory() does--it checks
> >>>> acpi_gbl_permanent_mmap.
> >>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
> >> had
> >>>> been set,
> >>>> it would have tried to free that pointer with an oops (actually, I checked
> that
> >>>> and got that oops).
> >>>>
> >>>> So using acpi_os_unmap_memory() is not an option here, but
> >>>> early_acpi_os_unmap_memory()
> >>>> match perfectly.
> >>> [Lv Zheng]
> >>> I don't think so.
> >>> For definition block tables, we know for sure there will always be
> references,
> >> until "Unload" opcode is invoked by the AML interpreter.
> >>> But for the data tables, OSPMs should use them in this way:
> >>> 1. map the table
> >>> 2. parse the table and convert it to OS specific structures
> >>> 3. unmap the table
> >>> This helps to shrink virtual memory address space usages.
> >>>
> >>> So from this point of view, all data tables should be unmapped right after
> >> being parsed.
> >>> Why do you need the map to be persistent in the kernel address space?
> >>> You can always map a small table, but what if the table size is very big?
> >>>
> >>>>
> >>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>>>
> >>>> I don't think so -- I have explained why.  It does different thing.
> >>>> Probably it (and/or other functions in that api) should be renamed.
> >>>>
> >>> [Lv Zheng]
> >>> Just let me ask one more question.
> >>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> >>> How ACPICA can work with just acpi_os_unmap_memory()?
> >>> You can check drivers/acpi/tbxxx.c.
> >>> Especially: acpi_tb_release_temp_table() and the code invoking it.
> >>>
> >>>>> [Lv Zheng]
> >>>>> One more thing is:
> >>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead
> of
> >>>> early_acpi_os_unmap_memory(),
> >>>>> then it implies that your driver does have a defect.
> >>>>
> >>>> I still don't understand what defect, sorry.
> >>> [Lv Zheng]
> >>> If you can't ensure this sequence for using the data tables:
> >>> 1. map the table
> >>> 2. parse the table and convert it to OS specific structure
> >>> 3. unmap the table
> >>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> >>
> >> Exactly.
> > [Lv Zheng]
> > So it looks to me:
> > Changing __init to __ref here is entirely not acceptable.
> > This API should stay being invoked during early stage.
> > Otherwise, it may leave us untrackable code that maps tables during early
> stage and leaks maps to the late stage.
> > If Linux contains such kind of code, I'm afraid, it will become impossible to
> introduce acpi_put_table() to clean up the mappings.
> > Because when acpi_put_table() is called during the late stage to free a map
> acquired during the early stage, it then obviously will end up with panic.
> 
> Can you please sugggest a common method to access ACPI tables that
> works both before *and* after acpi_gbl_permanent_mmap is set and __init
> code
> is removed?
[Lv Zheng] 
Do not change __init for now.

Currently you should:
1. before acpi_gbl_permanent_mmap is set:
acpi_get_table_with_size()
parse the table
early_acpi_os_unmap_memory()
Do your driver early stuff here

2. after acpi_gbl_permanent_mmap is set:
acpi_get_table()
Parse the table
Do your driver late stuff here
<- note there is no API now being an inverse of acpi_get_table().

Besides, I'm about to insert error messages between 1 and 2.
If an early map is not release, error message will be prompted to the developers.

And if you don't follow the above rules, it mean you are trying to lay a mine, waiting for me to step on it.
That's why this change is entirely not acceptable.

I'm about to send out the cleanup series in 1 week, and will Cc you.
You can rebase your code on top of the cleanup series.

Thanks and best regards
-Lv

> 
> > Thanks and best regards
> > -Lv
> >
> >> The central problem here is the way Aleksey is trying to hookup a console.
> >>
> >> What should be happening in this series is:
> >> 1. early map SPCR
> >> 2. parse the SPCR table
> >> 3. call add_preferred_console() to add the SPCR console to the console
> table
> >> 4. unmap SPCR
> >>
> >> This trivial and unobtrusive method would already have a 8250 console
> >> running via SPCR. I've already pointed this out in previous reviews.
> >>
> >> Further, the above method *will be required anyway* for the DBG2 table to
> >> start an earlycon, which I've already pointed out in previous reviews.
> >>
> >> Then to enable amba-pl011 console via ACPI, add a console match() method
> >> similar to the 8250 console match() method, univ8250_console_match().
> >>
> >> FWIW, PCI earlycon + console support was already submitted once before
> but
> >> never picked up by GregKH. I think I'll just grab that and re-submit so
> >> you would know what to emit for console options in the
> >> add_preferred_console().
> >>
> >>
> >> Regards,
> >> Peter Hurley
> >>
> >>
> >>>>> There is an early bootup requirement in Linux.
> >>>>> Maps acquired during the early stage should be freed by the driver during
> >> the
> >>>> early stage.
> >>>>> And the driver should re-acquire the memory map after booting.
> >>>>
> >>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
> that
> >>>> that code can be
> >>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
> of
> >> for
> >>>> example 8250 console)
> >>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
> that
> >>>> registers a console),
> >>>> We just can not tell if the received table pointer should or sould not be
> freed
> >>>> with early_memunmap()
> >>>> (actually __acpi_unmap_table() or whatever) without checking
> >>>> acpi_gbl_permanent_mmap,
> >>>> but that's all too low level.
> >>> [Lv Zheng]
> >>> The driver should make sure that:
> >>> Map/unmap is paired during early stage.
> >>> For late stage, it should be another pair of map/unmap.
> >>>
> >>>>
> >>>> Another option, as you describe, is to get this pointer early, don't free it
> >>> [Lv Zheng]
> >>> I mean you should free it early.
> >>>
> >>>> untill acpi_gbl_permanent_mmap is set, then free it (with
> >>>> early_acpi_os_unmap_memory(), that's
> >>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
> the
> >>>> persistent
> >>>> pointer to the table.  The problem with it is that we can not just watch
> >>>> acpi_gbl_permanent_mmap
> >>>> to catch this exact moment.  And also accessing
> acpi_gbl_permanent_mmap
> >> is
> >>>> not good as it probably is
> >>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >>>> Or I probably miss what you are suggesting.
> >>>>
> >>> [Lv Zheng]
> >>> I mean, you should:
> >>> During early stage:
> >>> acpi_os_map_memory()
> >>> Parse the table.
> >>> acpi_os_unmap_memory().
> >>>
> >>>>> This is because, during early bootup stage, there are only limited slots
> >>>> available for drivers to map memory.
> >>>>> So by changing __init to __ref here, you probably will hide many such
> >> defects.
> >>>>
> >>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >>>> BTW, exactly the same thing is done in the beginning of
> >>>> acpi_os_unmap_memory() and than's ok,
> >>>> that function is __ref.
> >>>>
> >>>>> And solving issues in this way doesn't seem to be an improvement.
> >>>>
> >>>> Could you please tell me where I am wrong?  I still don't understand your
> >> point.
> >>> [Lv Zheng]
> >>> But anyway, the defect should be in ACPI subsystem core.
> >>> The cause should be the API itself - acpi_get_table().
> >>>
> >>> So I agree you can use early_acpi_os_unmap_memory() during the period
> the
> >> root causes are not cleaned up.
> >>> But the bottom line is: the driver need to ensure that
> >> early_acpi_os_unmap_memory() is always invoked.
> >>> As long as you can ensure this, I don't have objections for deploying
> >> early_acpi_os_unmap_memory()  for now.
> >>>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>>
> >>>> Thank you
> >>>> Aleksey Makarov
> >>>>
> >>>>>
> >>>>> Thanks and best regards
> >>>>> -Lv
> >>>>>
> >>>>>>
> >>>>>> Thanks and best regards
> >>>>>> -Lv
> >>>>>>
> >>>>>>>
> >>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>>>> ---
> >>>>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>>>
> >>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>>>> index 67da6fb..8a552cd 100644
> >>>>>>> --- a/drivers/acpi/osl.c
> >>>>>>> +++ b/drivers/acpi/osl.c
> >>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
> *virt,
> >>>>>>> acpi_size size)
> >>>>>>>  }
> >>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>>>
> >>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> >> acpi_size
> >>>>>> size)
> >>>>>>> +/*
> >>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
> anywhere
> >>>>>>> + */
> >>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> >> acpi_size
> >>>>>> size)
> >>>>>>>  {
> >>>>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>>>  		__acpi_unmap_table(virt, size);
> >>>>>>> --
> >>>>>>> 2.7.1
> >>>>>>>
> >>>>>>> --
> >>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> info.html
> >>>>>> --
> >>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-22  2:24                   ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-22  2:24 UTC (permalink / raw)
  To: Aleksey Makarov, Peter Hurley, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi,

> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi Lv,
> 
> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>> early_acpi_os_unmap_memory()
> >>>>
> >>>> Hi Lv,
> >>>>
> >>>> Thank you for review.
> >>>>
> >>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>>>
> >>>> [..]
> >>>>
> >>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
> not
> >>>> set.
> >>>>>>>
> >>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>>>
> >>>>>>> We need this function to be non-__init because we need access to
> >>>>>>> some tables at unpredictable time--it may be before or after
> >>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> >> Console
> >>>>>>> Redirection) table is needed each time a new console is registered.
> >>>>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>>>> does.
> >>>>>> [Lv Zheng]
> >>>>>> Why don't you use another API instead of
> >> early_acpi_os_unmap_memory()
> >>>> in
> >>>>>> case you want to unmap things in any cases.
> >>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>>>
> >>>> As far as I understand, there exist two steps in ACPI initialization:
> >>>>
> >>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >>>> acpi_get_table_with_size()
> >>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
> >>>> should be unmapped.
> >>>>
> >>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> >> unmapped
> >>>> at all.
> >>>>
> >>> [Lv Zheng]
> >>> This statement is wrong, this should be:
> >>> As long as there is a __reference__ to the mapped table, the pointer should
> >> not be unmapped.
> >>> In fact, we have a series to introduce acpi_put_table() to achieve this.
> >>> So your argument is wrong from very first point.
> >>>
> >>>> That exactly what early_acpi_os_unmap_memory() does--it checks
> >>>> acpi_gbl_permanent_mmap.
> >>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
> >> had
> >>>> been set,
> >>>> it would have tried to free that pointer with an oops (actually, I checked
> that
> >>>> and got that oops).
> >>>>
> >>>> So using acpi_os_unmap_memory() is not an option here, but
> >>>> early_acpi_os_unmap_memory()
> >>>> match perfectly.
> >>> [Lv Zheng]
> >>> I don't think so.
> >>> For definition block tables, we know for sure there will always be
> references,
> >> until "Unload" opcode is invoked by the AML interpreter.
> >>> But for the data tables, OSPMs should use them in this way:
> >>> 1. map the table
> >>> 2. parse the table and convert it to OS specific structures
> >>> 3. unmap the table
> >>> This helps to shrink virtual memory address space usages.
> >>>
> >>> So from this point of view, all data tables should be unmapped right after
> >> being parsed.
> >>> Why do you need the map to be persistent in the kernel address space?
> >>> You can always map a small table, but what if the table size is very big?
> >>>
> >>>>
> >>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>>>
> >>>> I don't think so -- I have explained why.  It does different thing.
> >>>> Probably it (and/or other functions in that api) should be renamed.
> >>>>
> >>> [Lv Zheng]
> >>> Just let me ask one more question.
> >>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> >>> How ACPICA can work with just acpi_os_unmap_memory()?
> >>> You can check drivers/acpi/tbxxx.c.
> >>> Especially: acpi_tb_release_temp_table() and the code invoking it.
> >>>
> >>>>> [Lv Zheng]
> >>>>> One more thing is:
> >>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead
> of
> >>>> early_acpi_os_unmap_memory(),
> >>>>> then it implies that your driver does have a defect.
> >>>>
> >>>> I still don't understand what defect, sorry.
> >>> [Lv Zheng]
> >>> If you can't ensure this sequence for using the data tables:
> >>> 1. map the table
> >>> 2. parse the table and convert it to OS specific structure
> >>> 3. unmap the table
> >>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> >>
> >> Exactly.
> > [Lv Zheng]
> > So it looks to me:
> > Changing __init to __ref here is entirely not acceptable.
> > This API should stay being invoked during early stage.
> > Otherwise, it may leave us untrackable code that maps tables during early
> stage and leaks maps to the late stage.
> > If Linux contains such kind of code, I'm afraid, it will become impossible to
> introduce acpi_put_table() to clean up the mappings.
> > Because when acpi_put_table() is called during the late stage to free a map
> acquired during the early stage, it then obviously will end up with panic.
> 
> Can you please sugggest a common method to access ACPI tables that
> works both before *and* after acpi_gbl_permanent_mmap is set and __init
> code
> is removed?
[Lv Zheng] 
Do not change __init for now.

Currently you should:
1. before acpi_gbl_permanent_mmap is set:
acpi_get_table_with_size()
parse the table
early_acpi_os_unmap_memory()
Do your driver early stuff here

2. after acpi_gbl_permanent_mmap is set:
acpi_get_table()
Parse the table
Do your driver late stuff here
<- note there is no API now being an inverse of acpi_get_table().

Besides, I'm about to insert error messages between 1 and 2.
If an early map is not release, error message will be prompted to the developers.

And if you don't follow the above rules, it mean you are trying to lay a mine, waiting for me to step on it.
That's why this change is entirely not acceptable.

I'm about to send out the cleanup series in 1 week, and will Cc you.
You can rebase your code on top of the cleanup series.

Thanks and best regards
-Lv

> 
> > Thanks and best regards
> > -Lv
> >
> >> The central problem here is the way Aleksey is trying to hookup a console.
> >>
> >> What should be happening in this series is:
> >> 1. early map SPCR
> >> 2. parse the SPCR table
> >> 3. call add_preferred_console() to add the SPCR console to the console
> table
> >> 4. unmap SPCR
> >>
> >> This trivial and unobtrusive method would already have a 8250 console
> >> running via SPCR. I've already pointed this out in previous reviews.
> >>
> >> Further, the above method *will be required anyway* for the DBG2 table to
> >> start an earlycon, which I've already pointed out in previous reviews.
> >>
> >> Then to enable amba-pl011 console via ACPI, add a console match() method
> >> similar to the 8250 console match() method, univ8250_console_match().
> >>
> >> FWIW, PCI earlycon + console support was already submitted once before
> but
> >> never picked up by GregKH. I think I'll just grab that and re-submit so
> >> you would know what to emit for console options in the
> >> add_preferred_console().
> >>
> >>
> >> Regards,
> >> Peter Hurley
> >>
> >>
> >>>>> There is an early bootup requirement in Linux.
> >>>>> Maps acquired during the early stage should be freed by the driver during
> >> the
> >>>> early stage.
> >>>>> And the driver should re-acquire the memory map after booting.
> >>>>
> >>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
> that
> >>>> that code can be
> >>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
> of
> >> for
> >>>> example 8250 console)
> >>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
> that
> >>>> registers a console),
> >>>> We just can not tell if the received table pointer should or sould not be
> freed
> >>>> with early_memunmap()
> >>>> (actually __acpi_unmap_table() or whatever) without checking
> >>>> acpi_gbl_permanent_mmap,
> >>>> but that's all too low level.
> >>> [Lv Zheng]
> >>> The driver should make sure that:
> >>> Map/unmap is paired during early stage.
> >>> For late stage, it should be another pair of map/unmap.
> >>>
> >>>>
> >>>> Another option, as you describe, is to get this pointer early, don't free it
> >>> [Lv Zheng]
> >>> I mean you should free it early.
> >>>
> >>>> untill acpi_gbl_permanent_mmap is set, then free it (with
> >>>> early_acpi_os_unmap_memory(), that's
> >>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
> the
> >>>> persistent
> >>>> pointer to the table.  The problem with it is that we can not just watch
> >>>> acpi_gbl_permanent_mmap
> >>>> to catch this exact moment.  And also accessing
> acpi_gbl_permanent_mmap
> >> is
> >>>> not good as it probably is
> >>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >>>> Or I probably miss what you are suggesting.
> >>>>
> >>> [Lv Zheng]
> >>> I mean, you should:
> >>> During early stage:
> >>> acpi_os_map_memory()
> >>> Parse the table.
> >>> acpi_os_unmap_memory().
> >>>
> >>>>> This is because, during early bootup stage, there are only limited slots
> >>>> available for drivers to map memory.
> >>>>> So by changing __init to __ref here, you probably will hide many such
> >> defects.
> >>>>
> >>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >>>> BTW, exactly the same thing is done in the beginning of
> >>>> acpi_os_unmap_memory() and than's ok,
> >>>> that function is __ref.
> >>>>
> >>>>> And solving issues in this way doesn't seem to be an improvement.
> >>>>
> >>>> Could you please tell me where I am wrong?  I still don't understand your
> >> point.
> >>> [Lv Zheng]
> >>> But anyway, the defect should be in ACPI subsystem core.
> >>> The cause should be the API itself - acpi_get_table().
> >>>
> >>> So I agree you can use early_acpi_os_unmap_memory() during the period
> the
> >> root causes are not cleaned up.
> >>> But the bottom line is: the driver need to ensure that
> >> early_acpi_os_unmap_memory() is always invoked.
> >>> As long as you can ensure this, I don't have objections for deploying
> >> early_acpi_os_unmap_memory()  for now.
> >>>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>>
> >>>> Thank you
> >>>> Aleksey Makarov
> >>>>
> >>>>>
> >>>>> Thanks and best regards
> >>>>> -Lv
> >>>>>
> >>>>>>
> >>>>>> Thanks and best regards
> >>>>>> -Lv
> >>>>>>
> >>>>>>>
> >>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>>>> ---
> >>>>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>>>
> >>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>>>> index 67da6fb..8a552cd 100644
> >>>>>>> --- a/drivers/acpi/osl.c
> >>>>>>> +++ b/drivers/acpi/osl.c
> >>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
> *virt,
> >>>>>>> acpi_size size)
> >>>>>>>  }
> >>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>>>
> >>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> >> acpi_size
> >>>>>> size)
> >>>>>>> +/*
> >>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
> anywhere
> >>>>>>> + */
> >>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> >> acpi_size
> >>>>>> size)
> >>>>>>>  {
> >>>>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>>>  		__acpi_unmap_table(virt, size);
> >>>>>>> --
> >>>>>>> 2.7.1
> >>>>>>>
> >>>>>>> --
> >>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> info.html
> >>>>>> --
> >>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-22  2:24                   ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-22  2:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi Lv,
> 
> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
> >>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>> early_acpi_os_unmap_memory()
> >>>>
> >>>> Hi Lv,
> >>>>
> >>>> Thank you for review.
> >>>>
> >>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>>>
> >>>> [..]
> >>>>
> >>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
> not
> >>>> set.
> >>>>>>>
> >>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>>>
> >>>>>>> We need this function to be non-__init because we need access to
> >>>>>>> some tables at unpredictable time--it may be before or after
> >>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> >> Console
> >>>>>>> Redirection) table is needed each time a new console is registered.
> >>>>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>>>> does.
> >>>>>> [Lv Zheng]
> >>>>>> Why don't you use another API instead of
> >> early_acpi_os_unmap_memory()
> >>>> in
> >>>>>> case you want to unmap things in any cases.
> >>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>>>
> >>>> As far as I understand, there exist two steps in ACPI initialization:
> >>>>
> >>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >>>> acpi_get_table_with_size()
> >>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
> >>>> should be unmapped.
> >>>>
> >>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> >> unmapped
> >>>> at all.
> >>>>
> >>> [Lv Zheng]
> >>> This statement is wrong, this should be:
> >>> As long as there is a __reference__ to the mapped table, the pointer should
> >> not be unmapped.
> >>> In fact, we have a series to introduce acpi_put_table() to achieve this.
> >>> So your argument is wrong from very first point.
> >>>
> >>>> That exactly what early_acpi_os_unmap_memory() does--it checks
> >>>> acpi_gbl_permanent_mmap.
> >>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
> >> had
> >>>> been set,
> >>>> it would have tried to free that pointer with an oops (actually, I checked
> that
> >>>> and got that oops).
> >>>>
> >>>> So using acpi_os_unmap_memory() is not an option here, but
> >>>> early_acpi_os_unmap_memory()
> >>>> match perfectly.
> >>> [Lv Zheng]
> >>> I don't think so.
> >>> For definition block tables, we know for sure there will always be
> references,
> >> until "Unload" opcode is invoked by the AML interpreter.
> >>> But for the data tables, OSPMs should use them in this way:
> >>> 1. map the table
> >>> 2. parse the table and convert it to OS specific structures
> >>> 3. unmap the table
> >>> This helps to shrink virtual memory address space usages.
> >>>
> >>> So from this point of view, all data tables should be unmapped right after
> >> being parsed.
> >>> Why do you need the map to be persistent in the kernel address space?
> >>> You can always map a small table, but what if the table size is very big?
> >>>
> >>>>
> >>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>>>
> >>>> I don't think so -- I have explained why.  It does different thing.
> >>>> Probably it (and/or other functions in that api) should be renamed.
> >>>>
> >>> [Lv Zheng]
> >>> Just let me ask one more question.
> >>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> >>> How ACPICA can work with just acpi_os_unmap_memory()?
> >>> You can check drivers/acpi/tbxxx.c.
> >>> Especially: acpi_tb_release_temp_table() and the code invoking it.
> >>>
> >>>>> [Lv Zheng]
> >>>>> One more thing is:
> >>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead
> of
> >>>> early_acpi_os_unmap_memory(),
> >>>>> then it implies that your driver does have a defect.
> >>>>
> >>>> I still don't understand what defect, sorry.
> >>> [Lv Zheng]
> >>> If you can't ensure this sequence for using the data tables:
> >>> 1. map the table
> >>> 2. parse the table and convert it to OS specific structure
> >>> 3. unmap the table
> >>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> >>
> >> Exactly.
> > [Lv Zheng]
> > So it looks to me:
> > Changing __init to __ref here is entirely not acceptable.
> > This API should stay being invoked during early stage.
> > Otherwise, it may leave us untrackable code that maps tables during early
> stage and leaks maps to the late stage.
> > If Linux contains such kind of code, I'm afraid, it will become impossible to
> introduce acpi_put_table() to clean up the mappings.
> > Because when acpi_put_table() is called during the late stage to free a map
> acquired during the early stage, it then obviously will end up with panic.
> 
> Can you please sugggest a common method to access ACPI tables that
> works both before *and* after acpi_gbl_permanent_mmap is set and __init
> code
> is removed?
[Lv Zheng] 
Do not change __init for now.

Currently you should:
1. before acpi_gbl_permanent_mmap is set:
acpi_get_table_with_size()
parse the table
early_acpi_os_unmap_memory()
Do your driver early stuff here

2. after acpi_gbl_permanent_mmap is set:
acpi_get_table()
Parse the table
Do your driver late stuff here
<- note there is no API now being an inverse of acpi_get_table().

Besides, I'm about to insert error messages between 1 and 2.
If an early map is not release, error message will be prompted to the developers.

And if you don't follow the above rules, it mean you are trying to lay a mine, waiting for me to step on it.
That's why this change is entirely not acceptable.

I'm about to send out the cleanup series in 1 week, and will Cc you.
You can rebase your code on top of the cleanup series.

Thanks and best regards
-Lv

> 
> > Thanks and best regards
> > -Lv
> >
> >> The central problem here is the way Aleksey is trying to hookup a console.
> >>
> >> What should be happening in this series is:
> >> 1. early map SPCR
> >> 2. parse the SPCR table
> >> 3. call add_preferred_console() to add the SPCR console to the console
> table
> >> 4. unmap SPCR
> >>
> >> This trivial and unobtrusive method would already have a 8250 console
> >> running via SPCR. I've already pointed this out in previous reviews.
> >>
> >> Further, the above method *will be required anyway* for the DBG2 table to
> >> start an earlycon, which I've already pointed out in previous reviews.
> >>
> >> Then to enable amba-pl011 console via ACPI, add a console match() method
> >> similar to the 8250 console match() method, univ8250_console_match().
> >>
> >> FWIW, PCI earlycon + console support was already submitted once before
> but
> >> never picked up by GregKH. I think I'll just grab that and re-submit so
> >> you would know what to emit for console options in the
> >> add_preferred_console().
> >>
> >>
> >> Regards,
> >> Peter Hurley
> >>
> >>
> >>>>> There is an early bootup requirement in Linux.
> >>>>> Maps acquired during the early stage should be freed by the driver during
> >> the
> >>>> early stage.
> >>>>> And the driver should re-acquire the memory map after booting.
> >>>>
> >>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
> that
> >>>> that code can be
> >>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
> of
> >> for
> >>>> example 8250 console)
> >>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
> that
> >>>> registers a console),
> >>>> We just can not tell if the received table pointer should or sould not be
> freed
> >>>> with early_memunmap()
> >>>> (actually __acpi_unmap_table() or whatever) without checking
> >>>> acpi_gbl_permanent_mmap,
> >>>> but that's all too low level.
> >>> [Lv Zheng]
> >>> The driver should make sure that:
> >>> Map/unmap is paired during early stage.
> >>> For late stage, it should be another pair of map/unmap.
> >>>
> >>>>
> >>>> Another option, as you describe, is to get this pointer early, don't free it
> >>> [Lv Zheng]
> >>> I mean you should free it early.
> >>>
> >>>> untill acpi_gbl_permanent_mmap is set, then free it (with
> >>>> early_acpi_os_unmap_memory(), that's
> >>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
> the
> >>>> persistent
> >>>> pointer to the table.  The problem with it is that we can not just watch
> >>>> acpi_gbl_permanent_mmap
> >>>> to catch this exact moment.  And also accessing
> acpi_gbl_permanent_mmap
> >> is
> >>>> not good as it probably is
> >>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >>>> Or I probably miss what you are suggesting.
> >>>>
> >>> [Lv Zheng]
> >>> I mean, you should:
> >>> During early stage:
> >>> acpi_os_map_memory()
> >>> Parse the table.
> >>> acpi_os_unmap_memory().
> >>>
> >>>>> This is because, during early bootup stage, there are only limited slots
> >>>> available for drivers to map memory.
> >>>>> So by changing __init to __ref here, you probably will hide many such
> >> defects.
> >>>>
> >>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >>>> BTW, exactly the same thing is done in the beginning of
> >>>> acpi_os_unmap_memory() and than's ok,
> >>>> that function is __ref.
> >>>>
> >>>>> And solving issues in this way doesn't seem to be an improvement.
> >>>>
> >>>> Could you please tell me where I am wrong?  I still don't understand your
> >> point.
> >>> [Lv Zheng]
> >>> But anyway, the defect should be in ACPI subsystem core.
> >>> The cause should be the API itself - acpi_get_table().
> >>>
> >>> So I agree you can use early_acpi_os_unmap_memory() during the period
> the
> >> root causes are not cleaned up.
> >>> But the bottom line is: the driver need to ensure that
> >> early_acpi_os_unmap_memory() is always invoked.
> >>> As long as you can ensure this, I don't have objections for deploying
> >> early_acpi_os_unmap_memory()  for now.
> >>>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>>
> >>>> Thank you
> >>>> Aleksey Makarov
> >>>>
> >>>>>
> >>>>> Thanks and best regards
> >>>>> -Lv
> >>>>>
> >>>>>>
> >>>>>> Thanks and best regards
> >>>>>> -Lv
> >>>>>>
> >>>>>>>
> >>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>>>> ---
> >>>>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>>>
> >>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>>>> index 67da6fb..8a552cd 100644
> >>>>>>> --- a/drivers/acpi/osl.c
> >>>>>>> +++ b/drivers/acpi/osl.c
> >>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
> *virt,
> >>>>>>> acpi_size size)
> >>>>>>>  }
> >>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>>>
> >>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> >> acpi_size
> >>>>>> size)
> >>>>>>> +/*
> >>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
> anywhere
> >>>>>>> + */
> >>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> >> acpi_size
> >>>>>> size)
> >>>>>>>  {
> >>>>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>>>  		__acpi_unmap_table(virt, size);
> >>>>>>> --
> >>>>>>> 2.7.1
> >>>>>>>
> >>>>>>> --
> >>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>>> the body of a message to majordomo at vger.kernel.org
> >>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> info.html
> >>>>>> --
> >>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>> the body of a message to majordomo at vger.kernel.org
> >>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-19 17:20                   ` Christopher Covington
  (?)
@ 2016-02-22  5:37                     ` Peter Hurley
  -1 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-22  5:37 UTC (permalink / raw)
  To: Christopher Covington, Aleksey Makarov, Zheng, Lv, linux-acpi, harba
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Len Brown

On 02/19/2016 09:20 AM, Christopher Covington wrote:
> 
> 
> On February 19, 2016 10:25:50 AM EST, Peter Hurley <peter@hurleysoftware.com> wrote:
>> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>>> Hi Peter,
>>>
>>> Thank you for review.
>>>
>>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it
>> calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>> not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from
>> anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access
>> to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>> Console
>>>>>>>>> Redirection) table is needed each time a new console is
>> registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is
>> inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this
>> function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of
>> early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI
>> initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a
>> pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>> unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the
>> pointer should not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve
>> this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>> had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I
>> checked that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng] 
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be
>> references, until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped
>> right after being parsed.
>>>>> Why do you need the map to be persistent in the kernel address
>> space?
>>>>> You can always map a small table, but what if the table size is
>> very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different
>> thing.
>>>>>> Probably it (and/or other functions in that api) should be
>> renamed.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>> instead of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng] 
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI
>> subsystem core.
>>>>
>>>> Exactly.
>>>>
>>>> The central problem here is the way Aleksey is trying to hookup a
>> console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the
>> console table
>>>> 4. unmap SPCR
>>>
>>> This does not work.  
>>>
>>> SPCR specifies address of the console, but add_preferred_console()
>> accepts
>>> name of console and its index.  There are no general method to
>> translate address
>>> to name at such an early stage.
>>
>>
>> 	add_preferred_console(uart, 0, "io,0x3f8,115200");
>>
>> This will start a console with the 8250 driver. I've already pointed
>> this out to you in an earlier review. This is what existing firmware
>> already does.
>>
>> This is also the method you will use to start an earlycon from the
>> DBG2 table, by additionally calling setup_earlycon().
> 
> Can the device specified in DBG2 be used for both earlycon and KGDB?

I don't see why not. Since earlycon is a bootconsole, it's disabled when
the first regular console starts. I use earlycon + KGDB now on the same
device (ttyS0 == uart0 @ mmio 0x44e09000):

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.5.0-rc2+ (peter@thor) (gcc version 5.1.1 20150608 (Linaro GCC 5.1-2015.08) ) #60 PREE
MPT Sun Feb 21 20:17:16 PST 2016
[    0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] Machine model: TI AM335x BeagleBone Black
[    0.000000] earlycon: omap8250 at MMIO 0x44e09000 (options '')
[    0.000000] bootconsole [omap8250] enabled

....

[    3.086800] Serial: 8250/16550 driver, 32 ports, IRQ sharing disabled
[    3.099818] console [ttyS0] disabled
[    3.112402] 44e09000.serial: ttyS0 at MMIO 0x44e09000 (irq = 158, base_baud = 3000000) is a 8250
[    3.121575] console [ttyS0] enabled
[    3.121575] console [ttyS0] enabled
[    3.128678] bootconsole [omap8250] disabled
[    3.128678] bootconsole [omap8250] disabled
[    3.152397] 481a8000.serial: ttyS4 at MMIO 0x481a8000 (irq = 159, base_baud = 3000000) is a 8250
[    3.176393] 481aa000.serial: ttyS5 at MMIO 0x481aa000 (irq = 160, base_baud = 3000000) is a 8250
[    3.185998] KGDB: Registered I/O driver kgdboc
[    3.200374] KGDB: Waiting for connection from remote gdb...


> If it can only be used for one, let's make sure the choice of
> earlycon vs KGDB is intentional rather than accidental.

If anything, a future feature would be to run KGDB over earlycon.

Regards,
Peter Hurley

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-22  5:37                     ` Peter Hurley
  0 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-22  5:37 UTC (permalink / raw)
  To: Christopher Covington, Aleksey Makarov, Zheng, Lv, linux-acpi, harba
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Len Brown

On 02/19/2016 09:20 AM, Christopher Covington wrote:
> 
> 
> On February 19, 2016 10:25:50 AM EST, Peter Hurley <peter@hurleysoftware.com> wrote:
>> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>>> Hi Peter,
>>>
>>> Thank you for review.
>>>
>>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it
>> calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>> not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from
>> anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access
>> to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>> Console
>>>>>>>>> Redirection) table is needed each time a new console is
>> registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is
>> inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this
>> function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of
>> early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI
>> initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a
>> pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>> unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the
>> pointer should not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve
>> this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>> had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I
>> checked that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng] 
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be
>> references, until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped
>> right after being parsed.
>>>>> Why do you need the map to be persistent in the kernel address
>> space?
>>>>> You can always map a small table, but what if the table size is
>> very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different
>> thing.
>>>>>> Probably it (and/or other functions in that api) should be
>> renamed.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>> instead of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng] 
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI
>> subsystem core.
>>>>
>>>> Exactly.
>>>>
>>>> The central problem here is the way Aleksey is trying to hookup a
>> console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the
>> console table
>>>> 4. unmap SPCR
>>>
>>> This does not work.  
>>>
>>> SPCR specifies address of the console, but add_preferred_console()
>> accepts
>>> name of console and its index.  There are no general method to
>> translate address
>>> to name at such an early stage.
>>
>>
>> 	add_preferred_console(uart, 0, "io,0x3f8,115200");
>>
>> This will start a console with the 8250 driver. I've already pointed
>> this out to you in an earlier review. This is what existing firmware
>> already does.
>>
>> This is also the method you will use to start an earlycon from the
>> DBG2 table, by additionally calling setup_earlycon().
> 
> Can the device specified in DBG2 be used for both earlycon and KGDB?

I don't see why not. Since earlycon is a bootconsole, it's disabled when
the first regular console starts. I use earlycon + KGDB now on the same
device (ttyS0 == uart0 @ mmio 0x44e09000):

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.5.0-rc2+ (peter@thor) (gcc version 5.1.1 20150608 (Linaro GCC 5.1-2015.08) ) #60 PREE
MPT Sun Feb 21 20:17:16 PST 2016
[    0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] Machine model: TI AM335x BeagleBone Black
[    0.000000] earlycon: omap8250 at MMIO 0x44e09000 (options '')
[    0.000000] bootconsole [omap8250] enabled

....

[    3.086800] Serial: 8250/16550 driver, 32 ports, IRQ sharing disabled
[    3.099818] console [ttyS0] disabled
[    3.112402] 44e09000.serial: ttyS0 at MMIO 0x44e09000 (irq = 158, base_baud = 3000000) is a 8250
[    3.121575] console [ttyS0] enabled
[    3.121575] console [ttyS0] enabled
[    3.128678] bootconsole [omap8250] disabled
[    3.128678] bootconsole [omap8250] disabled
[    3.152397] 481a8000.serial: ttyS4 at MMIO 0x481a8000 (irq = 159, base_baud = 3000000) is a 8250
[    3.176393] 481aa000.serial: ttyS5 at MMIO 0x481aa000 (irq = 160, base_baud = 3000000) is a 8250
[    3.185998] KGDB: Registered I/O driver kgdboc
[    3.200374] KGDB: Waiting for connection from remote gdb...


> If it can only be used for one, let's make sure the choice of
> earlycon vs KGDB is intentional rather than accidental.

If anything, a future feature would be to run KGDB over earlycon.

Regards,
Peter Hurley

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-22  5:37                     ` Peter Hurley
  0 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-02-22  5:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/19/2016 09:20 AM, Christopher Covington wrote:
> 
> 
> On February 19, 2016 10:25:50 AM EST, Peter Hurley <peter@hurleysoftware.com> wrote:
>> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>>> Hi Peter,
>>>
>>> Thank you for review.
>>>
>>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it
>> calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>> not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from
>> anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access
>> to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>> Console
>>>>>>>>> Redirection) table is needed each time a new console is
>> registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is
>> inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this
>> function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of
>> early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI
>> initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a
>> pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>> unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the
>> pointer should not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve
>> this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>> had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I
>> checked that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng] 
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be
>> references, until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped
>> right after being parsed.
>>>>> Why do you need the map to be persistent in the kernel address
>> space?
>>>>> You can always map a small table, but what if the table size is
>> very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different
>> thing.
>>>>>> Probably it (and/or other functions in that api) should be
>> renamed.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>> instead of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng] 
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI
>> subsystem core.
>>>>
>>>> Exactly.
>>>>
>>>> The central problem here is the way Aleksey is trying to hookup a
>> console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the
>> console table
>>>> 4. unmap SPCR
>>>
>>> This does not work.  
>>>
>>> SPCR specifies address of the console, but add_preferred_console()
>> accepts
>>> name of console and its index.  There are no general method to
>> translate address
>>> to name at such an early stage.
>>
>>
>> 	add_preferred_console(uart, 0, "io,0x3f8,115200");
>>
>> This will start a console with the 8250 driver. I've already pointed
>> this out to you in an earlier review. This is what existing firmware
>> already does.
>>
>> This is also the method you will use to start an earlycon from the
>> DBG2 table, by additionally calling setup_earlycon().
> 
> Can the device specified in DBG2 be used for both earlycon and KGDB?

I don't see why not. Since earlycon is a bootconsole, it's disabled when
the first regular console starts. I use earlycon + KGDB now on the same
device (ttyS0 == uart0 @ mmio 0x44e09000):

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.5.0-rc2+ (peter at thor) (gcc version 5.1.1 20150608 (Linaro GCC 5.1-2015.08) ) #60 PREE
MPT Sun Feb 21 20:17:16 PST 2016
[    0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] Machine model: TI AM335x BeagleBone Black
[    0.000000] earlycon: omap8250 at MMIO 0x44e09000 (options '')
[    0.000000] bootconsole [omap8250] enabled

....

[    3.086800] Serial: 8250/16550 driver, 32 ports, IRQ sharing disabled
[    3.099818] console [ttyS0] disabled
[    3.112402] 44e09000.serial: ttyS0 at MMIO 0x44e09000 (irq = 158, base_baud = 3000000) is a 8250
[    3.121575] console [ttyS0] enabled
[    3.121575] console [ttyS0] enabled
[    3.128678] bootconsole [omap8250] disabled
[    3.128678] bootconsole [omap8250] disabled
[    3.152397] 481a8000.serial: ttyS4 at MMIO 0x481a8000 (irq = 159, base_baud = 3000000) is a 8250
[    3.176393] 481aa000.serial: ttyS5 at MMIO 0x481aa000 (irq = 160, base_baud = 3000000) is a 8250
[    3.185998] KGDB: Registered I/O driver kgdboc
[    3.200374] KGDB: Waiting for connection from remote gdb...


> If it can only be used for one, let's make sure the choice of
> earlycon vs KGDB is intentional rather than accidental.

If anything, a future feature would be to run KGDB over earlycon.

Regards,
Peter Hurley

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-19 15:25                 ` Peter Hurley
  (?)
@ 2016-02-22 14:35                   ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-22 14:35 UTC (permalink / raw)
  To: Peter Hurley, Zheng, Lv, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

On 02/19/2016 06:25 PM, Peter Hurley wrote:
> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>> Hi Peter,
>>
>> Thank you for review.
>>
>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>> Hi,
>>>>
>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>> early_acpi_os_unmap_memory()
>>>>>
>>>>> Hi Lv,
>>>>>
>>>>> Thank you for review.
>>>>>
>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>
>>>>> [..]
>>>>>
>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>>> set.
>>>>>>>>
>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>
>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>> does.
>>>>>>> [Lv Zheng]
>>>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>>>> in
>>>>>>> case you want to unmap things in any cases.
>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>
>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>
>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>> acpi_get_table_with_size()
>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>>> should be unmapped.
>>>>>
>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>>>> at all.
>>>>>
>>>> [Lv Zheng] 
>>>> This statement is wrong, this should be:
>>>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>> So your argument is wrong from very first point.
>>>>
>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>> acpi_gbl_permanent_mmap.
>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>>>> been set,
>>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>>> and got that oops).
>>>>>
>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>> early_acpi_os_unmap_memory()
>>>>> match perfectly.
>>>> [Lv Zheng] 
>>>> I don't think so.
>>>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>>>> But for the data tables, OSPMs should use them in this way:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structures
>>>> 3. unmap the table
>>>> This helps to shrink virtual memory address space usages.
>>>>
>>>> So from this point of view, all data tables should be unmapped right after being parsed.
>>>> Why do you need the map to be persistent in the kernel address space?
>>>> You can always map a small table, but what if the table size is very big?
>>>>
>>>>>
>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>
>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>
>>>> [Lv Zheng] 
>>>> Just let me ask one more question.
>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>> You can check drivers/acpi/tbxxx.c.
>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>
>>>>>> [Lv Zheng]
>>>>>> One more thing is:
>>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>>> early_acpi_os_unmap_memory(),
>>>>>> then it implies that your driver does have a defect.
>>>>>
>>>>> I still don't understand what defect, sorry.
>>>> [Lv Zheng] 
>>>> If you can't ensure this sequence for using the data tables:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structure
>>>> 3. unmap the table
>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>
>>> Exactly.
>>>
>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>
>>> What should be happening in this series is:
>>> 1. early map SPCR
>>> 2. parse the SPCR table
>>> 3. call add_preferred_console() to add the SPCR console to the console table
>>> 4. unmap SPCR
>>
>> This does not work.  
>>
>> SPCR specifies address of the console, but add_preferred_console() accepts
>> name of console and its index.  There are no general method to translate address
>> to name at such an early stage.
> 
> 
> 	add_preferred_console(uart, 0, "io,0x3f8,115200");

First argument here should be (char *), the name of the console.
We can not tell it just from the SPCR ACPI table without
introducing new made up names and writting which/case that should be 
supported all the linux lifetime.

I am also not quite shure I can tell the number of tty line (the 0 argument)
just from the address.

Did you mean "uart" here?  As far as I can see, this would match the *earlycon*,
not a regular console, that is not what this patch is about.
It is about selecting regular (non-boot) consoles.

I think translating address to string and then parsing it again is not
unaceptable, but definitely worse than the approach in my patch, where
I compare it directly.

> This will start a console with the 8250 driver. I've already pointed
> this out to you in an earlier review. This is what existing firmware
> already does.
> 
> This is also the method you will use to start an earlycon from the
> DBG2 table, by additionally calling setup_earlycon().
> 
> 
>> There is another reason why I prefer to parse SPCR each time a console is registered.
>> Some consoles can be registered very early in the initialization process and
>> we have to be sure add_preferred_console() is called before that.
> 
> However, since you're not adding a preferred console until uart driver
> loads, there may already be a preferred console selected and running.
> 
> This leads to weird issues like duplicated output on the serial console
> when an earlycon is disabled by the dummy VGA/FB console then the
> serial console starts and reprints the entire boot log on the same
> terminal the earlycon already printed.

Yes, misconfigured systems often misbehave.  In this case I would
question why there is an enabled console (we rely on ACPI to enable it).
And I probably do not understand the scenario, but 
- "earlycon is disabled by the dummy VGA/FB console"
and
- "earlycon already printed"
seem a bit contradictory.

> Better just to parse both the DBG2 and SPCR tables before or at
> early param, and add_preferred_consoles then.

I still don't see why it's better, but I think I explained why it's worse.

>> Of course, I could just parse it once and cache the results, but
>> this still requires accessing SPCR before acpi_gbl_permanent_mmap
>> is set *or* after that.
>>
>>> This trivial and unobtrusive method would already have a 8250 console
>>> running via SPCR. I've already pointed this out in previous reviews.
>>>
>>> Further, the above method *will be required anyway* for the DBG2 table to
>>> start an earlycon, which I've already pointed out in previous reviews.
>>>
>>> Then to enable amba-pl011 console via ACPI, add a console match() method
>>> similar to the 8250 console match() method, univ8250_console_match().
>>
>> So are you suggesting a separate method for each possible console?
>> This is not acceptable.
> 
> All 1 of them???

DBG2 specifies these subtypes of serial drivers:

- Fully 16550-compatible
- 16550 subset compatible with DBGP Revision 1
- ARM PL011 UART
- (deprecated) ARM SBSA (2.x only) Generic UART supporting only 32-bit accesses
- ARM SBSA Generic UART
- ARM DCC
- BCM2835

So it's at least 4 (or 3, I am not sure about ARM DCC) different types and
the list is open.  We would have to support it.

> The 8250 driver already does this, so no work for you there.

"uart" is for boot console, so it is not relevant.  Or did you refer to something else?

> That leaves you needing to write a trivial match() method for just
> the amba-pl011 driver.

Yes, that's probably OK, but in my series drivers should not be modified at all.
I believe that's better.

>> Do you suggest making up separate new name (like "uart" for 8250) for each type
>> of conosole SPCR can specify?
> 
> These are the documented names of the earlycons, which you'll be using
> when you add the DGB2 table parsing.

SPCR is not about earlycons.

Thank you
Aleksey Makarov

>>> FWIW, PCI earlycon + console support was already submitted once before but
>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>> you would know what to emit for console options in the add_preferred_console().
>>
>> Please do.  Or just send a link to to that submission.
> 
> Ok, will dig through and find it.
> 
>> Do you mean the Leif Lindholm's patches:
> 
> No.
> 
>> https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm@linaro.org
>>
>> He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
>> (I just match SPCR against data that struct uart_port already has)
>> 2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
>> And that's why his submission is RFC: he had troubles with the order of initialization.
>>
>> Thank you
>> Aleksey Makarov
>>
>>> Regards,
>>> Peter Hurley
>>>
>>>
>>>>>> There is an early bootup requirement in Linux.
>>>>>> Maps acquired during the early stage should be freed by the driver during the
>>>>> early stage.
>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>
>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>>> that code can be
>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>>>> example 8250 console)
>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>>> registers a console),
>>>>> We just can not tell if the received table pointer should or sould not be freed
>>>>> with early_memunmap()
>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>> acpi_gbl_permanent_mmap,
>>>>> but that's all too low level.
>>>> [Lv Zheng] 
>>>> The driver should make sure that:
>>>> Map/unmap is paired during early stage.
>>>> For late stage, it should be another pair of map/unmap.
>>>>
>>>>>
>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>> [Lv Zheng] 
>>>> I mean you should free it early.
>>>>
>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>> early_acpi_os_unmap_memory(), that's
>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>>> persistent
>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>> acpi_gbl_permanent_mmap
>>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>>>> not good as it probably is
>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>> Or I probably miss what you are suggesting.
>>>>>
>>>> [Lv Zheng] 
>>>> I mean, you should:
>>>> During early stage:
>>>> acpi_os_map_memory()
>>>> Parse the table.
>>>> acpi_os_unmap_memory().
>>>>
>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>> available for drivers to map memory.
>>>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>>>
>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>> BTW, exactly the same thing is done in the beginning of
>>>>> acpi_os_unmap_memory() and than's ok,
>>>>> that function is __ref.
>>>>>
>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>
>>>>> Could you please tell me where I am wrong?  I still don't understand your point.
>>>> [Lv Zheng] 
>>>> But anyway, the defect should be in ACPI subsystem core.
>>>> The cause should be the API itself - acpi_get_table().
>>>>
>>>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>>>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>>>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>>>
>>>> Thanks and best regards
>>>> -Lv
>>>>
>>>>>
>>>>> Thank you
>>>>> Aleksey Makarov
>>>>>
>>>>>>
>>>>>> Thanks and best regards
>>>>>> -Lv
>>>>>>
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>> ---
>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>>> acpi_size size)
>>>>>>>>  }
>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>
>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>> size)
>>>>>>>> +/*
>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>> + */
>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>> size)
>>>>>>>>  {
>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>> --
>>>>>>>> 2.7.1
> 
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-22 14:35                   ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-22 14:35 UTC (permalink / raw)
  To: Peter Hurley, Zheng, Lv, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

On 02/19/2016 06:25 PM, Peter Hurley wrote:
> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>> Hi Peter,
>>
>> Thank you for review.
>>
>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>> Hi,
>>>>
>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>> early_acpi_os_unmap_memory()
>>>>>
>>>>> Hi Lv,
>>>>>
>>>>> Thank you for review.
>>>>>
>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>
>>>>> [..]
>>>>>
>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>>> set.
>>>>>>>>
>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>
>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>> does.
>>>>>>> [Lv Zheng]
>>>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>>>> in
>>>>>>> case you want to unmap things in any cases.
>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>
>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>
>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>> acpi_get_table_with_size()
>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>>> should be unmapped.
>>>>>
>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>>>> at all.
>>>>>
>>>> [Lv Zheng] 
>>>> This statement is wrong, this should be:
>>>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>> So your argument is wrong from very first point.
>>>>
>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>> acpi_gbl_permanent_mmap.
>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>>>> been set,
>>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>>> and got that oops).
>>>>>
>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>> early_acpi_os_unmap_memory()
>>>>> match perfectly.
>>>> [Lv Zheng] 
>>>> I don't think so.
>>>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>>>> But for the data tables, OSPMs should use them in this way:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structures
>>>> 3. unmap the table
>>>> This helps to shrink virtual memory address space usages.
>>>>
>>>> So from this point of view, all data tables should be unmapped right after being parsed.
>>>> Why do you need the map to be persistent in the kernel address space?
>>>> You can always map a small table, but what if the table size is very big?
>>>>
>>>>>
>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>
>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>
>>>> [Lv Zheng] 
>>>> Just let me ask one more question.
>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>> You can check drivers/acpi/tbxxx.c.
>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>
>>>>>> [Lv Zheng]
>>>>>> One more thing is:
>>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>>> early_acpi_os_unmap_memory(),
>>>>>> then it implies that your driver does have a defect.
>>>>>
>>>>> I still don't understand what defect, sorry.
>>>> [Lv Zheng] 
>>>> If you can't ensure this sequence for using the data tables:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structure
>>>> 3. unmap the table
>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>
>>> Exactly.
>>>
>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>
>>> What should be happening in this series is:
>>> 1. early map SPCR
>>> 2. parse the SPCR table
>>> 3. call add_preferred_console() to add the SPCR console to the console table
>>> 4. unmap SPCR
>>
>> This does not work.  
>>
>> SPCR specifies address of the console, but add_preferred_console() accepts
>> name of console and its index.  There are no general method to translate address
>> to name at such an early stage.
> 
> 
> 	add_preferred_console(uart, 0, "io,0x3f8,115200");

First argument here should be (char *), the name of the console.
We can not tell it just from the SPCR ACPI table without
introducing new made up names and writting which/case that should be 
supported all the linux lifetime.

I am also not quite shure I can tell the number of tty line (the 0 argument)
just from the address.

Did you mean "uart" here?  As far as I can see, this would match the *earlycon*,
not a regular console, that is not what this patch is about.
It is about selecting regular (non-boot) consoles.

I think translating address to string and then parsing it again is not
unaceptable, but definitely worse than the approach in my patch, where
I compare it directly.

> This will start a console with the 8250 driver. I've already pointed
> this out to you in an earlier review. This is what existing firmware
> already does.
> 
> This is also the method you will use to start an earlycon from the
> DBG2 table, by additionally calling setup_earlycon().
> 
> 
>> There is another reason why I prefer to parse SPCR each time a console is registered.
>> Some consoles can be registered very early in the initialization process and
>> we have to be sure add_preferred_console() is called before that.
> 
> However, since you're not adding a preferred console until uart driver
> loads, there may already be a preferred console selected and running.
> 
> This leads to weird issues like duplicated output on the serial console
> when an earlycon is disabled by the dummy VGA/FB console then the
> serial console starts and reprints the entire boot log on the same
> terminal the earlycon already printed.

Yes, misconfigured systems often misbehave.  In this case I would
question why there is an enabled console (we rely on ACPI to enable it).
And I probably do not understand the scenario, but 
- "earlycon is disabled by the dummy VGA/FB console"
and
- "earlycon already printed"
seem a bit contradictory.

> Better just to parse both the DBG2 and SPCR tables before or at
> early param, and add_preferred_consoles then.

I still don't see why it's better, but I think I explained why it's worse.

>> Of course, I could just parse it once and cache the results, but
>> this still requires accessing SPCR before acpi_gbl_permanent_mmap
>> is set *or* after that.
>>
>>> This trivial and unobtrusive method would already have a 8250 console
>>> running via SPCR. I've already pointed this out in previous reviews.
>>>
>>> Further, the above method *will be required anyway* for the DBG2 table to
>>> start an earlycon, which I've already pointed out in previous reviews.
>>>
>>> Then to enable amba-pl011 console via ACPI, add a console match() method
>>> similar to the 8250 console match() method, univ8250_console_match().
>>
>> So are you suggesting a separate method for each possible console?
>> This is not acceptable.
> 
> All 1 of them???

DBG2 specifies these subtypes of serial drivers:

- Fully 16550-compatible
- 16550 subset compatible with DBGP Revision 1
- ARM PL011 UART
- (deprecated) ARM SBSA (2.x only) Generic UART supporting only 32-bit accesses
- ARM SBSA Generic UART
- ARM DCC
- BCM2835

So it's at least 4 (or 3, I am not sure about ARM DCC) different types and
the list is open.  We would have to support it.

> The 8250 driver already does this, so no work for you there.

"uart" is for boot console, so it is not relevant.  Or did you refer to something else?

> That leaves you needing to write a trivial match() method for just
> the amba-pl011 driver.

Yes, that's probably OK, but in my series drivers should not be modified at all.
I believe that's better.

>> Do you suggest making up separate new name (like "uart" for 8250) for each type
>> of conosole SPCR can specify?
> 
> These are the documented names of the earlycons, which you'll be using
> when you add the DGB2 table parsing.

SPCR is not about earlycons.

Thank you
Aleksey Makarov

>>> FWIW, PCI earlycon + console support was already submitted once before but
>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>> you would know what to emit for console options in the add_preferred_console().
>>
>> Please do.  Or just send a link to to that submission.
> 
> Ok, will dig through and find it.
> 
>> Do you mean the Leif Lindholm's patches:
> 
> No.
> 
>> https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm@linaro.org
>>
>> He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
>> (I just match SPCR against data that struct uart_port already has)
>> 2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
>> And that's why his submission is RFC: he had troubles with the order of initialization.
>>
>> Thank you
>> Aleksey Makarov
>>
>>> Regards,
>>> Peter Hurley
>>>
>>>
>>>>>> There is an early bootup requirement in Linux.
>>>>>> Maps acquired during the early stage should be freed by the driver during the
>>>>> early stage.
>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>
>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>>> that code can be
>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>>>> example 8250 console)
>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>>> registers a console),
>>>>> We just can not tell if the received table pointer should or sould not be freed
>>>>> with early_memunmap()
>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>> acpi_gbl_permanent_mmap,
>>>>> but that's all too low level.
>>>> [Lv Zheng] 
>>>> The driver should make sure that:
>>>> Map/unmap is paired during early stage.
>>>> For late stage, it should be another pair of map/unmap.
>>>>
>>>>>
>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>> [Lv Zheng] 
>>>> I mean you should free it early.
>>>>
>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>> early_acpi_os_unmap_memory(), that's
>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>>> persistent
>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>> acpi_gbl_permanent_mmap
>>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>>>> not good as it probably is
>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>> Or I probably miss what you are suggesting.
>>>>>
>>>> [Lv Zheng] 
>>>> I mean, you should:
>>>> During early stage:
>>>> acpi_os_map_memory()
>>>> Parse the table.
>>>> acpi_os_unmap_memory().
>>>>
>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>> available for drivers to map memory.
>>>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>>>
>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>> BTW, exactly the same thing is done in the beginning of
>>>>> acpi_os_unmap_memory() and than's ok,
>>>>> that function is __ref.
>>>>>
>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>
>>>>> Could you please tell me where I am wrong?  I still don't understand your point.
>>>> [Lv Zheng] 
>>>> But anyway, the defect should be in ACPI subsystem core.
>>>> The cause should be the API itself - acpi_get_table().
>>>>
>>>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>>>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>>>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>>>
>>>> Thanks and best regards
>>>> -Lv
>>>>
>>>>>
>>>>> Thank you
>>>>> Aleksey Makarov
>>>>>
>>>>>>
>>>>>> Thanks and best regards
>>>>>> -Lv
>>>>>>
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>> ---
>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>>> acpi_size size)
>>>>>>>>  }
>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>
>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>> size)
>>>>>>>> +/*
>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>> + */
>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>> size)
>>>>>>>>  {
>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>> --
>>>>>>>> 2.7.1
> 
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-22 14:35                   ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-22 14:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/19/2016 06:25 PM, Peter Hurley wrote:
> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>> Hi Peter,
>>
>> Thank you for review.
>>
>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>> Hi,
>>>>
>>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>> early_acpi_os_unmap_memory()
>>>>>
>>>>> Hi Lv,
>>>>>
>>>>> Thank you for review.
>>>>>
>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>
>>>>> [..]
>>>>>
>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>>> set.
>>>>>>>>
>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>
>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>> does.
>>>>>>> [Lv Zheng]
>>>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>>>> in
>>>>>>> case you want to unmap things in any cases.
>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>
>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>
>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>> acpi_get_table_with_size()
>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>>> should be unmapped.
>>>>>
>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>>>> at all.
>>>>>
>>>> [Lv Zheng] 
>>>> This statement is wrong, this should be:
>>>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>> So your argument is wrong from very first point.
>>>>
>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>> acpi_gbl_permanent_mmap.
>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>>>> been set,
>>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>>> and got that oops).
>>>>>
>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>> early_acpi_os_unmap_memory()
>>>>> match perfectly.
>>>> [Lv Zheng] 
>>>> I don't think so.
>>>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>>>> But for the data tables, OSPMs should use them in this way:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structures
>>>> 3. unmap the table
>>>> This helps to shrink virtual memory address space usages.
>>>>
>>>> So from this point of view, all data tables should be unmapped right after being parsed.
>>>> Why do you need the map to be persistent in the kernel address space?
>>>> You can always map a small table, but what if the table size is very big?
>>>>
>>>>>
>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>
>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>
>>>> [Lv Zheng] 
>>>> Just let me ask one more question.
>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>> You can check drivers/acpi/tbxxx.c.
>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>
>>>>>> [Lv Zheng]
>>>>>> One more thing is:
>>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>>> early_acpi_os_unmap_memory(),
>>>>>> then it implies that your driver does have a defect.
>>>>>
>>>>> I still don't understand what defect, sorry.
>>>> [Lv Zheng] 
>>>> If you can't ensure this sequence for using the data tables:
>>>> 1. map the table
>>>> 2. parse the table and convert it to OS specific structure
>>>> 3. unmap the table
>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>
>>> Exactly.
>>>
>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>
>>> What should be happening in this series is:
>>> 1. early map SPCR
>>> 2. parse the SPCR table
>>> 3. call add_preferred_console() to add the SPCR console to the console table
>>> 4. unmap SPCR
>>
>> This does not work.  
>>
>> SPCR specifies address of the console, but add_preferred_console() accepts
>> name of console and its index.  There are no general method to translate address
>> to name at such an early stage.
> 
> 
> 	add_preferred_console(uart, 0, "io,0x3f8,115200");

First argument here should be (char *), the name of the console.
We can not tell it just from the SPCR ACPI table without
introducing new made up names and writting which/case that should be 
supported all the linux lifetime.

I am also not quite shure I can tell the number of tty line (the 0 argument)
just from the address.

Did you mean "uart" here?  As far as I can see, this would match the *earlycon*,
not a regular console, that is not what this patch is about.
It is about selecting regular (non-boot) consoles.

I think translating address to string and then parsing it again is not
unaceptable, but definitely worse than the approach in my patch, where
I compare it directly.

> This will start a console with the 8250 driver. I've already pointed
> this out to you in an earlier review. This is what existing firmware
> already does.
> 
> This is also the method you will use to start an earlycon from the
> DBG2 table, by additionally calling setup_earlycon().
> 
> 
>> There is another reason why I prefer to parse SPCR each time a console is registered.
>> Some consoles can be registered very early in the initialization process and
>> we have to be sure add_preferred_console() is called before that.
> 
> However, since you're not adding a preferred console until uart driver
> loads, there may already be a preferred console selected and running.
> 
> This leads to weird issues like duplicated output on the serial console
> when an earlycon is disabled by the dummy VGA/FB console then the
> serial console starts and reprints the entire boot log on the same
> terminal the earlycon already printed.

Yes, misconfigured systems often misbehave.  In this case I would
question why there is an enabled console (we rely on ACPI to enable it).
And I probably do not understand the scenario, but 
- "earlycon is disabled by the dummy VGA/FB console"
and
- "earlycon already printed"
seem a bit contradictory.

> Better just to parse both the DBG2 and SPCR tables before or at
> early param, and add_preferred_consoles then.

I still don't see why it's better, but I think I explained why it's worse.

>> Of course, I could just parse it once and cache the results, but
>> this still requires accessing SPCR before acpi_gbl_permanent_mmap
>> is set *or* after that.
>>
>>> This trivial and unobtrusive method would already have a 8250 console
>>> running via SPCR. I've already pointed this out in previous reviews.
>>>
>>> Further, the above method *will be required anyway* for the DBG2 table to
>>> start an earlycon, which I've already pointed out in previous reviews.
>>>
>>> Then to enable amba-pl011 console via ACPI, add a console match() method
>>> similar to the 8250 console match() method, univ8250_console_match().
>>
>> So are you suggesting a separate method for each possible console?
>> This is not acceptable.
> 
> All 1 of them???

DBG2 specifies these subtypes of serial drivers:

- Fully 16550-compatible
- 16550 subset compatible with DBGP Revision 1
- ARM PL011 UART
- (deprecated) ARM SBSA (2.x only) Generic UART supporting only 32-bit accesses
- ARM SBSA Generic UART
- ARM DCC
- BCM2835

So it's at least 4 (or 3, I am not sure about ARM DCC) different types and
the list is open.  We would have to support it.

> The 8250 driver already does this, so no work for you there.

"uart" is for boot console, so it is not relevant.  Or did you refer to something else?

> That leaves you needing to write a trivial match() method for just
> the amba-pl011 driver.

Yes, that's probably OK, but in my series drivers should not be modified at all.
I believe that's better.

>> Do you suggest making up separate new name (like "uart" for 8250) for each type
>> of conosole SPCR can specify?
> 
> These are the documented names of the earlycons, which you'll be using
> when you add the DGB2 table parsing.

SPCR is not about earlycons.

Thank you
Aleksey Makarov

>>> FWIW, PCI earlycon + console support was already submitted once before but
>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>> you would know what to emit for console options in the add_preferred_console().
>>
>> Please do.  Or just send a link to to that submission.
> 
> Ok, will dig through and find it.
> 
>> Do you mean the Leif Lindholm's patches:
> 
> No.
> 
>> https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm at linaro.org
>>
>> He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
>> (I just match SPCR against data that struct uart_port already has)
>> 2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
>> And that's why his submission is RFC: he had troubles with the order of initialization.
>>
>> Thank you
>> Aleksey Makarov
>>
>>> Regards,
>>> Peter Hurley
>>>
>>>
>>>>>> There is an early bootup requirement in Linux.
>>>>>> Maps acquired during the early stage should be freed by the driver during the
>>>>> early stage.
>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>
>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>>> that code can be
>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>>>> example 8250 console)
>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>>> registers a console),
>>>>> We just can not tell if the received table pointer should or sould not be freed
>>>>> with early_memunmap()
>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>> acpi_gbl_permanent_mmap,
>>>>> but that's all too low level.
>>>> [Lv Zheng] 
>>>> The driver should make sure that:
>>>> Map/unmap is paired during early stage.
>>>> For late stage, it should be another pair of map/unmap.
>>>>
>>>>>
>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>> [Lv Zheng] 
>>>> I mean you should free it early.
>>>>
>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>> early_acpi_os_unmap_memory(), that's
>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>>> persistent
>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>> acpi_gbl_permanent_mmap
>>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>>>> not good as it probably is
>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>> Or I probably miss what you are suggesting.
>>>>>
>>>> [Lv Zheng] 
>>>> I mean, you should:
>>>> During early stage:
>>>> acpi_os_map_memory()
>>>> Parse the table.
>>>> acpi_os_unmap_memory().
>>>>
>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>> available for drivers to map memory.
>>>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>>>
>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>> BTW, exactly the same thing is done in the beginning of
>>>>> acpi_os_unmap_memory() and than's ok,
>>>>> that function is __ref.
>>>>>
>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>
>>>>> Could you please tell me where I am wrong?  I still don't understand your point.
>>>> [Lv Zheng] 
>>>> But anyway, the defect should be in ACPI subsystem core.
>>>> The cause should be the API itself - acpi_get_table().
>>>>
>>>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>>>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>>>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>>>
>>>> Thanks and best regards
>>>> -Lv
>>>>
>>>>>
>>>>> Thank you
>>>>> Aleksey Makarov
>>>>>
>>>>>>
>>>>>> Thanks and best regards
>>>>>> -Lv
>>>>>>
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>> ---
>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>>> acpi_size size)
>>>>>>>>  }
>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>
>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>> size)
>>>>>>>> +/*
>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>> + */
>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>> size)
>>>>>>>>  {
>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>> --
>>>>>>>> 2.7.1
> 
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-19 17:20                   ` Christopher Covington
  (?)
@ 2016-02-22 14:43                     ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-22 14:43 UTC (permalink / raw)
  To: Christopher Covington, Peter Hurley, Zheng, Lv, linux-acpi, harba
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Len Brown



On 02/19/2016 08:20 PM, Christopher Covington wrote:
> 
> 
> On February 19, 2016 10:25:50 AM EST, Peter Hurley <peter@hurleysoftware.com> wrote:
>> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>>> Hi Peter,
>>>
>>> Thank you for review.
>>>
>>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it
>> calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>> not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from
>> anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access
>> to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>> Console
>>>>>>>>> Redirection) table is needed each time a new console is
>> registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is
>> inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this
>> function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of
>> early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI
>> initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a
>> pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>> unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the
>> pointer should not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve
>> this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>> had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I
>> checked that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng] 
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be
>> references, until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped
>> right after being parsed.
>>>>> Why do you need the map to be persistent in the kernel address
>> space?
>>>>> You can always map a small table, but what if the table size is
>> very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different
>> thing.
>>>>>> Probably it (and/or other functions in that api) should be
>> renamed.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>> instead of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng] 
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI
>> subsystem core.
>>>>
>>>> Exactly.
>>>>
>>>> The central problem here is the way Aleksey is trying to hookup a
>> console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the
>> console table
>>>> 4. unmap SPCR
>>>
>>> This does not work.  
>>>
>>> SPCR specifies address of the console, but add_preferred_console()
>> accepts
>>> name of console and its index.  There are no general method to
>> translate address
>>> to name at such an early stage.
>>
>>
>> 	add_preferred_console(uart, 0, "io,0x3f8,115200");
>>
>> This will start a console with the 8250 driver. I've already pointed
>> this out to you in an earlier review. This is what existing firmware
>> already does.
>>
>> This is also the method you will use to start an earlycon from the
>> DBG2 table, by additionally calling setup_earlycon().
> 
> Can the device specified in DBG2 be used for both earlycon and KGDB? If it can only be used for one, let's make sure the choice of earlycon vs KGDB is intentional rather than accidental.

I just sent the DBG2 series.  It enables an earlycon on DBG2 port with
an "earlycon=acpi_dbg2" option (we can discuss particular name).
If you need KGDB on that port just support it for that port in the kernel
(i. e. add a new instance of ACPI_DBG2_DECLARE() macros for that port, see the patches)
and change the command line options.
I hope that is OK.  We could continue this discussion in the DBG2 thread.

Thank you
Aleksey Makarov

> 
> Thanks,
> Christopher Covington
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-22 14:43                     ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-22 14:43 UTC (permalink / raw)
  To: Christopher Covington, Peter Hurley, Zheng, Lv, linux-acpi, harba
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Len Brown



On 02/19/2016 08:20 PM, Christopher Covington wrote:
> 
> 
> On February 19, 2016 10:25:50 AM EST, Peter Hurley <peter@hurleysoftware.com> wrote:
>> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>>> Hi Peter,
>>>
>>> Thank you for review.
>>>
>>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it
>> calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>> not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from
>> anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access
>> to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>> Console
>>>>>>>>> Redirection) table is needed each time a new console is
>> registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is
>> inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this
>> function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of
>> early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI
>> initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a
>> pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>> unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the
>> pointer should not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve
>> this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>> had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I
>> checked that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng] 
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be
>> references, until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped
>> right after being parsed.
>>>>> Why do you need the map to be persistent in the kernel address
>> space?
>>>>> You can always map a small table, but what if the table size is
>> very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different
>> thing.
>>>>>> Probably it (and/or other functions in that api) should be
>> renamed.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>> instead of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng] 
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI
>> subsystem core.
>>>>
>>>> Exactly.
>>>>
>>>> The central problem here is the way Aleksey is trying to hookup a
>> console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the
>> console table
>>>> 4. unmap SPCR
>>>
>>> This does not work.  
>>>
>>> SPCR specifies address of the console, but add_preferred_console()
>> accepts
>>> name of console and its index.  There are no general method to
>> translate address
>>> to name at such an early stage.
>>
>>
>> 	add_preferred_console(uart, 0, "io,0x3f8,115200");
>>
>> This will start a console with the 8250 driver. I've already pointed
>> this out to you in an earlier review. This is what existing firmware
>> already does.
>>
>> This is also the method you will use to start an earlycon from the
>> DBG2 table, by additionally calling setup_earlycon().
> 
> Can the device specified in DBG2 be used for both earlycon and KGDB? If it can only be used for one, let's make sure the choice of earlycon vs KGDB is intentional rather than accidental.

I just sent the DBG2 series.  It enables an earlycon on DBG2 port with
an "earlycon=acpi_dbg2" option (we can discuss particular name).
If you need KGDB on that port just support it for that port in the kernel
(i. e. add a new instance of ACPI_DBG2_DECLARE() macros for that port, see the patches)
and change the command line options.
I hope that is OK.  We could continue this discussion in the DBG2 thread.

Thank you
Aleksey Makarov

> 
> Thanks,
> Christopher Covington
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-22 14:43                     ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-22 14:43 UTC (permalink / raw)
  To: linux-arm-kernel



On 02/19/2016 08:20 PM, Christopher Covington wrote:
> 
> 
> On February 19, 2016 10:25:50 AM EST, Peter Hurley <peter@hurleysoftware.com> wrote:
>> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>>> Hi Peter,
>>>
>>> Thank you for review.
>>>
>>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it
>> calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>> not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from
>> anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access
>> to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>> Console
>>>>>>>>> Redirection) table is needed each time a new console is
>> registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is
>> inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this
>> function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of
>> early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI
>> initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a
>> pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>> unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the
>> pointer should not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve
>> this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>> had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I
>> checked that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng] 
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be
>> references, until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped
>> right after being parsed.
>>>>> Why do you need the map to be persistent in the kernel address
>> space?
>>>>> You can always map a small table, but what if the table size is
>> very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different
>> thing.
>>>>>> Probably it (and/or other functions in that api) should be
>> renamed.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>> instead of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng] 
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI
>> subsystem core.
>>>>
>>>> Exactly.
>>>>
>>>> The central problem here is the way Aleksey is trying to hookup a
>> console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the
>> console table
>>>> 4. unmap SPCR
>>>
>>> This does not work.  
>>>
>>> SPCR specifies address of the console, but add_preferred_console()
>> accepts
>>> name of console and its index.  There are no general method to
>> translate address
>>> to name at such an early stage.
>>
>>
>> 	add_preferred_console(uart, 0, "io,0x3f8,115200");
>>
>> This will start a console with the 8250 driver. I've already pointed
>> this out to you in an earlier review. This is what existing firmware
>> already does.
>>
>> This is also the method you will use to start an earlycon from the
>> DBG2 table, by additionally calling setup_earlycon().
> 
> Can the device specified in DBG2 be used for both earlycon and KGDB? If it can only be used for one, let's make sure the choice of earlycon vs KGDB is intentional rather than accidental.

I just sent the DBG2 series.  It enables an earlycon on DBG2 port with
an "earlycon=acpi_dbg2" option (we can discuss particular name).
If you need KGDB on that port just support it for that port in the kernel
(i. e. add a new instance of ACPI_DBG2_DECLARE() macros for that port, see the patches)
and change the command line options.
I hope that is OK.  We could continue this discussion in the DBG2 thread.

Thank you
Aleksey Makarov

> 
> Thanks,
> Christopher Covington
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-22  2:24                   ` Zheng, Lv
  (?)
@ 2016-02-22 14:58                     ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-22 14:58 UTC (permalink / raw)
  To: Zheng, Lv, Peter Hurley, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi, 

On 02/22/2016 05:24 AM, Zheng, Lv wrote:
> Hi,
> 
>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> Hi Lv,
>>
>> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>> not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>>>> Console
>>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of
>>>> early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>>>> unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng]
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the pointer should
>>>> not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>>>> had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I checked
>> that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng]
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be
>> references,
>>>> until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped right after
>>>> being parsed.
>>>>> Why do you need the map to be persistent in the kernel address space?
>>>>> You can always map a small table, but what if the table size is very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>>
>>>>> [Lv Zheng]
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead
>> of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng]
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>>
>>>> Exactly.
>>> [Lv Zheng]
>>> So it looks to me:
>>> Changing __init to __ref here is entirely not acceptable.
>>> This API should stay being invoked during early stage.
>>> Otherwise, it may leave us untrackable code that maps tables during early
>> stage and leaks maps to the late stage.
>>> If Linux contains such kind of code, I'm afraid, it will become impossible to
>> introduce acpi_put_table() to clean up the mappings.
>>> Because when acpi_put_table() is called during the late stage to free a map
>> acquired during the early stage, it then obviously will end up with panic.
>>
>> Can you please sugggest a common method to access ACPI tables that
>> works both before *and* after acpi_gbl_permanent_mmap is set and __init
>> code
>> is removed?
> [Lv Zheng] 
> Do not change __init for now.
> 
> Currently you should:
> 1. before acpi_gbl_permanent_mmap is set:
> acpi_get_table_with_size()
> parse the table
> early_acpi_os_unmap_memory()
> Do your driver early stuff here
> 
> 2. after acpi_gbl_permanent_mmap is set:
> acpi_get_table()
> Parse the table
> Do your driver late stuff here
> <- note there is no API now being an inverse of acpi_get_table().

That's fine.  These are two different methods to access the table.
I need one that works in both cases.  Of course, they could be combined,
but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
seems to be an implementation detail of ACPI code.

Instead I am going to use the 1st method once and cache the result like this:


static int __init parse(void)
{
	static bool parsed;

	if (!parsed) {
		acpi_get_table_with_size()
		/* parse the table and cache the result */
		early_acpi_os_unmap_memory()
		parse = true;
	}
}

arch_initcal(parse());

int __ref the_handler_where_I_need_the_parse_results(void)
{
	parse();

	/* use the data */
}

I hope you are OK with it.

> Besides, I'm about to insert error messages between 1 and 2.
> If an early map is not release, error message will be prompted to the developers.

AFAICS, there is such an error message and I saw it.
Refer to check_early_ioremap_leak() at mm/early_ioremap.c

> And if you don't follow the above rules, it mean you are trying to lay a mine, waiting for me to step on it.
> That's why this change is entirely not acceptable.

Ok, I see.

> I'm about to send out the cleanup series in 1 week, and will Cc you.
> You can rebase your code on top of the cleanup series.

Thank you
Aleksey Makarov

> 
> Thanks and best regards
> -Lv
> 
>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the console
>> table
>>>> 4. unmap SPCR
>>>>
>>>> This trivial and unobtrusive method would already have a 8250 console
>>>> running via SPCR. I've already pointed this out in previous reviews.
>>>>
>>>> Further, the above method *will be required anyway* for the DBG2 table to
>>>> start an earlycon, which I've already pointed out in previous reviews.
>>>>
>>>> Then to enable amba-pl011 console via ACPI, add a console match() method
>>>> similar to the 8250 console match() method, univ8250_console_match().
>>>>
>>>> FWIW, PCI earlycon + console support was already submitted once before
>> but
>>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>>> you would know what to emit for console options in the
>>>> add_preferred_console().
>>>>
>>>>
>>>> Regards,
>>>> Peter Hurley
>>>>
>>>>
>>>>>>> There is an early bootup requirement in Linux.
>>>>>>> Maps acquired during the early stage should be freed by the driver during
>>>> the
>>>>>> early stage.
>>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>>
>>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
>> that
>>>>>> that code can be
>>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
>> of
>>>> for
>>>>>> example 8250 console)
>>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
>> that
>>>>>> registers a console),
>>>>>> We just can not tell if the received table pointer should or sould not be
>> freed
>>>>>> with early_memunmap()
>>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>>> acpi_gbl_permanent_mmap,
>>>>>> but that's all too low level.
>>>>> [Lv Zheng]
>>>>> The driver should make sure that:
>>>>> Map/unmap is paired during early stage.
>>>>> For late stage, it should be another pair of map/unmap.
>>>>>
>>>>>>
>>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>>> [Lv Zheng]
>>>>> I mean you should free it early.
>>>>>
>>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>>> early_acpi_os_unmap_memory(), that's
>>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
>> the
>>>>>> persistent
>>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>>> acpi_gbl_permanent_mmap
>>>>>> to catch this exact moment.  And also accessing
>> acpi_gbl_permanent_mmap
>>>> is
>>>>>> not good as it probably is
>>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>>> Or I probably miss what you are suggesting.
>>>>>>
>>>>> [Lv Zheng]
>>>>> I mean, you should:
>>>>> During early stage:
>>>>> acpi_os_map_memory()
>>>>> Parse the table.
>>>>> acpi_os_unmap_memory().
>>>>>
>>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>>> available for drivers to map memory.
>>>>>>> So by changing __init to __ref here, you probably will hide many such
>>>> defects.
>>>>>>
>>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>>> BTW, exactly the same thing is done in the beginning of
>>>>>> acpi_os_unmap_memory() and than's ok,
>>>>>> that function is __ref.
>>>>>>
>>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>>
>>>>>> Could you please tell me where I am wrong?  I still don't understand your
>>>> point.
>>>>> [Lv Zheng]
>>>>> But anyway, the defect should be in ACPI subsystem core.
>>>>> The cause should be the API itself - acpi_get_table().
>>>>>
>>>>> So I agree you can use early_acpi_os_unmap_memory() during the period
>> the
>>>> root causes are not cleaned up.
>>>>> But the bottom line is: the driver need to ensure that
>>>> early_acpi_os_unmap_memory() is always invoked.
>>>>> As long as you can ensure this, I don't have objections for deploying
>>>> early_acpi_os_unmap_memory()  for now.
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thank you
>>>>>> Aleksey Makarov
>>>>>>
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Thanks and best regards
>>>>>>>> -Lv
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>>> ---
>>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
>> *virt,
>>>>>>>>> acpi_size size)
>>>>>>>>>  }
>>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>>
>>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
>>>> acpi_size
>>>>>>>> size)
>>>>>>>>> +/*
>>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
>> anywhere
>>>>>>>>> + */
>>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
>>>> acpi_size
>>>>>>>> size)
>>>>>>>>>  {
>>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>>> --
>>>>>>>>> 2.7.1
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
>> info.html
>>>>>>>> --
>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-22 14:58                     ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-22 14:58 UTC (permalink / raw)
  To: Zheng, Lv, Peter Hurley, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi, 

On 02/22/2016 05:24 AM, Zheng, Lv wrote:
> Hi,
> 
>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> Hi Lv,
>>
>> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>> not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>>>> Console
>>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of
>>>> early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>>>> unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng]
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the pointer should
>>>> not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>>>> had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I checked
>> that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng]
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be
>> references,
>>>> until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped right after
>>>> being parsed.
>>>>> Why do you need the map to be persistent in the kernel address space?
>>>>> You can always map a small table, but what if the table size is very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>>
>>>>> [Lv Zheng]
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead
>> of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng]
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>>
>>>> Exactly.
>>> [Lv Zheng]
>>> So it looks to me:
>>> Changing __init to __ref here is entirely not acceptable.
>>> This API should stay being invoked during early stage.
>>> Otherwise, it may leave us untrackable code that maps tables during early
>> stage and leaks maps to the late stage.
>>> If Linux contains such kind of code, I'm afraid, it will become impossible to
>> introduce acpi_put_table() to clean up the mappings.
>>> Because when acpi_put_table() is called during the late stage to free a map
>> acquired during the early stage, it then obviously will end up with panic.
>>
>> Can you please sugggest a common method to access ACPI tables that
>> works both before *and* after acpi_gbl_permanent_mmap is set and __init
>> code
>> is removed?
> [Lv Zheng] 
> Do not change __init for now.
> 
> Currently you should:
> 1. before acpi_gbl_permanent_mmap is set:
> acpi_get_table_with_size()
> parse the table
> early_acpi_os_unmap_memory()
> Do your driver early stuff here
> 
> 2. after acpi_gbl_permanent_mmap is set:
> acpi_get_table()
> Parse the table
> Do your driver late stuff here
> <- note there is no API now being an inverse of acpi_get_table().

That's fine.  These are two different methods to access the table.
I need one that works in both cases.  Of course, they could be combined,
but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
seems to be an implementation detail of ACPI code.

Instead I am going to use the 1st method once and cache the result like this:


static int __init parse(void)
{
	static bool parsed;

	if (!parsed) {
		acpi_get_table_with_size()
		/* parse the table and cache the result */
		early_acpi_os_unmap_memory()
		parse = true;
	}
}

arch_initcal(parse());

int __ref the_handler_where_I_need_the_parse_results(void)
{
	parse();

	/* use the data */
}

I hope you are OK with it.

> Besides, I'm about to insert error messages between 1 and 2.
> If an early map is not release, error message will be prompted to the developers.

AFAICS, there is such an error message and I saw it.
Refer to check_early_ioremap_leak() at mm/early_ioremap.c

> And if you don't follow the above rules, it mean you are trying to lay a mine, waiting for me to step on it.
> That's why this change is entirely not acceptable.

Ok, I see.

> I'm about to send out the cleanup series in 1 week, and will Cc you.
> You can rebase your code on top of the cleanup series.

Thank you
Aleksey Makarov

> 
> Thanks and best regards
> -Lv
> 
>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the console
>> table
>>>> 4. unmap SPCR
>>>>
>>>> This trivial and unobtrusive method would already have a 8250 console
>>>> running via SPCR. I've already pointed this out in previous reviews.
>>>>
>>>> Further, the above method *will be required anyway* for the DBG2 table to
>>>> start an earlycon, which I've already pointed out in previous reviews.
>>>>
>>>> Then to enable amba-pl011 console via ACPI, add a console match() method
>>>> similar to the 8250 console match() method, univ8250_console_match().
>>>>
>>>> FWIW, PCI earlycon + console support was already submitted once before
>> but
>>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>>> you would know what to emit for console options in the
>>>> add_preferred_console().
>>>>
>>>>
>>>> Regards,
>>>> Peter Hurley
>>>>
>>>>
>>>>>>> There is an early bootup requirement in Linux.
>>>>>>> Maps acquired during the early stage should be freed by the driver during
>>>> the
>>>>>> early stage.
>>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>>
>>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
>> that
>>>>>> that code can be
>>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
>> of
>>>> for
>>>>>> example 8250 console)
>>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
>> that
>>>>>> registers a console),
>>>>>> We just can not tell if the received table pointer should or sould not be
>> freed
>>>>>> with early_memunmap()
>>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>>> acpi_gbl_permanent_mmap,
>>>>>> but that's all too low level.
>>>>> [Lv Zheng]
>>>>> The driver should make sure that:
>>>>> Map/unmap is paired during early stage.
>>>>> For late stage, it should be another pair of map/unmap.
>>>>>
>>>>>>
>>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>>> [Lv Zheng]
>>>>> I mean you should free it early.
>>>>>
>>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>>> early_acpi_os_unmap_memory(), that's
>>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
>> the
>>>>>> persistent
>>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>>> acpi_gbl_permanent_mmap
>>>>>> to catch this exact moment.  And also accessing
>> acpi_gbl_permanent_mmap
>>>> is
>>>>>> not good as it probably is
>>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>>> Or I probably miss what you are suggesting.
>>>>>>
>>>>> [Lv Zheng]
>>>>> I mean, you should:
>>>>> During early stage:
>>>>> acpi_os_map_memory()
>>>>> Parse the table.
>>>>> acpi_os_unmap_memory().
>>>>>
>>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>>> available for drivers to map memory.
>>>>>>> So by changing __init to __ref here, you probably will hide many such
>>>> defects.
>>>>>>
>>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>>> BTW, exactly the same thing is done in the beginning of
>>>>>> acpi_os_unmap_memory() and than's ok,
>>>>>> that function is __ref.
>>>>>>
>>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>>
>>>>>> Could you please tell me where I am wrong?  I still don't understand your
>>>> point.
>>>>> [Lv Zheng]
>>>>> But anyway, the defect should be in ACPI subsystem core.
>>>>> The cause should be the API itself - acpi_get_table().
>>>>>
>>>>> So I agree you can use early_acpi_os_unmap_memory() during the period
>> the
>>>> root causes are not cleaned up.
>>>>> But the bottom line is: the driver need to ensure that
>>>> early_acpi_os_unmap_memory() is always invoked.
>>>>> As long as you can ensure this, I don't have objections for deploying
>>>> early_acpi_os_unmap_memory()  for now.
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thank you
>>>>>> Aleksey Makarov
>>>>>>
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Thanks and best regards
>>>>>>>> -Lv
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>>> ---
>>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
>> *virt,
>>>>>>>>> acpi_size size)
>>>>>>>>>  }
>>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>>
>>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
>>>> acpi_size
>>>>>>>> size)
>>>>>>>>> +/*
>>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
>> anywhere
>>>>>>>>> + */
>>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
>>>> acpi_size
>>>>>>>> size)
>>>>>>>>>  {
>>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>>> --
>>>>>>>>> 2.7.1
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
>> info.html
>>>>>>>> --
>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-22 14:58                     ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-22 14:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi, 

On 02/22/2016 05:24 AM, Zheng, Lv wrote:
> Hi,
> 
>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> Hi Lv,
>>
>> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Peter Hurley [mailto:peter at hurleysoftware.com]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is
>> not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>>>> Console
>>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of
>>>> early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>>>> unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng]
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the pointer should
>>>> not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap
>>>> had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I checked
>> that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng]
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be
>> references,
>>>> until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped right after
>>>> being parsed.
>>>>> Why do you need the map to be persistent in the kernel address space?
>>>>> You can always map a small table, but what if the table size is very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>>
>>>>> [Lv Zheng]
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead
>> of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng]
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>>
>>>> Exactly.
>>> [Lv Zheng]
>>> So it looks to me:
>>> Changing __init to __ref here is entirely not acceptable.
>>> This API should stay being invoked during early stage.
>>> Otherwise, it may leave us untrackable code that maps tables during early
>> stage and leaks maps to the late stage.
>>> If Linux contains such kind of code, I'm afraid, it will become impossible to
>> introduce acpi_put_table() to clean up the mappings.
>>> Because when acpi_put_table() is called during the late stage to free a map
>> acquired during the early stage, it then obviously will end up with panic.
>>
>> Can you please sugggest a common method to access ACPI tables that
>> works both before *and* after acpi_gbl_permanent_mmap is set and __init
>> code
>> is removed?
> [Lv Zheng] 
> Do not change __init for now.
> 
> Currently you should:
> 1. before acpi_gbl_permanent_mmap is set:
> acpi_get_table_with_size()
> parse the table
> early_acpi_os_unmap_memory()
> Do your driver early stuff here
> 
> 2. after acpi_gbl_permanent_mmap is set:
> acpi_get_table()
> Parse the table
> Do your driver late stuff here
> <- note there is no API now being an inverse of acpi_get_table().

That's fine.  These are two different methods to access the table.
I need one that works in both cases.  Of course, they could be combined,
but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
seems to be an implementation detail of ACPI code.

Instead I am going to use the 1st method once and cache the result like this:


static int __init parse(void)
{
	static bool parsed;

	if (!parsed) {
		acpi_get_table_with_size()
		/* parse the table and cache the result */
		early_acpi_os_unmap_memory()
		parse = true;
	}
}

arch_initcal(parse());

int __ref the_handler_where_I_need_the_parse_results(void)
{
	parse();

	/* use the data */
}

I hope you are OK with it.

> Besides, I'm about to insert error messages between 1 and 2.
> If an early map is not release, error message will be prompted to the developers.

AFAICS, there is such an error message and I saw it.
Refer to check_early_ioremap_leak() at mm/early_ioremap.c

> And if you don't follow the above rules, it mean you are trying to lay a mine, waiting for me to step on it.
> That's why this change is entirely not acceptable.

Ok, I see.

> I'm about to send out the cleanup series in 1 week, and will Cc you.
> You can rebase your code on top of the cleanup series.

Thank you
Aleksey Makarov

> 
> Thanks and best regards
> -Lv
> 
>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the console
>> table
>>>> 4. unmap SPCR
>>>>
>>>> This trivial and unobtrusive method would already have a 8250 console
>>>> running via SPCR. I've already pointed this out in previous reviews.
>>>>
>>>> Further, the above method *will be required anyway* for the DBG2 table to
>>>> start an earlycon, which I've already pointed out in previous reviews.
>>>>
>>>> Then to enable amba-pl011 console via ACPI, add a console match() method
>>>> similar to the 8250 console match() method, univ8250_console_match().
>>>>
>>>> FWIW, PCI earlycon + console support was already submitted once before
>> but
>>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>>> you would know what to emit for console options in the
>>>> add_preferred_console().
>>>>
>>>>
>>>> Regards,
>>>> Peter Hurley
>>>>
>>>>
>>>>>>> There is an early bootup requirement in Linux.
>>>>>>> Maps acquired during the early stage should be freed by the driver during
>>>> the
>>>>>> early stage.
>>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>>
>>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
>> that
>>>>>> that code can be
>>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
>> of
>>>> for
>>>>>> example 8250 console)
>>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
>> that
>>>>>> registers a console),
>>>>>> We just can not tell if the received table pointer should or sould not be
>> freed
>>>>>> with early_memunmap()
>>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>>> acpi_gbl_permanent_mmap,
>>>>>> but that's all too low level.
>>>>> [Lv Zheng]
>>>>> The driver should make sure that:
>>>>> Map/unmap is paired during early stage.
>>>>> For late stage, it should be another pair of map/unmap.
>>>>>
>>>>>>
>>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>>> [Lv Zheng]
>>>>> I mean you should free it early.
>>>>>
>>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>>> early_acpi_os_unmap_memory(), that's
>>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
>> the
>>>>>> persistent
>>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>>> acpi_gbl_permanent_mmap
>>>>>> to catch this exact moment.  And also accessing
>> acpi_gbl_permanent_mmap
>>>> is
>>>>>> not good as it probably is
>>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>>> Or I probably miss what you are suggesting.
>>>>>>
>>>>> [Lv Zheng]
>>>>> I mean, you should:
>>>>> During early stage:
>>>>> acpi_os_map_memory()
>>>>> Parse the table.
>>>>> acpi_os_unmap_memory().
>>>>>
>>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>>> available for drivers to map memory.
>>>>>>> So by changing __init to __ref here, you probably will hide many such
>>>> defects.
>>>>>>
>>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>>> BTW, exactly the same thing is done in the beginning of
>>>>>> acpi_os_unmap_memory() and than's ok,
>>>>>> that function is __ref.
>>>>>>
>>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>>
>>>>>> Could you please tell me where I am wrong?  I still don't understand your
>>>> point.
>>>>> [Lv Zheng]
>>>>> But anyway, the defect should be in ACPI subsystem core.
>>>>> The cause should be the API itself - acpi_get_table().
>>>>>
>>>>> So I agree you can use early_acpi_os_unmap_memory() during the period
>> the
>>>> root causes are not cleaned up.
>>>>> But the bottom line is: the driver need to ensure that
>>>> early_acpi_os_unmap_memory() is always invoked.
>>>>> As long as you can ensure this, I don't have objections for deploying
>>>> early_acpi_os_unmap_memory()  for now.
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thank you
>>>>>> Aleksey Makarov
>>>>>>
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Thanks and best regards
>>>>>>>> -Lv
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>>> ---
>>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
>> *virt,
>>>>>>>>> acpi_size size)
>>>>>>>>>  }
>>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>>
>>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
>>>> acpi_size
>>>>>>>> size)
>>>>>>>>> +/*
>>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
>> anywhere
>>>>>>>>> + */
>>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
>>>> acpi_size
>>>>>>>> size)
>>>>>>>>>  {
>>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>>> --
>>>>>>>>> 2.7.1
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>>>> the body of a message to majordomo at vger.kernel.org
>>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
>> info.html
>>>>>>>> --
>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>>> the body of a message to majordomo at vger.kernel.org
>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
  2016-02-21  9:42     ` Yury Norov
@ 2016-02-22 15:03       ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-22 15:03 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-acpi, Russell King, Graeme Gregory, Greg Kroah-Hartman,
	Rafael J . Wysocki, linux-kernel, Leif Lindholm,
	Christopher Covington, linux-serial, Jiri Slaby, Al Stone,
	linux-arm-kernel, Len Brown

Hi Yury,

Thank you for review/suggestions.  I will address it all in the next version except for...

On 02/21/2016 12:42 PM, Yury Norov wrote:
> On Mon, Feb 15, 2016 at 09:05:26PM +0300, Aleksey Makarov wrote:
>> 'ARM Server Base Boot Requiremets' [1] mentions SPCR (Serial Port
>> Console Redirection Table) [2] as a mandatory ACPI table that
>> specifies the configuration of serial console.
>>
>> Parse this table and check if any registered console match the
>> description.  If it does, enable that console.
>>
>> Introduce a new function acpi_console_check().  At the uart port
>> registration, this function checks if the ACPI SPCR table specifies
>> its argument of type struct uart_port to be a console
>> and if so calls add_preferred_console().
>>
>> [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
>> [2] http://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx
>>
>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>> ---
>>  drivers/acpi/Kconfig             |  3 ++
>>  drivers/acpi/Makefile            |  1 +
>>  drivers/acpi/spcr.c              | 97 ++++++++++++++++++++++++++++++++++++++++
>>  drivers/tty/serial/serial_core.c | 14 +++++-
>>  include/linux/acpi.h             | 10 +++++
>>  5 files changed, 123 insertions(+), 2 deletions(-)
>>  create mode 100644 drivers/acpi/spcr.c
>>
>> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
>> index 65fb483..5611eb6 100644
>> --- a/drivers/acpi/Kconfig
>> +++ b/drivers/acpi/Kconfig
>> @@ -77,6 +77,9 @@ config ACPI_DEBUGGER_USER
>>  
>>  endif
>>  
>> +config ACPI_SPCR_TABLE
>> +	bool
>> +
>>  config ACPI_SLEEP
>>  	bool
>>  	depends on SUSPEND || HIBERNATION
>> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
>> index 346101c..708b143 100644
>> --- a/drivers/acpi/Makefile
>> +++ b/drivers/acpi/Makefile
>> @@ -81,6 +81,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
>>  obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
>> +obj-$(CONFIG_ACPI_SPCR_TABLE)	+= spcr.o
>>  obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
>>  
>>  # processor has its own "processor." module_param namespace
>> diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
>> new file mode 100644
>> index 0000000..a1eca91
>> --- /dev/null
>> +++ b/drivers/acpi/spcr.c
>> @@ -0,0 +1,97 @@
>> +/*
>> + * Copyright (c) 2012, Intel Corporation
>> + * Copyright (c) 2015, Red Hat, Inc.
>> + * Copyright (c) 2015, 2016 Linaro Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + */
>> +
>> +#define pr_fmt(fmt) "ACPI: SPCR: " fmt
>> +
>> +#include <linux/acpi.h>
>> +#include <linux/console.h>
>> +#include <linux/kernel.h>
>> +#include <linux/serial_core.h>
>> +
>> +static int acpi_table_parse_spcr(int (*handler)(struct acpi_table_spcr *table,
>> +						void *data), void *data)
>> +{
>> +	struct acpi_table_spcr *table = NULL;
> Hi Alexey,
> 
> Few minor comments...
> 
> Are you sure you need thin initialization?
> 
>> +	acpi_size table_size;
>> +	acpi_status status;
>> +	int err;
>> +
>> +	status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0,
>> +					  (struct acpi_table_header **)&table,
>> +					  &table_size);
>> +
>> +	if (ACPI_FAILURE(status))
>> +		return -ENODEV;
>> +
>> +	err = handler(table, data);
>> +
>> +	early_acpi_os_unmap_memory(table, table_size);
>> +
>> +	return err;
>> +}
>> +
>> +static int spcr_table_handler_check(struct acpi_table_spcr *table, void *data)
> 
> The name of function is not clear for me.
> You're not only checking here, but also
> adding console. 
> 
>> +{
>> +	struct uart_port *uport = data;
>> +	char *options;
>> +
>> +	if (table->header.revision < 2)
>> +		return -EOPNOTSUPP;
>> +
>> +	switch (table->baud_rate) {
> 
> You don't need 'options' if your big condition returns false,
> so you can evaluate it inside conditional block.
> 
>> +	case 3:
>> +		options = "9600";
>> +		break;
>> +	case 4:
>> +		options = "19200";
>> +		break;
>> +	case 6:
>> +		options = "57600";
>> +		break;
>> +	case 7:
>> +		options = "115200";
>> +		break;
>> +	default:
>> +		options = "";
>> +		break;
> 
> 'break' isnot needed here

... except for this.

No, it is not, but C language style guides tell us to have it here.
Also see the first example from Documentation/CodingStyle 
where they have it.

Thank you
Aleksey Makarov

> 
>> +	}
>> +
>> +	if ((table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY &&
> 
> Nitpick: just for better readability, I'd split it onto a set of
> separated checks:
> 
>         foo() {
>                 if (!cond1)
>                         return 0;
> 
>                 if (!cond2)
>                         return 0;
>                 ...
> 
>                 switch () {
>                 case 1:
>                         ...
>                 case 2:
>                         ...
>                 case 3:
>                         ...
>                 default:
>                         ...
>                 }
>                 
>                 return 1;
>         }
> 
>> +	     table->serial_port.address == (u64)uport->mapbase) ||
>> +	    (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_IO &&
>> +	     table->serial_port.address == (u64)uport->iobase)) {
>> +		pr_info("adding preferred console [%s%d]\n", uport->cons->name,
>> +			uport->line);
>> +		add_preferred_console(uport->cons->name, uport->line, options);
>> +		return 1;
>> +
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * acpi_console_check - Check if uart matches the console specified by SPCR.
>> + *
>> + * @uport:	uart port to check
>> + *
>> + * This function checks if the ACPI SPCR table specifies @uport to be a console
>> + * and if so calls add_preferred_console()
>> + *
>> + * Return: a non-error value if the console matches.
>> + */
>> +bool acpi_console_check(struct uart_port *uport)
>> +{
>> +	if (acpi_disabled || console_set_on_cmdline)
>> +		return false;
>> +
>> +	return acpi_table_parse_spcr(spcr_table_handler_check, uport) > 0;
>> +}
>> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
>> index a126a60..459ab54 100644
>> --- a/drivers/tty/serial/serial_core.c
>> +++ b/drivers/tty/serial/serial_core.c
>> @@ -34,6 +34,7 @@
>>  #include <linux/serial_core.h>
>>  #include <linux/delay.h>
>>  #include <linux/mutex.h>
>> +#include <linux/acpi.h>
>>  
>>  #include <asm/irq.h>
>>  #include <asm/uaccess.h>
>> @@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>>  		spin_lock_init(&uport->lock);
>>  		lockdep_set_class(&uport->lock, &port_lock_key);
>>  	}
>> -	if (uport->cons && uport->dev)
>> -		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
>> +
>> +	/*
>> +	 * Support both open FW and ACPI access to console definitions.
>> +	 * Both of_console_check() and acpi_console_check() will call
>> +	 * add_preferred_console() if a console definition is found.
>> +	 */
>> +	if (uport->cons && uport->dev) {
>> +		if (!acpi_console_check(uport))
>> +			of_console_check(uport->dev->of_node, uport->cons->name,
>> +					 uport->line);
>> +	}
>>  
>>  	uart_configure_port(drv, state, uport);
>>  
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 06ed7e5..ea0c297 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
>>  #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
>>  #endif
>>  
>> +struct uart_port;
>> +#ifdef CONFIG_ACPI_SPCR_TABLE
>> +bool acpi_console_check(struct uart_port *uport);
>> +#else
>> +static inline bool acpi_console_check(struct uart_port *uport)
>> +{
>> +	return FALSE;
>> +}
>> +#endif
>> +
>>  #endif	/*_LINUX_ACPI_H*/
>> -- 
>> 2.7.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 2/5] ACPI: parse SPCR and enable matching console
@ 2016-02-22 15:03       ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-22 15:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Yury,

Thank you for review/suggestions.  I will address it all in the next version except for...

On 02/21/2016 12:42 PM, Yury Norov wrote:
> On Mon, Feb 15, 2016 at 09:05:26PM +0300, Aleksey Makarov wrote:
>> 'ARM Server Base Boot Requiremets' [1] mentions SPCR (Serial Port
>> Console Redirection Table) [2] as a mandatory ACPI table that
>> specifies the configuration of serial console.
>>
>> Parse this table and check if any registered console match the
>> description.  If it does, enable that console.
>>
>> Introduce a new function acpi_console_check().  At the uart port
>> registration, this function checks if the ACPI SPCR table specifies
>> its argument of type struct uart_port to be a console
>> and if so calls add_preferred_console().
>>
>> [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
>> [2] http://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx
>>
>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>> ---
>>  drivers/acpi/Kconfig             |  3 ++
>>  drivers/acpi/Makefile            |  1 +
>>  drivers/acpi/spcr.c              | 97 ++++++++++++++++++++++++++++++++++++++++
>>  drivers/tty/serial/serial_core.c | 14 +++++-
>>  include/linux/acpi.h             | 10 +++++
>>  5 files changed, 123 insertions(+), 2 deletions(-)
>>  create mode 100644 drivers/acpi/spcr.c
>>
>> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
>> index 65fb483..5611eb6 100644
>> --- a/drivers/acpi/Kconfig
>> +++ b/drivers/acpi/Kconfig
>> @@ -77,6 +77,9 @@ config ACPI_DEBUGGER_USER
>>  
>>  endif
>>  
>> +config ACPI_SPCR_TABLE
>> +	bool
>> +
>>  config ACPI_SLEEP
>>  	bool
>>  	depends on SUSPEND || HIBERNATION
>> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
>> index 346101c..708b143 100644
>> --- a/drivers/acpi/Makefile
>> +++ b/drivers/acpi/Makefile
>> @@ -81,6 +81,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
>>  obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
>> +obj-$(CONFIG_ACPI_SPCR_TABLE)	+= spcr.o
>>  obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o
>>  
>>  # processor has its own "processor." module_param namespace
>> diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
>> new file mode 100644
>> index 0000000..a1eca91
>> --- /dev/null
>> +++ b/drivers/acpi/spcr.c
>> @@ -0,0 +1,97 @@
>> +/*
>> + * Copyright (c) 2012, Intel Corporation
>> + * Copyright (c) 2015, Red Hat, Inc.
>> + * Copyright (c) 2015, 2016 Linaro Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + */
>> +
>> +#define pr_fmt(fmt) "ACPI: SPCR: " fmt
>> +
>> +#include <linux/acpi.h>
>> +#include <linux/console.h>
>> +#include <linux/kernel.h>
>> +#include <linux/serial_core.h>
>> +
>> +static int acpi_table_parse_spcr(int (*handler)(struct acpi_table_spcr *table,
>> +						void *data), void *data)
>> +{
>> +	struct acpi_table_spcr *table = NULL;
> Hi Alexey,
> 
> Few minor comments...
> 
> Are you sure you need thin initialization?
> 
>> +	acpi_size table_size;
>> +	acpi_status status;
>> +	int err;
>> +
>> +	status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0,
>> +					  (struct acpi_table_header **)&table,
>> +					  &table_size);
>> +
>> +	if (ACPI_FAILURE(status))
>> +		return -ENODEV;
>> +
>> +	err = handler(table, data);
>> +
>> +	early_acpi_os_unmap_memory(table, table_size);
>> +
>> +	return err;
>> +}
>> +
>> +static int spcr_table_handler_check(struct acpi_table_spcr *table, void *data)
> 
> The name of function is not clear for me.
> You're not only checking here, but also
> adding console. 
> 
>> +{
>> +	struct uart_port *uport = data;
>> +	char *options;
>> +
>> +	if (table->header.revision < 2)
>> +		return -EOPNOTSUPP;
>> +
>> +	switch (table->baud_rate) {
> 
> You don't need 'options' if your big condition returns false,
> so you can evaluate it inside conditional block.
> 
>> +	case 3:
>> +		options = "9600";
>> +		break;
>> +	case 4:
>> +		options = "19200";
>> +		break;
>> +	case 6:
>> +		options = "57600";
>> +		break;
>> +	case 7:
>> +		options = "115200";
>> +		break;
>> +	default:
>> +		options = "";
>> +		break;
> 
> 'break' isnot needed here

... except for this.

No, it is not, but C language style guides tell us to have it here.
Also see the first example from Documentation/CodingStyle 
where they have it.

Thank you
Aleksey Makarov

> 
>> +	}
>> +
>> +	if ((table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY &&
> 
> Nitpick: just for better readability, I'd split it onto a set of
> separated checks:
> 
>         foo() {
>                 if (!cond1)
>                         return 0;
> 
>                 if (!cond2)
>                         return 0;
>                 ...
> 
>                 switch () {
>                 case 1:
>                         ...
>                 case 2:
>                         ...
>                 case 3:
>                         ...
>                 default:
>                         ...
>                 }
>                 
>                 return 1;
>         }
> 
>> +	     table->serial_port.address == (u64)uport->mapbase) ||
>> +	    (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_IO &&
>> +	     table->serial_port.address == (u64)uport->iobase)) {
>> +		pr_info("adding preferred console [%s%d]\n", uport->cons->name,
>> +			uport->line);
>> +		add_preferred_console(uport->cons->name, uport->line, options);
>> +		return 1;
>> +
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/**
>> + * acpi_console_check - Check if uart matches the console specified by SPCR.
>> + *
>> + * @uport:	uart port to check
>> + *
>> + * This function checks if the ACPI SPCR table specifies @uport to be a console
>> + * and if so calls add_preferred_console()
>> + *
>> + * Return: a non-error value if the console matches.
>> + */
>> +bool acpi_console_check(struct uart_port *uport)
>> +{
>> +	if (acpi_disabled || console_set_on_cmdline)
>> +		return false;
>> +
>> +	return acpi_table_parse_spcr(spcr_table_handler_check, uport) > 0;
>> +}
>> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
>> index a126a60..459ab54 100644
>> --- a/drivers/tty/serial/serial_core.c
>> +++ b/drivers/tty/serial/serial_core.c
>> @@ -34,6 +34,7 @@
>>  #include <linux/serial_core.h>
>>  #include <linux/delay.h>
>>  #include <linux/mutex.h>
>> +#include <linux/acpi.h>
>>  
>>  #include <asm/irq.h>
>>  #include <asm/uaccess.h>
>> @@ -2654,8 +2655,17 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
>>  		spin_lock_init(&uport->lock);
>>  		lockdep_set_class(&uport->lock, &port_lock_key);
>>  	}
>> -	if (uport->cons && uport->dev)
>> -		of_console_check(uport->dev->of_node, uport->cons->name, uport->line);
>> +
>> +	/*
>> +	 * Support both open FW and ACPI access to console definitions.
>> +	 * Both of_console_check() and acpi_console_check() will call
>> +	 * add_preferred_console() if a console definition is found.
>> +	 */
>> +	if (uport->cons && uport->dev) {
>> +		if (!acpi_console_check(uport))
>> +			of_console_check(uport->dev->of_node, uport->cons->name,
>> +					 uport->line);
>> +	}
>>  
>>  	uart_configure_port(drv, state, uport);
>>  
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 06ed7e5..ea0c297 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -1004,4 +1004,14 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
>>  #define acpi_probe_device_table(t)	({ int __r = 0; __r;})
>>  #endif
>>  
>> +struct uart_port;
>> +#ifdef CONFIG_ACPI_SPCR_TABLE
>> +bool acpi_console_check(struct uart_port *uport);
>> +#else
>> +static inline bool acpi_console_check(struct uart_port *uport)
>> +{
>> +	return FALSE;
>> +}
>> +#endif
>> +
>>  #endif	/*_LINUX_ACPI_H*/
>> -- 
>> 2.7.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-22 14:58                     ` Aleksey Makarov
  (?)
@ 2016-02-23  0:19                       ` Zheng, Lv
  -1 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-23  0:19 UTC (permalink / raw)
  To: Aleksey Makarov, Peter Hurley, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi,

> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi,
> 
> On 02/22/2016 05:24 AM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> Hi Lv,
> >>
> >> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> >>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>> early_acpi_os_unmap_memory()
> >>>>
> >>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> >>>>> Hi,
> >>>>>
> >>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>>
> >>>>>> Hi Lv,
> >>>>>>
> >>>>>> Thank you for review.
> >>>>>>
> >>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>>>>>
> >>>>>> [..]
> >>>>>>
> >>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap
> is
> >> not
> >>>>>> set.
> >>>>>>>>>
> >>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>>>>>
> >>>>>>>>> We need this function to be non-__init because we need access to
> >>>>>>>>> some tables at unpredictable time--it may be before or after
> >>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> >>>> Console
> >>>>>>>>> Redirection) table is needed each time a new console is registered.
> >>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>>>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>>>>>> does.
> >>>>>>>> [Lv Zheng]
> >>>>>>>> Why don't you use another API instead of
> >>>> early_acpi_os_unmap_memory()
> >>>>>> in
> >>>>>>>> case you want to unmap things in any cases.
> >>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>>>>>
> >>>>>> As far as I understand, there exist two steps in ACPI initialization:
> >>>>>>
> >>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >>>>>> acpi_get_table_with_size()
> >>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer
> it
> >>>>>> should be unmapped.
> >>>>>>
> >>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> >>>> unmapped
> >>>>>> at all.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> This statement is wrong, this should be:
> >>>>> As long as there is a __reference__ to the mapped table, the pointer
> should
> >>>> not be unmapped.
> >>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
> >>>>> So your argument is wrong from very first point.
> >>>>>
> >>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
> >>>>>> acpi_gbl_permanent_mmap.
> >>>>>> If I had used acpi_os_unmap_memory() after
> acpi_gbl_permanent_mmap
> >>>> had
> >>>>>> been set,
> >>>>>> it would have tried to free that pointer with an oops (actually, I
> checked
> >> that
> >>>>>> and got that oops).
> >>>>>>
> >>>>>> So using acpi_os_unmap_memory() is not an option here, but
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>> match perfectly.
> >>>>> [Lv Zheng]
> >>>>> I don't think so.
> >>>>> For definition block tables, we know for sure there will always be
> >> references,
> >>>> until "Unload" opcode is invoked by the AML interpreter.
> >>>>> But for the data tables, OSPMs should use them in this way:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structures
> >>>>> 3. unmap the table
> >>>>> This helps to shrink virtual memory address space usages.
> >>>>>
> >>>>> So from this point of view, all data tables should be unmapped right
> after
> >>>> being parsed.
> >>>>> Why do you need the map to be persistent in the kernel address space?
> >>>>> You can always map a small table, but what if the table size is very big?
> >>>>>
> >>>>>>
> >>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>>>>>
> >>>>>> I don't think so -- I have explained why.  It does different thing.
> >>>>>> Probably it (and/or other functions in that api) should be renamed.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> Just let me ask one more question.
> >>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> >>>>> How ACPICA can work with just acpi_os_unmap_memory()?
> >>>>> You can check drivers/acpi/tbxxx.c.
> >>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
> >>>>>
> >>>>>>> [Lv Zheng]
> >>>>>>> One more thing is:
> >>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
> instead
> >> of
> >>>>>> early_acpi_os_unmap_memory(),
> >>>>>>> then it implies that your driver does have a defect.
> >>>>>>
> >>>>>> I still don't understand what defect, sorry.
> >>>>> [Lv Zheng]
> >>>>> If you can't ensure this sequence for using the data tables:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structure
> >>>>> 3. unmap the table
> >>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> >>>>
> >>>> Exactly.
> >>> [Lv Zheng]
> >>> So it looks to me:
> >>> Changing __init to __ref here is entirely not acceptable.
> >>> This API should stay being invoked during early stage.
> >>> Otherwise, it may leave us untrackable code that maps tables during early
> >> stage and leaks maps to the late stage.
> >>> If Linux contains such kind of code, I'm afraid, it will become impossible to
> >> introduce acpi_put_table() to clean up the mappings.
> >>> Because when acpi_put_table() is called during the late stage to free a map
> >> acquired during the early stage, it then obviously will end up with panic.
> >>
> >> Can you please sugggest a common method to access ACPI tables that
> >> works both before *and* after acpi_gbl_permanent_mmap is set and __init
> >> code
> >> is removed?
> > [Lv Zheng]
> > Do not change __init for now.
> >
> > Currently you should:
> > 1. before acpi_gbl_permanent_mmap is set:
> > acpi_get_table_with_size()
> > parse the table
> > early_acpi_os_unmap_memory()
> > Do your driver early stuff here
> >
> > 2. after acpi_gbl_permanent_mmap is set:
> > acpi_get_table()
> > Parse the table
> > Do your driver late stuff here
> > <- note there is no API now being an inverse of acpi_get_table().
> 
> That's fine.  These are two different methods to access the table.
> I need one that works in both cases.  Of course, they could be combined,
> but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
> seems to be an implementation detail of ACPI code.
[Lv Zheng] 
You should not access acpi_gbl_permanent_mmap.
The variable will be deleted after combining the 2 methods.
What we need to ensure is that during the period where the 2 different methods are not combined,
early_acpi_os_unmap_memory() should always be invoked.
And __init can help us to prevent developers submitting wrong code.

> 
> Instead I am going to use the 1st method once and cache the result like this:
> 
> 
> static int __init parse(void)
> {
> 	static bool parsed;
> 
> 	if (!parsed) {
> 		acpi_get_table_with_size()
> 		/* parse the table and cache the result */
> 		early_acpi_os_unmap_memory()
> 		parse = true;
> 	}
> }
> 
> arch_initcal(parse());
> 
> int __ref the_handler_where_I_need_the_parse_results(void)
> {
> 	parse();
> 
> 	/* use the data */
> }
> 
> I hope you are OK with it.
[Lv Zheng] 
I'm OK with the code flow in parse().
As long as there is no compiler complaining detected against the __init declarator of early_acpi_os_unmap_memory(), I'm OK with the rest.

> 
> > Besides, I'm about to insert error messages between 1 and 2.
> > If an early map is not release, error message will be prompted to the
> developers.
> 
> AFAICS, there is such an error message and I saw it.
> Refer to check_early_ioremap_leak() at mm/early_ioremap.c
[Lv Zheng] 
We also need ACPICA upstream to be aware of this, otherwise wrong changes could be merged from ACPICA upstream.

Thanks
-Lv

> 
> > And if you don't follow the above rules, it mean you are trying to lay a mine,
> waiting for me to step on it.
> > That's why this change is entirely not acceptable.
> 
> Ok, I see.
> 
> > I'm about to send out the cleanup series in 1 week, and will Cc you.
> > You can rebase your code on top of the cleanup series.
> 
> Thank you
> Aleksey Makarov
> 
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>> The central problem here is the way Aleksey is trying to hookup a console.
> >>>>
> >>>> What should be happening in this series is:
> >>>> 1. early map SPCR
> >>>> 2. parse the SPCR table
> >>>> 3. call add_preferred_console() to add the SPCR console to the console
> >> table
> >>>> 4. unmap SPCR
> >>>>
> >>>> This trivial and unobtrusive method would already have a 8250 console
> >>>> running via SPCR. I've already pointed this out in previous reviews.
> >>>>
> >>>> Further, the above method *will be required anyway* for the DBG2 table
> to
> >>>> start an earlycon, which I've already pointed out in previous reviews.
> >>>>
> >>>> Then to enable amba-pl011 console via ACPI, add a console match()
> method
> >>>> similar to the 8250 console match() method, univ8250_console_match().
> >>>>
> >>>> FWIW, PCI earlycon + console support was already submitted once before
> >> but
> >>>> never picked up by GregKH. I think I'll just grab that and re-submit so
> >>>> you would know what to emit for console options in the
> >>>> add_preferred_console().
> >>>>
> >>>>
> >>>> Regards,
> >>>> Peter Hurley
> >>>>
> >>>>
> >>>>>>> There is an early bootup requirement in Linux.
> >>>>>>> Maps acquired during the early stage should be freed by the driver
> during
> >>>> the
> >>>>>> early stage.
> >>>>>>> And the driver should re-acquire the memory map after booting.
> >>>>>>
> >>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
> >> that
> >>>>>> that code can be
> >>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
> >> of
> >>>> for
> >>>>>> example 8250 console)
> >>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
> >> that
> >>>>>> registers a console),
> >>>>>> We just can not tell if the received table pointer should or sould not be
> >> freed
> >>>>>> with early_memunmap()
> >>>>>> (actually __acpi_unmap_table() or whatever) without checking
> >>>>>> acpi_gbl_permanent_mmap,
> >>>>>> but that's all too low level.
> >>>>> [Lv Zheng]
> >>>>> The driver should make sure that:
> >>>>> Map/unmap is paired during early stage.
> >>>>> For late stage, it should be another pair of map/unmap.
> >>>>>
> >>>>>>
> >>>>>> Another option, as you describe, is to get this pointer early, don't free it
> >>>>> [Lv Zheng]
> >>>>> I mean you should free it early.
> >>>>>
> >>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
> >>>>>> early_acpi_os_unmap_memory(), that's
> >>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
> >> the
> >>>>>> persistent
> >>>>>> pointer to the table.  The problem with it is that we can not just watch
> >>>>>> acpi_gbl_permanent_mmap
> >>>>>> to catch this exact moment.  And also accessing
> >> acpi_gbl_permanent_mmap
> >>>> is
> >>>>>> not good as it probably is
> >>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >>>>>> Or I probably miss what you are suggesting.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> I mean, you should:
> >>>>> During early stage:
> >>>>> acpi_os_map_memory()
> >>>>> Parse the table.
> >>>>> acpi_os_unmap_memory().
> >>>>>
> >>>>>>> This is because, during early bootup stage, there are only limited slots
> >>>>>> available for drivers to map memory.
> >>>>>>> So by changing __init to __ref here, you probably will hide many such
> >>>> defects.
> >>>>>>
> >>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >>>>>> BTW, exactly the same thing is done in the beginning of
> >>>>>> acpi_os_unmap_memory() and than's ok,
> >>>>>> that function is __ref.
> >>>>>>
> >>>>>>> And solving issues in this way doesn't seem to be an improvement.
> >>>>>>
> >>>>>> Could you please tell me where I am wrong?  I still don't understand
> your
> >>>> point.
> >>>>> [Lv Zheng]
> >>>>> But anyway, the defect should be in ACPI subsystem core.
> >>>>> The cause should be the API itself - acpi_get_table().
> >>>>>
> >>>>> So I agree you can use early_acpi_os_unmap_memory() during the
> period
> >> the
> >>>> root causes are not cleaned up.
> >>>>> But the bottom line is: the driver need to ensure that
> >>>> early_acpi_os_unmap_memory() is always invoked.
> >>>>> As long as you can ensure this, I don't have objections for deploying
> >>>> early_acpi_os_unmap_memory()  for now.
> >>>>>
> >>>>> Thanks and best regards
> >>>>> -Lv
> >>>>>
> >>>>>>
> >>>>>> Thank you
> >>>>>> Aleksey Makarov
> >>>>>>
> >>>>>>>
> >>>>>>> Thanks and best regards
> >>>>>>> -Lv
> >>>>>>>
> >>>>>>>>
> >>>>>>>> Thanks and best regards
> >>>>>>>> -Lv
> >>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>>>>>> ---
> >>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>>>>>> index 67da6fb..8a552cd 100644
> >>>>>>>>> --- a/drivers/acpi/osl.c
> >>>>>>>>> +++ b/drivers/acpi/osl.c
> >>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
> >> *virt,
> >>>>>>>>> acpi_size size)
> >>>>>>>>>  }
> >>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>>>>>
> >>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>> +/*
> >>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
> >> anywhere
> >>>>>>>>> + */
> >>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>>  {
> >>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>>>>>  		__acpi_unmap_table(virt, size);
> >>>>>>>>> --
> >>>>>>>>> 2.7.1
> >>>>>>>>>
> >>>>>>>>> --
> >>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi"
> in
> >>>>>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> >> info.html
> >>>>>>>> --
> >>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> info.html
> >>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-23  0:19                       ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-23  0:19 UTC (permalink / raw)
  To: Aleksey Makarov, Peter Hurley, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi,

> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi,
> 
> On 02/22/2016 05:24 AM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> Hi Lv,
> >>
> >> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> >>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>> early_acpi_os_unmap_memory()
> >>>>
> >>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> >>>>> Hi,
> >>>>>
> >>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>>
> >>>>>> Hi Lv,
> >>>>>>
> >>>>>> Thank you for review.
> >>>>>>
> >>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>>>>>
> >>>>>> [..]
> >>>>>>
> >>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap
> is
> >> not
> >>>>>> set.
> >>>>>>>>>
> >>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>>>>>
> >>>>>>>>> We need this function to be non-__init because we need access to
> >>>>>>>>> some tables at unpredictable time--it may be before or after
> >>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> >>>> Console
> >>>>>>>>> Redirection) table is needed each time a new console is registered.
> >>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>>>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>>>>>> does.
> >>>>>>>> [Lv Zheng]
> >>>>>>>> Why don't you use another API instead of
> >>>> early_acpi_os_unmap_memory()
> >>>>>> in
> >>>>>>>> case you want to unmap things in any cases.
> >>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>>>>>
> >>>>>> As far as I understand, there exist two steps in ACPI initialization:
> >>>>>>
> >>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >>>>>> acpi_get_table_with_size()
> >>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer
> it
> >>>>>> should be unmapped.
> >>>>>>
> >>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> >>>> unmapped
> >>>>>> at all.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> This statement is wrong, this should be:
> >>>>> As long as there is a __reference__ to the mapped table, the pointer
> should
> >>>> not be unmapped.
> >>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
> >>>>> So your argument is wrong from very first point.
> >>>>>
> >>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
> >>>>>> acpi_gbl_permanent_mmap.
> >>>>>> If I had used acpi_os_unmap_memory() after
> acpi_gbl_permanent_mmap
> >>>> had
> >>>>>> been set,
> >>>>>> it would have tried to free that pointer with an oops (actually, I
> checked
> >> that
> >>>>>> and got that oops).
> >>>>>>
> >>>>>> So using acpi_os_unmap_memory() is not an option here, but
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>> match perfectly.
> >>>>> [Lv Zheng]
> >>>>> I don't think so.
> >>>>> For definition block tables, we know for sure there will always be
> >> references,
> >>>> until "Unload" opcode is invoked by the AML interpreter.
> >>>>> But for the data tables, OSPMs should use them in this way:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structures
> >>>>> 3. unmap the table
> >>>>> This helps to shrink virtual memory address space usages.
> >>>>>
> >>>>> So from this point of view, all data tables should be unmapped right
> after
> >>>> being parsed.
> >>>>> Why do you need the map to be persistent in the kernel address space?
> >>>>> You can always map a small table, but what if the table size is very big?
> >>>>>
> >>>>>>
> >>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>>>>>
> >>>>>> I don't think so -- I have explained why.  It does different thing.
> >>>>>> Probably it (and/or other functions in that api) should be renamed.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> Just let me ask one more question.
> >>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> >>>>> How ACPICA can work with just acpi_os_unmap_memory()?
> >>>>> You can check drivers/acpi/tbxxx.c.
> >>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
> >>>>>
> >>>>>>> [Lv Zheng]
> >>>>>>> One more thing is:
> >>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
> instead
> >> of
> >>>>>> early_acpi_os_unmap_memory(),
> >>>>>>> then it implies that your driver does have a defect.
> >>>>>>
> >>>>>> I still don't understand what defect, sorry.
> >>>>> [Lv Zheng]
> >>>>> If you can't ensure this sequence for using the data tables:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structure
> >>>>> 3. unmap the table
> >>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> >>>>
> >>>> Exactly.
> >>> [Lv Zheng]
> >>> So it looks to me:
> >>> Changing __init to __ref here is entirely not acceptable.
> >>> This API should stay being invoked during early stage.
> >>> Otherwise, it may leave us untrackable code that maps tables during early
> >> stage and leaks maps to the late stage.
> >>> If Linux contains such kind of code, I'm afraid, it will become impossible to
> >> introduce acpi_put_table() to clean up the mappings.
> >>> Because when acpi_put_table() is called during the late stage to free a map
> >> acquired during the early stage, it then obviously will end up with panic.
> >>
> >> Can you please sugggest a common method to access ACPI tables that
> >> works both before *and* after acpi_gbl_permanent_mmap is set and __init
> >> code
> >> is removed?
> > [Lv Zheng]
> > Do not change __init for now.
> >
> > Currently you should:
> > 1. before acpi_gbl_permanent_mmap is set:
> > acpi_get_table_with_size()
> > parse the table
> > early_acpi_os_unmap_memory()
> > Do your driver early stuff here
> >
> > 2. after acpi_gbl_permanent_mmap is set:
> > acpi_get_table()
> > Parse the table
> > Do your driver late stuff here
> > <- note there is no API now being an inverse of acpi_get_table().
> 
> That's fine.  These are two different methods to access the table.
> I need one that works in both cases.  Of course, they could be combined,
> but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
> seems to be an implementation detail of ACPI code.
[Lv Zheng] 
You should not access acpi_gbl_permanent_mmap.
The variable will be deleted after combining the 2 methods.
What we need to ensure is that during the period where the 2 different methods are not combined,
early_acpi_os_unmap_memory() should always be invoked.
And __init can help us to prevent developers submitting wrong code.

> 
> Instead I am going to use the 1st method once and cache the result like this:
> 
> 
> static int __init parse(void)
> {
> 	static bool parsed;
> 
> 	if (!parsed) {
> 		acpi_get_table_with_size()
> 		/* parse the table and cache the result */
> 		early_acpi_os_unmap_memory()
> 		parse = true;
> 	}
> }
> 
> arch_initcal(parse());
> 
> int __ref the_handler_where_I_need_the_parse_results(void)
> {
> 	parse();
> 
> 	/* use the data */
> }
> 
> I hope you are OK with it.
[Lv Zheng] 
I'm OK with the code flow in parse().
As long as there is no compiler complaining detected against the __init declarator of early_acpi_os_unmap_memory(), I'm OK with the rest.

> 
> > Besides, I'm about to insert error messages between 1 and 2.
> > If an early map is not release, error message will be prompted to the
> developers.
> 
> AFAICS, there is such an error message and I saw it.
> Refer to check_early_ioremap_leak() at mm/early_ioremap.c
[Lv Zheng] 
We also need ACPICA upstream to be aware of this, otherwise wrong changes could be merged from ACPICA upstream.

Thanks
-Lv

> 
> > And if you don't follow the above rules, it mean you are trying to lay a mine,
> waiting for me to step on it.
> > That's why this change is entirely not acceptable.
> 
> Ok, I see.
> 
> > I'm about to send out the cleanup series in 1 week, and will Cc you.
> > You can rebase your code on top of the cleanup series.
> 
> Thank you
> Aleksey Makarov
> 
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>> The central problem here is the way Aleksey is trying to hookup a console.
> >>>>
> >>>> What should be happening in this series is:
> >>>> 1. early map SPCR
> >>>> 2. parse the SPCR table
> >>>> 3. call add_preferred_console() to add the SPCR console to the console
> >> table
> >>>> 4. unmap SPCR
> >>>>
> >>>> This trivial and unobtrusive method would already have a 8250 console
> >>>> running via SPCR. I've already pointed this out in previous reviews.
> >>>>
> >>>> Further, the above method *will be required anyway* for the DBG2 table
> to
> >>>> start an earlycon, which I've already pointed out in previous reviews.
> >>>>
> >>>> Then to enable amba-pl011 console via ACPI, add a console match()
> method
> >>>> similar to the 8250 console match() method, univ8250_console_match().
> >>>>
> >>>> FWIW, PCI earlycon + console support was already submitted once before
> >> but
> >>>> never picked up by GregKH. I think I'll just grab that and re-submit so
> >>>> you would know what to emit for console options in the
> >>>> add_preferred_console().
> >>>>
> >>>>
> >>>> Regards,
> >>>> Peter Hurley
> >>>>
> >>>>
> >>>>>>> There is an early bootup requirement in Linux.
> >>>>>>> Maps acquired during the early stage should be freed by the driver
> during
> >>>> the
> >>>>>> early stage.
> >>>>>>> And the driver should re-acquire the memory map after booting.
> >>>>>>
> >>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
> >> that
> >>>>>> that code can be
> >>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
> >> of
> >>>> for
> >>>>>> example 8250 console)
> >>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
> >> that
> >>>>>> registers a console),
> >>>>>> We just can not tell if the received table pointer should or sould not be
> >> freed
> >>>>>> with early_memunmap()
> >>>>>> (actually __acpi_unmap_table() or whatever) without checking
> >>>>>> acpi_gbl_permanent_mmap,
> >>>>>> but that's all too low level.
> >>>>> [Lv Zheng]
> >>>>> The driver should make sure that:
> >>>>> Map/unmap is paired during early stage.
> >>>>> For late stage, it should be another pair of map/unmap.
> >>>>>
> >>>>>>
> >>>>>> Another option, as you describe, is to get this pointer early, don't free it
> >>>>> [Lv Zheng]
> >>>>> I mean you should free it early.
> >>>>>
> >>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
> >>>>>> early_acpi_os_unmap_memory(), that's
> >>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
> >> the
> >>>>>> persistent
> >>>>>> pointer to the table.  The problem with it is that we can not just watch
> >>>>>> acpi_gbl_permanent_mmap
> >>>>>> to catch this exact moment.  And also accessing
> >> acpi_gbl_permanent_mmap
> >>>> is
> >>>>>> not good as it probably is
> >>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >>>>>> Or I probably miss what you are suggesting.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> I mean, you should:
> >>>>> During early stage:
> >>>>> acpi_os_map_memory()
> >>>>> Parse the table.
> >>>>> acpi_os_unmap_memory().
> >>>>>
> >>>>>>> This is because, during early bootup stage, there are only limited slots
> >>>>>> available for drivers to map memory.
> >>>>>>> So by changing __init to __ref here, you probably will hide many such
> >>>> defects.
> >>>>>>
> >>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >>>>>> BTW, exactly the same thing is done in the beginning of
> >>>>>> acpi_os_unmap_memory() and than's ok,
> >>>>>> that function is __ref.
> >>>>>>
> >>>>>>> And solving issues in this way doesn't seem to be an improvement.
> >>>>>>
> >>>>>> Could you please tell me where I am wrong?  I still don't understand
> your
> >>>> point.
> >>>>> [Lv Zheng]
> >>>>> But anyway, the defect should be in ACPI subsystem core.
> >>>>> The cause should be the API itself - acpi_get_table().
> >>>>>
> >>>>> So I agree you can use early_acpi_os_unmap_memory() during the
> period
> >> the
> >>>> root causes are not cleaned up.
> >>>>> But the bottom line is: the driver need to ensure that
> >>>> early_acpi_os_unmap_memory() is always invoked.
> >>>>> As long as you can ensure this, I don't have objections for deploying
> >>>> early_acpi_os_unmap_memory()  for now.
> >>>>>
> >>>>> Thanks and best regards
> >>>>> -Lv
> >>>>>
> >>>>>>
> >>>>>> Thank you
> >>>>>> Aleksey Makarov
> >>>>>>
> >>>>>>>
> >>>>>>> Thanks and best regards
> >>>>>>> -Lv
> >>>>>>>
> >>>>>>>>
> >>>>>>>> Thanks and best regards
> >>>>>>>> -Lv
> >>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>>>>>> ---
> >>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>>>>>> index 67da6fb..8a552cd 100644
> >>>>>>>>> --- a/drivers/acpi/osl.c
> >>>>>>>>> +++ b/drivers/acpi/osl.c
> >>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
> >> *virt,
> >>>>>>>>> acpi_size size)
> >>>>>>>>>  }
> >>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>>>>>
> >>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>> +/*
> >>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
> >> anywhere
> >>>>>>>>> + */
> >>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>>  {
> >>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>>>>>  		__acpi_unmap_table(virt, size);
> >>>>>>>>> --
> >>>>>>>>> 2.7.1
> >>>>>>>>>
> >>>>>>>>> --
> >>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi"
> in
> >>>>>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> >> info.html
> >>>>>>>> --
> >>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> info.html
> >>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-23  0:19                       ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-23  0:19 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi,
> 
> On 02/22/2016 05:24 AM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> Hi Lv,
> >>
> >> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> >>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>> early_acpi_os_unmap_memory()
> >>>>
> >>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> >>>>> Hi,
> >>>>>
> >>>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
> >>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>>
> >>>>>> Hi Lv,
> >>>>>>
> >>>>>> Thank you for review.
> >>>>>>
> >>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>>>>>
> >>>>>> [..]
> >>>>>>
> >>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap
> is
> >> not
> >>>>>> set.
> >>>>>>>>>
> >>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>>>>>
> >>>>>>>>> We need this function to be non-__init because we need access to
> >>>>>>>>> some tables at unpredictable time--it may be before or after
> >>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> >>>> Console
> >>>>>>>>> Redirection) table is needed each time a new console is registered.
> >>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>>>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>>>>>> does.
> >>>>>>>> [Lv Zheng]
> >>>>>>>> Why don't you use another API instead of
> >>>> early_acpi_os_unmap_memory()
> >>>>>> in
> >>>>>>>> case you want to unmap things in any cases.
> >>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>>>>>
> >>>>>> As far as I understand, there exist two steps in ACPI initialization:
> >>>>>>
> >>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >>>>>> acpi_get_table_with_size()
> >>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer
> it
> >>>>>> should be unmapped.
> >>>>>>
> >>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> >>>> unmapped
> >>>>>> at all.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> This statement is wrong, this should be:
> >>>>> As long as there is a __reference__ to the mapped table, the pointer
> should
> >>>> not be unmapped.
> >>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
> >>>>> So your argument is wrong from very first point.
> >>>>>
> >>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
> >>>>>> acpi_gbl_permanent_mmap.
> >>>>>> If I had used acpi_os_unmap_memory() after
> acpi_gbl_permanent_mmap
> >>>> had
> >>>>>> been set,
> >>>>>> it would have tried to free that pointer with an oops (actually, I
> checked
> >> that
> >>>>>> and got that oops).
> >>>>>>
> >>>>>> So using acpi_os_unmap_memory() is not an option here, but
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>> match perfectly.
> >>>>> [Lv Zheng]
> >>>>> I don't think so.
> >>>>> For definition block tables, we know for sure there will always be
> >> references,
> >>>> until "Unload" opcode is invoked by the AML interpreter.
> >>>>> But for the data tables, OSPMs should use them in this way:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structures
> >>>>> 3. unmap the table
> >>>>> This helps to shrink virtual memory address space usages.
> >>>>>
> >>>>> So from this point of view, all data tables should be unmapped right
> after
> >>>> being parsed.
> >>>>> Why do you need the map to be persistent in the kernel address space?
> >>>>> You can always map a small table, but what if the table size is very big?
> >>>>>
> >>>>>>
> >>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>>>>>
> >>>>>> I don't think so -- I have explained why.  It does different thing.
> >>>>>> Probably it (and/or other functions in that api) should be renamed.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> Just let me ask one more question.
> >>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> >>>>> How ACPICA can work with just acpi_os_unmap_memory()?
> >>>>> You can check drivers/acpi/tbxxx.c.
> >>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
> >>>>>
> >>>>>>> [Lv Zheng]
> >>>>>>> One more thing is:
> >>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
> instead
> >> of
> >>>>>> early_acpi_os_unmap_memory(),
> >>>>>>> then it implies that your driver does have a defect.
> >>>>>>
> >>>>>> I still don't understand what defect, sorry.
> >>>>> [Lv Zheng]
> >>>>> If you can't ensure this sequence for using the data tables:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structure
> >>>>> 3. unmap the table
> >>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> >>>>
> >>>> Exactly.
> >>> [Lv Zheng]
> >>> So it looks to me:
> >>> Changing __init to __ref here is entirely not acceptable.
> >>> This API should stay being invoked during early stage.
> >>> Otherwise, it may leave us untrackable code that maps tables during early
> >> stage and leaks maps to the late stage.
> >>> If Linux contains such kind of code, I'm afraid, it will become impossible to
> >> introduce acpi_put_table() to clean up the mappings.
> >>> Because when acpi_put_table() is called during the late stage to free a map
> >> acquired during the early stage, it then obviously will end up with panic.
> >>
> >> Can you please sugggest a common method to access ACPI tables that
> >> works both before *and* after acpi_gbl_permanent_mmap is set and __init
> >> code
> >> is removed?
> > [Lv Zheng]
> > Do not change __init for now.
> >
> > Currently you should:
> > 1. before acpi_gbl_permanent_mmap is set:
> > acpi_get_table_with_size()
> > parse the table
> > early_acpi_os_unmap_memory()
> > Do your driver early stuff here
> >
> > 2. after acpi_gbl_permanent_mmap is set:
> > acpi_get_table()
> > Parse the table
> > Do your driver late stuff here
> > <- note there is no API now being an inverse of acpi_get_table().
> 
> That's fine.  These are two different methods to access the table.
> I need one that works in both cases.  Of course, they could be combined,
> but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
> seems to be an implementation detail of ACPI code.
[Lv Zheng] 
You should not access acpi_gbl_permanent_mmap.
The variable will be deleted after combining the 2 methods.
What we need to ensure is that during the period where the 2 different methods are not combined,
early_acpi_os_unmap_memory() should always be invoked.
And __init can help us to prevent developers submitting wrong code.

> 
> Instead I am going to use the 1st method once and cache the result like this:
> 
> 
> static int __init parse(void)
> {
> 	static bool parsed;
> 
> 	if (!parsed) {
> 		acpi_get_table_with_size()
> 		/* parse the table and cache the result */
> 		early_acpi_os_unmap_memory()
> 		parse = true;
> 	}
> }
> 
> arch_initcal(parse());
> 
> int __ref the_handler_where_I_need_the_parse_results(void)
> {
> 	parse();
> 
> 	/* use the data */
> }
> 
> I hope you are OK with it.
[Lv Zheng] 
I'm OK with the code flow in parse().
As long as there is no compiler complaining detected against the __init declarator of early_acpi_os_unmap_memory(), I'm OK with the rest.

> 
> > Besides, I'm about to insert error messages between 1 and 2.
> > If an early map is not release, error message will be prompted to the
> developers.
> 
> AFAICS, there is such an error message and I saw it.
> Refer to check_early_ioremap_leak() at mm/early_ioremap.c
[Lv Zheng] 
We also need ACPICA upstream to be aware of this, otherwise wrong changes could be merged from ACPICA upstream.

Thanks
-Lv

> 
> > And if you don't follow the above rules, it mean you are trying to lay a mine,
> waiting for me to step on it.
> > That's why this change is entirely not acceptable.
> 
> Ok, I see.
> 
> > I'm about to send out the cleanup series in 1 week, and will Cc you.
> > You can rebase your code on top of the cleanup series.
> 
> Thank you
> Aleksey Makarov
> 
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>> The central problem here is the way Aleksey is trying to hookup a console.
> >>>>
> >>>> What should be happening in this series is:
> >>>> 1. early map SPCR
> >>>> 2. parse the SPCR table
> >>>> 3. call add_preferred_console() to add the SPCR console to the console
> >> table
> >>>> 4. unmap SPCR
> >>>>
> >>>> This trivial and unobtrusive method would already have a 8250 console
> >>>> running via SPCR. I've already pointed this out in previous reviews.
> >>>>
> >>>> Further, the above method *will be required anyway* for the DBG2 table
> to
> >>>> start an earlycon, which I've already pointed out in previous reviews.
> >>>>
> >>>> Then to enable amba-pl011 console via ACPI, add a console match()
> method
> >>>> similar to the 8250 console match() method, univ8250_console_match().
> >>>>
> >>>> FWIW, PCI earlycon + console support was already submitted once before
> >> but
> >>>> never picked up by GregKH. I think I'll just grab that and re-submit so
> >>>> you would know what to emit for console options in the
> >>>> add_preferred_console().
> >>>>
> >>>>
> >>>> Regards,
> >>>> Peter Hurley
> >>>>
> >>>>
> >>>>>>> There is an early bootup requirement in Linux.
> >>>>>>> Maps acquired during the early stage should be freed by the driver
> during
> >>>> the
> >>>>>> early stage.
> >>>>>>> And the driver should re-acquire the memory map after booting.
> >>>>>>
> >>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
> >> that
> >>>>>> that code can be
> >>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
> >> of
> >>>> for
> >>>>>> example 8250 console)
> >>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
> >> that
> >>>>>> registers a console),
> >>>>>> We just can not tell if the received table pointer should or sould not be
> >> freed
> >>>>>> with early_memunmap()
> >>>>>> (actually __acpi_unmap_table() or whatever) without checking
> >>>>>> acpi_gbl_permanent_mmap,
> >>>>>> but that's all too low level.
> >>>>> [Lv Zheng]
> >>>>> The driver should make sure that:
> >>>>> Map/unmap is paired during early stage.
> >>>>> For late stage, it should be another pair of map/unmap.
> >>>>>
> >>>>>>
> >>>>>> Another option, as you describe, is to get this pointer early, don't free it
> >>>>> [Lv Zheng]
> >>>>> I mean you should free it early.
> >>>>>
> >>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
> >>>>>> early_acpi_os_unmap_memory(), that's
> >>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
> >> the
> >>>>>> persistent
> >>>>>> pointer to the table.  The problem with it is that we can not just watch
> >>>>>> acpi_gbl_permanent_mmap
> >>>>>> to catch this exact moment.  And also accessing
> >> acpi_gbl_permanent_mmap
> >>>> is
> >>>>>> not good as it probably is
> >>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >>>>>> Or I probably miss what you are suggesting.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> I mean, you should:
> >>>>> During early stage:
> >>>>> acpi_os_map_memory()
> >>>>> Parse the table.
> >>>>> acpi_os_unmap_memory().
> >>>>>
> >>>>>>> This is because, during early bootup stage, there are only limited slots
> >>>>>> available for drivers to map memory.
> >>>>>>> So by changing __init to __ref here, you probably will hide many such
> >>>> defects.
> >>>>>>
> >>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >>>>>> BTW, exactly the same thing is done in the beginning of
> >>>>>> acpi_os_unmap_memory() and than's ok,
> >>>>>> that function is __ref.
> >>>>>>
> >>>>>>> And solving issues in this way doesn't seem to be an improvement.
> >>>>>>
> >>>>>> Could you please tell me where I am wrong?  I still don't understand
> your
> >>>> point.
> >>>>> [Lv Zheng]
> >>>>> But anyway, the defect should be in ACPI subsystem core.
> >>>>> The cause should be the API itself - acpi_get_table().
> >>>>>
> >>>>> So I agree you can use early_acpi_os_unmap_memory() during the
> period
> >> the
> >>>> root causes are not cleaned up.
> >>>>> But the bottom line is: the driver need to ensure that
> >>>> early_acpi_os_unmap_memory() is always invoked.
> >>>>> As long as you can ensure this, I don't have objections for deploying
> >>>> early_acpi_os_unmap_memory()  for now.
> >>>>>
> >>>>> Thanks and best regards
> >>>>> -Lv
> >>>>>
> >>>>>>
> >>>>>> Thank you
> >>>>>> Aleksey Makarov
> >>>>>>
> >>>>>>>
> >>>>>>> Thanks and best regards
> >>>>>>> -Lv
> >>>>>>>
> >>>>>>>>
> >>>>>>>> Thanks and best regards
> >>>>>>>> -Lv
> >>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>>>>>> ---
> >>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>>>>>> index 67da6fb..8a552cd 100644
> >>>>>>>>> --- a/drivers/acpi/osl.c
> >>>>>>>>> +++ b/drivers/acpi/osl.c
> >>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
> >> *virt,
> >>>>>>>>> acpi_size size)
> >>>>>>>>>  }
> >>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>>>>>
> >>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>> +/*
> >>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
> >> anywhere
> >>>>>>>>> + */
> >>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>>  {
> >>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>>>>>  		__acpi_unmap_table(virt, size);
> >>>>>>>>> --
> >>>>>>>>> 2.7.1
> >>>>>>>>>
> >>>>>>>>> --
> >>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi"
> in
> >>>>>>>>> the body of a message to majordomo at vger.kernel.org
> >>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> >> info.html
> >>>>>>>> --
> >>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>>>> the body of a message to majordomo at vger.kernel.org
> >>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> info.html
> >>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-22 14:58                     ` Aleksey Makarov
  (?)
@ 2016-02-26  6:39                       ` Zheng, Lv
  -1 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-26  6:39 UTC (permalink / raw)
  To: Aleksey Makarov, Peter Hurley, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi, Aleksey

Though I promised you to have this done in 1 week:
https://github.com/zetalog/acpica/commit/a234569
I implemented the idea and tried the cleanup in Linux.
But unfortunately the cleanup triggered several locking issues inside of ACPICA table API users.
So it doesn't seem to be so easy and quick to make it upstreamed.
And I have to continue to test and improve the cleanup.

I'm sorry for that, hope you can find substitute solutions before the cleanup is upstreamed.

Thanks and best regards
-Lv

> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> Sent: Monday, February 22, 2016 10:58 PM
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi,
> 
> On 02/22/2016 05:24 AM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> Hi Lv,
> >>
> >> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> >>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>> early_acpi_os_unmap_memory()
> >>>>
> >>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> >>>>> Hi,
> >>>>>
> >>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>>
> >>>>>> Hi Lv,
> >>>>>>
> >>>>>> Thank you for review.
> >>>>>>
> >>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>>>>>
> >>>>>> [..]
> >>>>>>
> >>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap
> is
> >> not
> >>>>>> set.
> >>>>>>>>>
> >>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>>>>>
> >>>>>>>>> We need this function to be non-__init because we need access to
> >>>>>>>>> some tables at unpredictable time--it may be before or after
> >>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> >>>> Console
> >>>>>>>>> Redirection) table is needed each time a new console is registered.
> >>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>>>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>>>>>> does.
> >>>>>>>> [Lv Zheng]
> >>>>>>>> Why don't you use another API instead of
> >>>> early_acpi_os_unmap_memory()
> >>>>>> in
> >>>>>>>> case you want to unmap things in any cases.
> >>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>>>>>
> >>>>>> As far as I understand, there exist two steps in ACPI initialization:
> >>>>>>
> >>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >>>>>> acpi_get_table_with_size()
> >>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer
> it
> >>>>>> should be unmapped.
> >>>>>>
> >>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> >>>> unmapped
> >>>>>> at all.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> This statement is wrong, this should be:
> >>>>> As long as there is a __reference__ to the mapped table, the pointer
> should
> >>>> not be unmapped.
> >>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
> >>>>> So your argument is wrong from very first point.
> >>>>>
> >>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
> >>>>>> acpi_gbl_permanent_mmap.
> >>>>>> If I had used acpi_os_unmap_memory() after
> acpi_gbl_permanent_mmap
> >>>> had
> >>>>>> been set,
> >>>>>> it would have tried to free that pointer with an oops (actually, I
> checked
> >> that
> >>>>>> and got that oops).
> >>>>>>
> >>>>>> So using acpi_os_unmap_memory() is not an option here, but
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>> match perfectly.
> >>>>> [Lv Zheng]
> >>>>> I don't think so.
> >>>>> For definition block tables, we know for sure there will always be
> >> references,
> >>>> until "Unload" opcode is invoked by the AML interpreter.
> >>>>> But for the data tables, OSPMs should use them in this way:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structures
> >>>>> 3. unmap the table
> >>>>> This helps to shrink virtual memory address space usages.
> >>>>>
> >>>>> So from this point of view, all data tables should be unmapped right
> after
> >>>> being parsed.
> >>>>> Why do you need the map to be persistent in the kernel address space?
> >>>>> You can always map a small table, but what if the table size is very big?
> >>>>>
> >>>>>>
> >>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>>>>>
> >>>>>> I don't think so -- I have explained why.  It does different thing.
> >>>>>> Probably it (and/or other functions in that api) should be renamed.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> Just let me ask one more question.
> >>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> >>>>> How ACPICA can work with just acpi_os_unmap_memory()?
> >>>>> You can check drivers/acpi/tbxxx.c.
> >>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
> >>>>>
> >>>>>>> [Lv Zheng]
> >>>>>>> One more thing is:
> >>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
> instead
> >> of
> >>>>>> early_acpi_os_unmap_memory(),
> >>>>>>> then it implies that your driver does have a defect.
> >>>>>>
> >>>>>> I still don't understand what defect, sorry.
> >>>>> [Lv Zheng]
> >>>>> If you can't ensure this sequence for using the data tables:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structure
> >>>>> 3. unmap the table
> >>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> >>>>
> >>>> Exactly.
> >>> [Lv Zheng]
> >>> So it looks to me:
> >>> Changing __init to __ref here is entirely not acceptable.
> >>> This API should stay being invoked during early stage.
> >>> Otherwise, it may leave us untrackable code that maps tables during early
> >> stage and leaks maps to the late stage.
> >>> If Linux contains such kind of code, I'm afraid, it will become impossible to
> >> introduce acpi_put_table() to clean up the mappings.
> >>> Because when acpi_put_table() is called during the late stage to free a map
> >> acquired during the early stage, it then obviously will end up with panic.
> >>
> >> Can you please sugggest a common method to access ACPI tables that
> >> works both before *and* after acpi_gbl_permanent_mmap is set and __init
> >> code
> >> is removed?
> > [Lv Zheng]
> > Do not change __init for now.
> >
> > Currently you should:
> > 1. before acpi_gbl_permanent_mmap is set:
> > acpi_get_table_with_size()
> > parse the table
> > early_acpi_os_unmap_memory()
> > Do your driver early stuff here
> >
> > 2. after acpi_gbl_permanent_mmap is set:
> > acpi_get_table()
> > Parse the table
> > Do your driver late stuff here
> > <- note there is no API now being an inverse of acpi_get_table().
> 
> That's fine.  These are two different methods to access the table.
> I need one that works in both cases.  Of course, they could be combined,
> but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
> seems to be an implementation detail of ACPI code.
> 
> Instead I am going to use the 1st method once and cache the result like this:
> 
> 
> static int __init parse(void)
> {
> 	static bool parsed;
> 
> 	if (!parsed) {
> 		acpi_get_table_with_size()
> 		/* parse the table and cache the result */
> 		early_acpi_os_unmap_memory()
> 		parse = true;
> 	}
> }
> 
> arch_initcal(parse());
> 
> int __ref the_handler_where_I_need_the_parse_results(void)
> {
> 	parse();
> 
> 	/* use the data */
> }
> 
> I hope you are OK with it.
> 
> > Besides, I'm about to insert error messages between 1 and 2.
> > If an early map is not release, error message will be prompted to the
> developers.
> 
> AFAICS, there is such an error message and I saw it.
> Refer to check_early_ioremap_leak() at mm/early_ioremap.c
> 
> > And if you don't follow the above rules, it mean you are trying to lay a mine,
> waiting for me to step on it.
> > That's why this change is entirely not acceptable.
> 
> Ok, I see.
> 
> > I'm about to send out the cleanup series in 1 week, and will Cc you.
> > You can rebase your code on top of the cleanup series.
> 
> Thank you
> Aleksey Makarov
> 
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>> The central problem here is the way Aleksey is trying to hookup a console.
> >>>>
> >>>> What should be happening in this series is:
> >>>> 1. early map SPCR
> >>>> 2. parse the SPCR table
> >>>> 3. call add_preferred_console() to add the SPCR console to the console
> >> table
> >>>> 4. unmap SPCR
> >>>>
> >>>> This trivial and unobtrusive method would already have a 8250 console
> >>>> running via SPCR. I've already pointed this out in previous reviews.
> >>>>
> >>>> Further, the above method *will be required anyway* for the DBG2 table
> to
> >>>> start an earlycon, which I've already pointed out in previous reviews.
> >>>>
> >>>> Then to enable amba-pl011 console via ACPI, add a console match()
> method
> >>>> similar to the 8250 console match() method, univ8250_console_match().
> >>>>
> >>>> FWIW, PCI earlycon + console support was already submitted once before
> >> but
> >>>> never picked up by GregKH. I think I'll just grab that and re-submit so
> >>>> you would know what to emit for console options in the
> >>>> add_preferred_console().
> >>>>
> >>>>
> >>>> Regards,
> >>>> Peter Hurley
> >>>>
> >>>>
> >>>>>>> There is an early bootup requirement in Linux.
> >>>>>>> Maps acquired during the early stage should be freed by the driver
> during
> >>>> the
> >>>>>> early stage.
> >>>>>>> And the driver should re-acquire the memory map after booting.
> >>>>>>
> >>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
> >> that
> >>>>>> that code can be
> >>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
> >> of
> >>>> for
> >>>>>> example 8250 console)
> >>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
> >> that
> >>>>>> registers a console),
> >>>>>> We just can not tell if the received table pointer should or sould not be
> >> freed
> >>>>>> with early_memunmap()
> >>>>>> (actually __acpi_unmap_table() or whatever) without checking
> >>>>>> acpi_gbl_permanent_mmap,
> >>>>>> but that's all too low level.
> >>>>> [Lv Zheng]
> >>>>> The driver should make sure that:
> >>>>> Map/unmap is paired during early stage.
> >>>>> For late stage, it should be another pair of map/unmap.
> >>>>>
> >>>>>>
> >>>>>> Another option, as you describe, is to get this pointer early, don't free it
> >>>>> [Lv Zheng]
> >>>>> I mean you should free it early.
> >>>>>
> >>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
> >>>>>> early_acpi_os_unmap_memory(), that's
> >>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
> >> the
> >>>>>> persistent
> >>>>>> pointer to the table.  The problem with it is that we can not just watch
> >>>>>> acpi_gbl_permanent_mmap
> >>>>>> to catch this exact moment.  And also accessing
> >> acpi_gbl_permanent_mmap
> >>>> is
> >>>>>> not good as it probably is
> >>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >>>>>> Or I probably miss what you are suggesting.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> I mean, you should:
> >>>>> During early stage:
> >>>>> acpi_os_map_memory()
> >>>>> Parse the table.
> >>>>> acpi_os_unmap_memory().
> >>>>>
> >>>>>>> This is because, during early bootup stage, there are only limited slots
> >>>>>> available for drivers to map memory.
> >>>>>>> So by changing __init to __ref here, you probably will hide many such
> >>>> defects.
> >>>>>>
> >>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >>>>>> BTW, exactly the same thing is done in the beginning of
> >>>>>> acpi_os_unmap_memory() and than's ok,
> >>>>>> that function is __ref.
> >>>>>>
> >>>>>>> And solving issues in this way doesn't seem to be an improvement.
> >>>>>>
> >>>>>> Could you please tell me where I am wrong?  I still don't understand
> your
> >>>> point.
> >>>>> [Lv Zheng]
> >>>>> But anyway, the defect should be in ACPI subsystem core.
> >>>>> The cause should be the API itself - acpi_get_table().
> >>>>>
> >>>>> So I agree you can use early_acpi_os_unmap_memory() during the
> period
> >> the
> >>>> root causes are not cleaned up.
> >>>>> But the bottom line is: the driver need to ensure that
> >>>> early_acpi_os_unmap_memory() is always invoked.
> >>>>> As long as you can ensure this, I don't have objections for deploying
> >>>> early_acpi_os_unmap_memory()  for now.
> >>>>>
> >>>>> Thanks and best regards
> >>>>> -Lv
> >>>>>
> >>>>>>
> >>>>>> Thank you
> >>>>>> Aleksey Makarov
> >>>>>>
> >>>>>>>
> >>>>>>> Thanks and best regards
> >>>>>>> -Lv
> >>>>>>>
> >>>>>>>>
> >>>>>>>> Thanks and best regards
> >>>>>>>> -Lv
> >>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>>>>>> ---
> >>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>>>>>> index 67da6fb..8a552cd 100644
> >>>>>>>>> --- a/drivers/acpi/osl.c
> >>>>>>>>> +++ b/drivers/acpi/osl.c
> >>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
> >> *virt,
> >>>>>>>>> acpi_size size)
> >>>>>>>>>  }
> >>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>>>>>
> >>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>> +/*
> >>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
> >> anywhere
> >>>>>>>>> + */
> >>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>>  {
> >>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>>>>>  		__acpi_unmap_table(virt, size);
> >>>>>>>>> --
> >>>>>>>>> 2.7.1
> >>>>>>>>>
> >>>>>>>>> --
> >>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi"
> in
> >>>>>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> >> info.html
> >>>>>>>> --
> >>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> info.html
> >>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* RE: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-26  6:39                       ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-26  6:39 UTC (permalink / raw)
  To: Aleksey Makarov, Peter Hurley, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

Hi, Aleksey

Though I promised you to have this done in 1 week:
https://github.com/zetalog/acpica/commit/a234569
I implemented the idea and tried the cleanup in Linux.
But unfortunately the cleanup triggered several locking issues inside of ACPICA table API users.
So it doesn't seem to be so easy and quick to make it upstreamed.
And I have to continue to test and improve the cleanup.

I'm sorry for that, hope you can find substitute solutions before the cleanup is upstreamed.

Thanks and best regards
-Lv

> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> Sent: Monday, February 22, 2016 10:58 PM
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi,
> 
> On 02/22/2016 05:24 AM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> Hi Lv,
> >>
> >> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> >>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>> early_acpi_os_unmap_memory()
> >>>>
> >>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> >>>>> Hi,
> >>>>>
> >>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
> >>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>>
> >>>>>> Hi Lv,
> >>>>>>
> >>>>>> Thank you for review.
> >>>>>>
> >>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>>>>>
> >>>>>> [..]
> >>>>>>
> >>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap
> is
> >> not
> >>>>>> set.
> >>>>>>>>>
> >>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>>>>>
> >>>>>>>>> We need this function to be non-__init because we need access to
> >>>>>>>>> some tables at unpredictable time--it may be before or after
> >>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> >>>> Console
> >>>>>>>>> Redirection) table is needed each time a new console is registered.
> >>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>>>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>>>>>> does.
> >>>>>>>> [Lv Zheng]
> >>>>>>>> Why don't you use another API instead of
> >>>> early_acpi_os_unmap_memory()
> >>>>>> in
> >>>>>>>> case you want to unmap things in any cases.
> >>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>>>>>
> >>>>>> As far as I understand, there exist two steps in ACPI initialization:
> >>>>>>
> >>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >>>>>> acpi_get_table_with_size()
> >>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer
> it
> >>>>>> should be unmapped.
> >>>>>>
> >>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> >>>> unmapped
> >>>>>> at all.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> This statement is wrong, this should be:
> >>>>> As long as there is a __reference__ to the mapped table, the pointer
> should
> >>>> not be unmapped.
> >>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
> >>>>> So your argument is wrong from very first point.
> >>>>>
> >>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
> >>>>>> acpi_gbl_permanent_mmap.
> >>>>>> If I had used acpi_os_unmap_memory() after
> acpi_gbl_permanent_mmap
> >>>> had
> >>>>>> been set,
> >>>>>> it would have tried to free that pointer with an oops (actually, I
> checked
> >> that
> >>>>>> and got that oops).
> >>>>>>
> >>>>>> So using acpi_os_unmap_memory() is not an option here, but
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>> match perfectly.
> >>>>> [Lv Zheng]
> >>>>> I don't think so.
> >>>>> For definition block tables, we know for sure there will always be
> >> references,
> >>>> until "Unload" opcode is invoked by the AML interpreter.
> >>>>> But for the data tables, OSPMs should use them in this way:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structures
> >>>>> 3. unmap the table
> >>>>> This helps to shrink virtual memory address space usages.
> >>>>>
> >>>>> So from this point of view, all data tables should be unmapped right
> after
> >>>> being parsed.
> >>>>> Why do you need the map to be persistent in the kernel address space?
> >>>>> You can always map a small table, but what if the table size is very big?
> >>>>>
> >>>>>>
> >>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>>>>>
> >>>>>> I don't think so -- I have explained why.  It does different thing.
> >>>>>> Probably it (and/or other functions in that api) should be renamed.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> Just let me ask one more question.
> >>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> >>>>> How ACPICA can work with just acpi_os_unmap_memory()?
> >>>>> You can check drivers/acpi/tbxxx.c.
> >>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
> >>>>>
> >>>>>>> [Lv Zheng]
> >>>>>>> One more thing is:
> >>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
> instead
> >> of
> >>>>>> early_acpi_os_unmap_memory(),
> >>>>>>> then it implies that your driver does have a defect.
> >>>>>>
> >>>>>> I still don't understand what defect, sorry.
> >>>>> [Lv Zheng]
> >>>>> If you can't ensure this sequence for using the data tables:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structure
> >>>>> 3. unmap the table
> >>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> >>>>
> >>>> Exactly.
> >>> [Lv Zheng]
> >>> So it looks to me:
> >>> Changing __init to __ref here is entirely not acceptable.
> >>> This API should stay being invoked during early stage.
> >>> Otherwise, it may leave us untrackable code that maps tables during early
> >> stage and leaks maps to the late stage.
> >>> If Linux contains such kind of code, I'm afraid, it will become impossible to
> >> introduce acpi_put_table() to clean up the mappings.
> >>> Because when acpi_put_table() is called during the late stage to free a map
> >> acquired during the early stage, it then obviously will end up with panic.
> >>
> >> Can you please sugggest a common method to access ACPI tables that
> >> works both before *and* after acpi_gbl_permanent_mmap is set and __init
> >> code
> >> is removed?
> > [Lv Zheng]
> > Do not change __init for now.
> >
> > Currently you should:
> > 1. before acpi_gbl_permanent_mmap is set:
> > acpi_get_table_with_size()
> > parse the table
> > early_acpi_os_unmap_memory()
> > Do your driver early stuff here
> >
> > 2. after acpi_gbl_permanent_mmap is set:
> > acpi_get_table()
> > Parse the table
> > Do your driver late stuff here
> > <- note there is no API now being an inverse of acpi_get_table().
> 
> That's fine.  These are two different methods to access the table.
> I need one that works in both cases.  Of course, they could be combined,
> but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
> seems to be an implementation detail of ACPI code.
> 
> Instead I am going to use the 1st method once and cache the result like this:
> 
> 
> static int __init parse(void)
> {
> 	static bool parsed;
> 
> 	if (!parsed) {
> 		acpi_get_table_with_size()
> 		/* parse the table and cache the result */
> 		early_acpi_os_unmap_memory()
> 		parse = true;
> 	}
> }
> 
> arch_initcal(parse());
> 
> int __ref the_handler_where_I_need_the_parse_results(void)
> {
> 	parse();
> 
> 	/* use the data */
> }
> 
> I hope you are OK with it.
> 
> > Besides, I'm about to insert error messages between 1 and 2.
> > If an early map is not release, error message will be prompted to the
> developers.
> 
> AFAICS, there is such an error message and I saw it.
> Refer to check_early_ioremap_leak() at mm/early_ioremap.c
> 
> > And if you don't follow the above rules, it mean you are trying to lay a mine,
> waiting for me to step on it.
> > That's why this change is entirely not acceptable.
> 
> Ok, I see.
> 
> > I'm about to send out the cleanup series in 1 week, and will Cc you.
> > You can rebase your code on top of the cleanup series.
> 
> Thank you
> Aleksey Makarov
> 
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>> The central problem here is the way Aleksey is trying to hookup a console.
> >>>>
> >>>> What should be happening in this series is:
> >>>> 1. early map SPCR
> >>>> 2. parse the SPCR table
> >>>> 3. call add_preferred_console() to add the SPCR console to the console
> >> table
> >>>> 4. unmap SPCR
> >>>>
> >>>> This trivial and unobtrusive method would already have a 8250 console
> >>>> running via SPCR. I've already pointed this out in previous reviews.
> >>>>
> >>>> Further, the above method *will be required anyway* for the DBG2 table
> to
> >>>> start an earlycon, which I've already pointed out in previous reviews.
> >>>>
> >>>> Then to enable amba-pl011 console via ACPI, add a console match()
> method
> >>>> similar to the 8250 console match() method, univ8250_console_match().
> >>>>
> >>>> FWIW, PCI earlycon + console support was already submitted once before
> >> but
> >>>> never picked up by GregKH. I think I'll just grab that and re-submit so
> >>>> you would know what to emit for console options in the
> >>>> add_preferred_console().
> >>>>
> >>>>
> >>>> Regards,
> >>>> Peter Hurley
> >>>>
> >>>>
> >>>>>>> There is an early bootup requirement in Linux.
> >>>>>>> Maps acquired during the early stage should be freed by the driver
> during
> >>>> the
> >>>>>> early stage.
> >>>>>>> And the driver should re-acquire the memory map after booting.
> >>>>>>
> >>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
> >> that
> >>>>>> that code can be
> >>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
> >> of
> >>>> for
> >>>>>> example 8250 console)
> >>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
> >> that
> >>>>>> registers a console),
> >>>>>> We just can not tell if the received table pointer should or sould not be
> >> freed
> >>>>>> with early_memunmap()
> >>>>>> (actually __acpi_unmap_table() or whatever) without checking
> >>>>>> acpi_gbl_permanent_mmap,
> >>>>>> but that's all too low level.
> >>>>> [Lv Zheng]
> >>>>> The driver should make sure that:
> >>>>> Map/unmap is paired during early stage.
> >>>>> For late stage, it should be another pair of map/unmap.
> >>>>>
> >>>>>>
> >>>>>> Another option, as you describe, is to get this pointer early, don't free it
> >>>>> [Lv Zheng]
> >>>>> I mean you should free it early.
> >>>>>
> >>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
> >>>>>> early_acpi_os_unmap_memory(), that's
> >>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
> >> the
> >>>>>> persistent
> >>>>>> pointer to the table.  The problem with it is that we can not just watch
> >>>>>> acpi_gbl_permanent_mmap
> >>>>>> to catch this exact moment.  And also accessing
> >> acpi_gbl_permanent_mmap
> >>>> is
> >>>>>> not good as it probably is
> >>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >>>>>> Or I probably miss what you are suggesting.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> I mean, you should:
> >>>>> During early stage:
> >>>>> acpi_os_map_memory()
> >>>>> Parse the table.
> >>>>> acpi_os_unmap_memory().
> >>>>>
> >>>>>>> This is because, during early bootup stage, there are only limited slots
> >>>>>> available for drivers to map memory.
> >>>>>>> So by changing __init to __ref here, you probably will hide many such
> >>>> defects.
> >>>>>>
> >>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >>>>>> BTW, exactly the same thing is done in the beginning of
> >>>>>> acpi_os_unmap_memory() and than's ok,
> >>>>>> that function is __ref.
> >>>>>>
> >>>>>>> And solving issues in this way doesn't seem to be an improvement.
> >>>>>>
> >>>>>> Could you please tell me where I am wrong?  I still don't understand
> your
> >>>> point.
> >>>>> [Lv Zheng]
> >>>>> But anyway, the defect should be in ACPI subsystem core.
> >>>>> The cause should be the API itself - acpi_get_table().
> >>>>>
> >>>>> So I agree you can use early_acpi_os_unmap_memory() during the
> period
> >> the
> >>>> root causes are not cleaned up.
> >>>>> But the bottom line is: the driver need to ensure that
> >>>> early_acpi_os_unmap_memory() is always invoked.
> >>>>> As long as you can ensure this, I don't have objections for deploying
> >>>> early_acpi_os_unmap_memory()  for now.
> >>>>>
> >>>>> Thanks and best regards
> >>>>> -Lv
> >>>>>
> >>>>>>
> >>>>>> Thank you
> >>>>>> Aleksey Makarov
> >>>>>>
> >>>>>>>
> >>>>>>> Thanks and best regards
> >>>>>>> -Lv
> >>>>>>>
> >>>>>>>>
> >>>>>>>> Thanks and best regards
> >>>>>>>> -Lv
> >>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>>>>>> ---
> >>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>>>>>> index 67da6fb..8a552cd 100644
> >>>>>>>>> --- a/drivers/acpi/osl.c
> >>>>>>>>> +++ b/drivers/acpi/osl.c
> >>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
> >> *virt,
> >>>>>>>>> acpi_size size)
> >>>>>>>>>  }
> >>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>>>>>
> >>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>> +/*
> >>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
> >> anywhere
> >>>>>>>>> + */
> >>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>>  {
> >>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>>>>>  		__acpi_unmap_table(virt, size);
> >>>>>>>>> --
> >>>>>>>>> 2.7.1
> >>>>>>>>>
> >>>>>>>>> --
> >>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi"
> in
> >>>>>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> >> info.html
> >>>>>>>> --
> >>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>>>> the body of a message to majordomo@vger.kernel.org
> >>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> info.html
> >>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-26  6:39                       ` Zheng, Lv
  0 siblings, 0 replies; 86+ messages in thread
From: Zheng, Lv @ 2016-02-26  6:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi, Aleksey

Though I promised you to have this done in 1 week:
https://github.com/zetalog/acpica/commit/a234569
I implemented the idea and tried the cleanup in Linux.
But unfortunately the cleanup triggered several locking issues inside of ACPICA table API users.
So it doesn't seem to be so easy and quick to make it upstreamed.
And I have to continue to test and improve the cleanup.

I'm sorry for that, hope you can find substitute solutions before the cleanup is upstreamed.

Thanks and best regards
-Lv

> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
> Sent: Monday, February 22, 2016 10:58 PM
> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> early_acpi_os_unmap_memory()
> 
> Hi,
> 
> On 02/22/2016 05:24 AM, Zheng, Lv wrote:
> > Hi,
> >
> >> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
> >> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >> early_acpi_os_unmap_memory()
> >>
> >> Hi Lv,
> >>
> >> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
> >>> Hi,
> >>>
> >>>> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> >>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>> early_acpi_os_unmap_memory()
> >>>>
> >>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
> >>>>> Hi,
> >>>>>
> >>>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
> >>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>>
> >>>>>> Hi Lv,
> >>>>>>
> >>>>>> Thank you for review.
> >>>>>>
> >>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
> >>>>>>
> >>>>>> [..]
> >>>>>>
> >>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
> >>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap
> is
> >> not
> >>>>>> set.
> >>>>>>>>>
> >>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
> >>>>>>>>>
> >>>>>>>>> We need this function to be non-__init because we need access to
> >>>>>>>>> some tables at unpredictable time--it may be before or after
> >>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
> >>>> Console
> >>>>>>>>> Redirection) table is needed each time a new console is registered.
> >>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
> >>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
> >>>>>>>>> the pointer should be unmapped.  This is exactly what this function
> >>>>>>>>> does.
> >>>>>>>> [Lv Zheng]
> >>>>>>>> Why don't you use another API instead of
> >>>> early_acpi_os_unmap_memory()
> >>>>>> in
> >>>>>>>> case you want to unmap things in any cases.
> >>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
> >>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
> >>>>>>
> >>>>>> As far as I understand, there exist two steps in ACPI initialization:
> >>>>>>
> >>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
> >>>>>> acpi_get_table_with_size()
> >>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer
> it
> >>>>>> should be unmapped.
> >>>>>>
> >>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
> >>>> unmapped
> >>>>>> at all.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> This statement is wrong, this should be:
> >>>>> As long as there is a __reference__ to the mapped table, the pointer
> should
> >>>> not be unmapped.
> >>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
> >>>>> So your argument is wrong from very first point.
> >>>>>
> >>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
> >>>>>> acpi_gbl_permanent_mmap.
> >>>>>> If I had used acpi_os_unmap_memory() after
> acpi_gbl_permanent_mmap
> >>>> had
> >>>>>> been set,
> >>>>>> it would have tried to free that pointer with an oops (actually, I
> checked
> >> that
> >>>>>> and got that oops).
> >>>>>>
> >>>>>> So using acpi_os_unmap_memory() is not an option here, but
> >>>>>> early_acpi_os_unmap_memory()
> >>>>>> match perfectly.
> >>>>> [Lv Zheng]
> >>>>> I don't think so.
> >>>>> For definition block tables, we know for sure there will always be
> >> references,
> >>>> until "Unload" opcode is invoked by the AML interpreter.
> >>>>> But for the data tables, OSPMs should use them in this way:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structures
> >>>>> 3. unmap the table
> >>>>> This helps to shrink virtual memory address space usages.
> >>>>>
> >>>>> So from this point of view, all data tables should be unmapped right
> after
> >>>> being parsed.
> >>>>> Why do you need the map to be persistent in the kernel address space?
> >>>>> You can always map a small table, but what if the table size is very big?
> >>>>>
> >>>>>>
> >>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
> >>>>>>
> >>>>>> I don't think so -- I have explained why.  It does different thing.
> >>>>>> Probably it (and/or other functions in that api) should be renamed.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> Just let me ask one more question.
> >>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
> >>>>> How ACPICA can work with just acpi_os_unmap_memory()?
> >>>>> You can check drivers/acpi/tbxxx.c.
> >>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
> >>>>>
> >>>>>>> [Lv Zheng]
> >>>>>>> One more thing is:
> >>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
> instead
> >> of
> >>>>>> early_acpi_os_unmap_memory(),
> >>>>>>> then it implies that your driver does have a defect.
> >>>>>>
> >>>>>> I still don't understand what defect, sorry.
> >>>>> [Lv Zheng]
> >>>>> If you can't ensure this sequence for using the data tables:
> >>>>> 1. map the table
> >>>>> 2. parse the table and convert it to OS specific structure
> >>>>> 3. unmap the table
> >>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
> >>>>
> >>>> Exactly.
> >>> [Lv Zheng]
> >>> So it looks to me:
> >>> Changing __init to __ref here is entirely not acceptable.
> >>> This API should stay being invoked during early stage.
> >>> Otherwise, it may leave us untrackable code that maps tables during early
> >> stage and leaks maps to the late stage.
> >>> If Linux contains such kind of code, I'm afraid, it will become impossible to
> >> introduce acpi_put_table() to clean up the mappings.
> >>> Because when acpi_put_table() is called during the late stage to free a map
> >> acquired during the early stage, it then obviously will end up with panic.
> >>
> >> Can you please sugggest a common method to access ACPI tables that
> >> works both before *and* after acpi_gbl_permanent_mmap is set and __init
> >> code
> >> is removed?
> > [Lv Zheng]
> > Do not change __init for now.
> >
> > Currently you should:
> > 1. before acpi_gbl_permanent_mmap is set:
> > acpi_get_table_with_size()
> > parse the table
> > early_acpi_os_unmap_memory()
> > Do your driver early stuff here
> >
> > 2. after acpi_gbl_permanent_mmap is set:
> > acpi_get_table()
> > Parse the table
> > Do your driver late stuff here
> > <- note there is no API now being an inverse of acpi_get_table().
> 
> That's fine.  These are two different methods to access the table.
> I need one that works in both cases.  Of course, they could be combined,
> but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
> seems to be an implementation detail of ACPI code.
> 
> Instead I am going to use the 1st method once and cache the result like this:
> 
> 
> static int __init parse(void)
> {
> 	static bool parsed;
> 
> 	if (!parsed) {
> 		acpi_get_table_with_size()
> 		/* parse the table and cache the result */
> 		early_acpi_os_unmap_memory()
> 		parse = true;
> 	}
> }
> 
> arch_initcal(parse());
> 
> int __ref the_handler_where_I_need_the_parse_results(void)
> {
> 	parse();
> 
> 	/* use the data */
> }
> 
> I hope you are OK with it.
> 
> > Besides, I'm about to insert error messages between 1 and 2.
> > If an early map is not release, error message will be prompted to the
> developers.
> 
> AFAICS, there is such an error message and I saw it.
> Refer to check_early_ioremap_leak() at mm/early_ioremap.c
> 
> > And if you don't follow the above rules, it mean you are trying to lay a mine,
> waiting for me to step on it.
> > That's why this change is entirely not acceptable.
> 
> Ok, I see.
> 
> > I'm about to send out the cleanup series in 1 week, and will Cc you.
> > You can rebase your code on top of the cleanup series.
> 
> Thank you
> Aleksey Makarov
> 
> >
> > Thanks and best regards
> > -Lv
> >
> >>
> >>> Thanks and best regards
> >>> -Lv
> >>>
> >>>> The central problem here is the way Aleksey is trying to hookup a console.
> >>>>
> >>>> What should be happening in this series is:
> >>>> 1. early map SPCR
> >>>> 2. parse the SPCR table
> >>>> 3. call add_preferred_console() to add the SPCR console to the console
> >> table
> >>>> 4. unmap SPCR
> >>>>
> >>>> This trivial and unobtrusive method would already have a 8250 console
> >>>> running via SPCR. I've already pointed this out in previous reviews.
> >>>>
> >>>> Further, the above method *will be required anyway* for the DBG2 table
> to
> >>>> start an earlycon, which I've already pointed out in previous reviews.
> >>>>
> >>>> Then to enable amba-pl011 console via ACPI, add a console match()
> method
> >>>> similar to the 8250 console match() method, univ8250_console_match().
> >>>>
> >>>> FWIW, PCI earlycon + console support was already submitted once before
> >> but
> >>>> never picked up by GregKH. I think I'll just grab that and re-submit so
> >>>> you would know what to emit for console options in the
> >>>> add_preferred_console().
> >>>>
> >>>>
> >>>> Regards,
> >>>> Peter Hurley
> >>>>
> >>>>
> >>>>>>> There is an early bootup requirement in Linux.
> >>>>>>> Maps acquired during the early stage should be freed by the driver
> during
> >>>> the
> >>>>>> early stage.
> >>>>>>> And the driver should re-acquire the memory map after booting.
> >>>>>>
> >>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
> >> that
> >>>>>> that code can be
> >>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
> >> of
> >>>> for
> >>>>>> example 8250 console)
> >>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
> >> that
> >>>>>> registers a console),
> >>>>>> We just can not tell if the received table pointer should or sould not be
> >> freed
> >>>>>> with early_memunmap()
> >>>>>> (actually __acpi_unmap_table() or whatever) without checking
> >>>>>> acpi_gbl_permanent_mmap,
> >>>>>> but that's all too low level.
> >>>>> [Lv Zheng]
> >>>>> The driver should make sure that:
> >>>>> Map/unmap is paired during early stage.
> >>>>> For late stage, it should be another pair of map/unmap.
> >>>>>
> >>>>>>
> >>>>>> Another option, as you describe, is to get this pointer early, don't free it
> >>>>> [Lv Zheng]
> >>>>> I mean you should free it early.
> >>>>>
> >>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
> >>>>>> early_acpi_os_unmap_memory(), that's
> >>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
> >> the
> >>>>>> persistent
> >>>>>> pointer to the table.  The problem with it is that we can not just watch
> >>>>>> acpi_gbl_permanent_mmap
> >>>>>> to catch this exact moment.  And also accessing
> >> acpi_gbl_permanent_mmap
> >>>> is
> >>>>>> not good as it probably is
> >>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
> >>>>>> Or I probably miss what you are suggesting.
> >>>>>>
> >>>>> [Lv Zheng]
> >>>>> I mean, you should:
> >>>>> During early stage:
> >>>>> acpi_os_map_memory()
> >>>>> Parse the table.
> >>>>> acpi_os_unmap_memory().
> >>>>>
> >>>>>>> This is because, during early bootup stage, there are only limited slots
> >>>>>> available for drivers to map memory.
> >>>>>>> So by changing __init to __ref here, you probably will hide many such
> >>>> defects.
> >>>>>>
> >>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
> >>>>>> BTW, exactly the same thing is done in the beginning of
> >>>>>> acpi_os_unmap_memory() and than's ok,
> >>>>>> that function is __ref.
> >>>>>>
> >>>>>>> And solving issues in this way doesn't seem to be an improvement.
> >>>>>>
> >>>>>> Could you please tell me where I am wrong?  I still don't understand
> your
> >>>> point.
> >>>>> [Lv Zheng]
> >>>>> But anyway, the defect should be in ACPI subsystem core.
> >>>>> The cause should be the API itself - acpi_get_table().
> >>>>>
> >>>>> So I agree you can use early_acpi_os_unmap_memory() during the
> period
> >> the
> >>>> root causes are not cleaned up.
> >>>>> But the bottom line is: the driver need to ensure that
> >>>> early_acpi_os_unmap_memory() is always invoked.
> >>>>> As long as you can ensure this, I don't have objections for deploying
> >>>> early_acpi_os_unmap_memory()  for now.
> >>>>>
> >>>>> Thanks and best regards
> >>>>> -Lv
> >>>>>
> >>>>>>
> >>>>>> Thank you
> >>>>>> Aleksey Makarov
> >>>>>>
> >>>>>>>
> >>>>>>> Thanks and best regards
> >>>>>>> -Lv
> >>>>>>>
> >>>>>>>>
> >>>>>>>> Thanks and best regards
> >>>>>>>> -Lv
> >>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> >>>>>>>>> ---
> >>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
> >>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>>>>>>>>
> >>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
> >>>>>>>>> index 67da6fb..8a552cd 100644
> >>>>>>>>> --- a/drivers/acpi/osl.c
> >>>>>>>>> +++ b/drivers/acpi/osl.c
> >>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
> >> *virt,
> >>>>>>>>> acpi_size size)
> >>>>>>>>>  }
> >>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
> >>>>>>>>>
> >>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>> +/*
> >>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
> >>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
> >> anywhere
> >>>>>>>>> + */
> >>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
> >>>> acpi_size
> >>>>>>>> size)
> >>>>>>>>>  {
> >>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
> >>>>>>>>>  		__acpi_unmap_table(virt, size);
> >>>>>>>>> --
> >>>>>>>>> 2.7.1
> >>>>>>>>>
> >>>>>>>>> --
> >>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi"
> in
> >>>>>>>>> the body of a message to majordomo at vger.kernel.org
> >>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> >> info.html
> >>>>>>>> --
> >>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> >>>>>>>> the body of a message to majordomo at vger.kernel.org
> >>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
> info.html
> >>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-26  6:39                       ` Zheng, Lv
  (?)
@ 2016-02-26 10:33                         ` Aleksey Makarov
  -1 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-26 10:33 UTC (permalink / raw)
  To: Zheng, Lv
  Cc: Peter Hurley, linux-acpi, linux-serial, linux-kernel,
	linux-arm-kernel, Russell King, Greg Kroah-Hartman,
	Rafael J . Wysocki, Leif Lindholm, Graeme Gregory, Al Stone,
	Christopher Covington, Len Brown



On 02/26/2016 09:39 AM, Zheng, Lv wrote:
> Hi, Aleksey
> 
> Though I promised you to have this done in 1 week:
> https://github.com/zetalog/acpica/commit/a234569
> I implemented the idea and tried the cleanup in Linux.
> But unfortunately the cleanup triggered several locking issues inside of ACPICA table API users.
> So it doesn't seem to be so easy and quick to make it upstreamed.
> And I have to continue to test and improve the cleanup.
> 
> I'm sorry for that, hope you can find substitute solutions before the cleanup is upstreamed.

That's fine, I use the approach I described in the last mail, it works.

Thank you
Aleksey Makarov

> 
> Thanks and best regards
> -Lv
> 
>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>> Sent: Monday, February 22, 2016 10:58 PM
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> Hi,
>>
>> On 02/22/2016 05:24 AM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> Hi Lv,
>>>>
>>>> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>>>> early_acpi_os_unmap_memory()
>>>>>>>>
>>>>>>>> Hi Lv,
>>>>>>>>
>>>>>>>> Thank you for review.
>>>>>>>>
>>>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>>>
>>>>>>>> [..]
>>>>>>>>
>>>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap
>> is
>>>> not
>>>>>>>> set.
>>>>>>>>>>>
>>>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>>>>
>>>>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>>>>>> Console
>>>>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>>>>> does.
>>>>>>>>>> [Lv Zheng]
>>>>>>>>>> Why don't you use another API instead of
>>>>>> early_acpi_os_unmap_memory()
>>>>>>>> in
>>>>>>>>>> case you want to unmap things in any cases.
>>>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>>>
>>>>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>>>>
>>>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>>>> acpi_get_table_with_size()
>>>>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer
>> it
>>>>>>>> should be unmapped.
>>>>>>>>
>>>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>>>>>> unmapped
>>>>>>>> at all.
>>>>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> This statement is wrong, this should be:
>>>>>>> As long as there is a __reference__ to the mapped table, the pointer
>> should
>>>>>> not be unmapped.
>>>>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>>>>> So your argument is wrong from very first point.
>>>>>>>
>>>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>>>> acpi_gbl_permanent_mmap.
>>>>>>>> If I had used acpi_os_unmap_memory() after
>> acpi_gbl_permanent_mmap
>>>>>> had
>>>>>>>> been set,
>>>>>>>> it would have tried to free that pointer with an oops (actually, I
>> checked
>>>> that
>>>>>>>> and got that oops).
>>>>>>>>
>>>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>>>> early_acpi_os_unmap_memory()
>>>>>>>> match perfectly.
>>>>>>> [Lv Zheng]
>>>>>>> I don't think so.
>>>>>>> For definition block tables, we know for sure there will always be
>>>> references,
>>>>>> until "Unload" opcode is invoked by the AML interpreter.
>>>>>>> But for the data tables, OSPMs should use them in this way:
>>>>>>> 1. map the table
>>>>>>> 2. parse the table and convert it to OS specific structures
>>>>>>> 3. unmap the table
>>>>>>> This helps to shrink virtual memory address space usages.
>>>>>>>
>>>>>>> So from this point of view, all data tables should be unmapped right
>> after
>>>>>> being parsed.
>>>>>>> Why do you need the map to be persistent in the kernel address space?
>>>>>>> You can always map a small table, but what if the table size is very big?
>>>>>>>
>>>>>>>>
>>>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>>>
>>>>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> Just let me ask one more question.
>>>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>>>> You can check drivers/acpi/tbxxx.c.
>>>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>>>
>>>>>>>>> [Lv Zheng]
>>>>>>>>> One more thing is:
>>>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>> instead
>>>> of
>>>>>>>> early_acpi_os_unmap_memory(),
>>>>>>>>> then it implies that your driver does have a defect.
>>>>>>>>
>>>>>>>> I still don't understand what defect, sorry.
>>>>>>> [Lv Zheng]
>>>>>>> If you can't ensure this sequence for using the data tables:
>>>>>>> 1. map the table
>>>>>>> 2. parse the table and convert it to OS specific structure
>>>>>>> 3. unmap the table
>>>>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>>>>
>>>>>> Exactly.
>>>>> [Lv Zheng]
>>>>> So it looks to me:
>>>>> Changing __init to __ref here is entirely not acceptable.
>>>>> This API should stay being invoked during early stage.
>>>>> Otherwise, it may leave us untrackable code that maps tables during early
>>>> stage and leaks maps to the late stage.
>>>>> If Linux contains such kind of code, I'm afraid, it will become impossible to
>>>> introduce acpi_put_table() to clean up the mappings.
>>>>> Because when acpi_put_table() is called during the late stage to free a map
>>>> acquired during the early stage, it then obviously will end up with panic.
>>>>
>>>> Can you please sugggest a common method to access ACPI tables that
>>>> works both before *and* after acpi_gbl_permanent_mmap is set and __init
>>>> code
>>>> is removed?
>>> [Lv Zheng]
>>> Do not change __init for now.
>>>
>>> Currently you should:
>>> 1. before acpi_gbl_permanent_mmap is set:
>>> acpi_get_table_with_size()
>>> parse the table
>>> early_acpi_os_unmap_memory()
>>> Do your driver early stuff here
>>>
>>> 2. after acpi_gbl_permanent_mmap is set:
>>> acpi_get_table()
>>> Parse the table
>>> Do your driver late stuff here
>>> <- note there is no API now being an inverse of acpi_get_table().
>>
>> That's fine.  These are two different methods to access the table.
>> I need one that works in both cases.  Of course, they could be combined,
>> but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
>> seems to be an implementation detail of ACPI code.
>>
>> Instead I am going to use the 1st method once and cache the result like this:
>>
>>
>> static int __init parse(void)
>> {
>> 	static bool parsed;
>>
>> 	if (!parsed) {
>> 		acpi_get_table_with_size()
>> 		/* parse the table and cache the result */
>> 		early_acpi_os_unmap_memory()
>> 		parse = true;
>> 	}
>> }
>>
>> arch_initcal(parse());
>>
>> int __ref the_handler_where_I_need_the_parse_results(void)
>> {
>> 	parse();
>>
>> 	/* use the data */
>> }
>>
>> I hope you are OK with it.
>>
>>> Besides, I'm about to insert error messages between 1 and 2.
>>> If an early map is not release, error message will be prompted to the
>> developers.
>>
>> AFAICS, there is such an error message and I saw it.
>> Refer to check_early_ioremap_leak() at mm/early_ioremap.c
>>
>>> And if you don't follow the above rules, it mean you are trying to lay a mine,
>> waiting for me to step on it.
>>> That's why this change is entirely not acceptable.
>>
>> Ok, I see.
>>
>>> I'm about to send out the cleanup series in 1 week, and will Cc you.
>>> You can rebase your code on top of the cleanup series.
>>
>> Thank you
>> Aleksey Makarov
>>
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>>>>
>>>>>> What should be happening in this series is:
>>>>>> 1. early map SPCR
>>>>>> 2. parse the SPCR table
>>>>>> 3. call add_preferred_console() to add the SPCR console to the console
>>>> table
>>>>>> 4. unmap SPCR
>>>>>>
>>>>>> This trivial and unobtrusive method would already have a 8250 console
>>>>>> running via SPCR. I've already pointed this out in previous reviews.
>>>>>>
>>>>>> Further, the above method *will be required anyway* for the DBG2 table
>> to
>>>>>> start an earlycon, which I've already pointed out in previous reviews.
>>>>>>
>>>>>> Then to enable amba-pl011 console via ACPI, add a console match()
>> method
>>>>>> similar to the 8250 console match() method, univ8250_console_match().
>>>>>>
>>>>>> FWIW, PCI earlycon + console support was already submitted once before
>>>> but
>>>>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>>>>> you would know what to emit for console options in the
>>>>>> add_preferred_console().
>>>>>>
>>>>>>
>>>>>> Regards,
>>>>>> Peter Hurley
>>>>>>
>>>>>>
>>>>>>>>> There is an early bootup requirement in Linux.
>>>>>>>>> Maps acquired during the early stage should be freed by the driver
>> during
>>>>>> the
>>>>>>>> early stage.
>>>>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>>>>
>>>>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
>>>> that
>>>>>>>> that code can be
>>>>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
>>>> of
>>>>>> for
>>>>>>>> example 8250 console)
>>>>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
>>>> that
>>>>>>>> registers a console),
>>>>>>>> We just can not tell if the received table pointer should or sould not be
>>>> freed
>>>>>>>> with early_memunmap()
>>>>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>>>>> acpi_gbl_permanent_mmap,
>>>>>>>> but that's all too low level.
>>>>>>> [Lv Zheng]
>>>>>>> The driver should make sure that:
>>>>>>> Map/unmap is paired during early stage.
>>>>>>> For late stage, it should be another pair of map/unmap.
>>>>>>>
>>>>>>>>
>>>>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>>>>> [Lv Zheng]
>>>>>>> I mean you should free it early.
>>>>>>>
>>>>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>>>>> early_acpi_os_unmap_memory(), that's
>>>>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
>>>> the
>>>>>>>> persistent
>>>>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>>>>> acpi_gbl_permanent_mmap
>>>>>>>> to catch this exact moment.  And also accessing
>>>> acpi_gbl_permanent_mmap
>>>>>> is
>>>>>>>> not good as it probably is
>>>>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>>>>> Or I probably miss what you are suggesting.
>>>>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> I mean, you should:
>>>>>>> During early stage:
>>>>>>> acpi_os_map_memory()
>>>>>>> Parse the table.
>>>>>>> acpi_os_unmap_memory().
>>>>>>>
>>>>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>>>>> available for drivers to map memory.
>>>>>>>>> So by changing __init to __ref here, you probably will hide many such
>>>>>> defects.
>>>>>>>>
>>>>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>>>>> BTW, exactly the same thing is done in the beginning of
>>>>>>>> acpi_os_unmap_memory() and than's ok,
>>>>>>>> that function is __ref.
>>>>>>>>
>>>>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>>>>
>>>>>>>> Could you please tell me where I am wrong?  I still don't understand
>> your
>>>>>> point.
>>>>>>> [Lv Zheng]
>>>>>>> But anyway, the defect should be in ACPI subsystem core.
>>>>>>> The cause should be the API itself - acpi_get_table().
>>>>>>>
>>>>>>> So I agree you can use early_acpi_os_unmap_memory() during the
>> period
>>>> the
>>>>>> root causes are not cleaned up.
>>>>>>> But the bottom line is: the driver need to ensure that
>>>>>> early_acpi_os_unmap_memory() is always invoked.
>>>>>>> As long as you can ensure this, I don't have objections for deploying
>>>>>> early_acpi_os_unmap_memory()  for now.
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Thank you
>>>>>>>> Aleksey Makarov
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Thanks and best regards
>>>>>>>>> -Lv
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Thanks and best regards
>>>>>>>>>> -Lv
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>>>>> ---
>>>>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
>>>> *virt,
>>>>>>>>>>> acpi_size size)
>>>>>>>>>>>  }
>>>>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>>>>
>>>>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
>>>>>> acpi_size
>>>>>>>>>> size)
>>>>>>>>>>> +/*
>>>>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
>>>> anywhere
>>>>>>>>>>> + */
>>>>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
>>>>>> acpi_size
>>>>>>>>>> size)
>>>>>>>>>>>  {
>>>>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>>>>> --
>>>>>>>>>>> 2.7.1
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi"
>> in
>>>>>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
>>>> info.html
>>>>>>>>>> --
>>>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
>> info.html
>>>>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-26 10:33                         ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-26 10:33 UTC (permalink / raw)
  To: Zheng, Lv
  Cc: Peter Hurley, linux-acpi, linux-serial, linux-kernel,
	linux-arm-kernel, Russell King, Greg Kroah-Hartman,
	Rafael J . Wysocki, Leif Lindholm, Graeme Gregory, Al Stone,
	Christopher Covington, Len Brown



On 02/26/2016 09:39 AM, Zheng, Lv wrote:
> Hi, Aleksey
> 
> Though I promised you to have this done in 1 week:
> https://github.com/zetalog/acpica/commit/a234569
> I implemented the idea and tried the cleanup in Linux.
> But unfortunately the cleanup triggered several locking issues inside of ACPICA table API users.
> So it doesn't seem to be so easy and quick to make it upstreamed.
> And I have to continue to test and improve the cleanup.
> 
> I'm sorry for that, hope you can find substitute solutions before the cleanup is upstreamed.

That's fine, I use the approach I described in the last mail, it works.

Thank you
Aleksey Makarov

> 
> Thanks and best regards
> -Lv
> 
>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>> Sent: Monday, February 22, 2016 10:58 PM
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> Hi,
>>
>> On 02/22/2016 05:24 AM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> Hi Lv,
>>>>
>>>> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>>>> early_acpi_os_unmap_memory()
>>>>>>>>
>>>>>>>> Hi Lv,
>>>>>>>>
>>>>>>>> Thank you for review.
>>>>>>>>
>>>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>>>
>>>>>>>> [..]
>>>>>>>>
>>>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap
>> is
>>>> not
>>>>>>>> set.
>>>>>>>>>>>
>>>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>>>>
>>>>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>>>>>> Console
>>>>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>>>>> does.
>>>>>>>>>> [Lv Zheng]
>>>>>>>>>> Why don't you use another API instead of
>>>>>> early_acpi_os_unmap_memory()
>>>>>>>> in
>>>>>>>>>> case you want to unmap things in any cases.
>>>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>>>
>>>>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>>>>
>>>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>>>> acpi_get_table_with_size()
>>>>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer
>> it
>>>>>>>> should be unmapped.
>>>>>>>>
>>>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>>>>>> unmapped
>>>>>>>> at all.
>>>>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> This statement is wrong, this should be:
>>>>>>> As long as there is a __reference__ to the mapped table, the pointer
>> should
>>>>>> not be unmapped.
>>>>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>>>>> So your argument is wrong from very first point.
>>>>>>>
>>>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>>>> acpi_gbl_permanent_mmap.
>>>>>>>> If I had used acpi_os_unmap_memory() after
>> acpi_gbl_permanent_mmap
>>>>>> had
>>>>>>>> been set,
>>>>>>>> it would have tried to free that pointer with an oops (actually, I
>> checked
>>>> that
>>>>>>>> and got that oops).
>>>>>>>>
>>>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>>>> early_acpi_os_unmap_memory()
>>>>>>>> match perfectly.
>>>>>>> [Lv Zheng]
>>>>>>> I don't think so.
>>>>>>> For definition block tables, we know for sure there will always be
>>>> references,
>>>>>> until "Unload" opcode is invoked by the AML interpreter.
>>>>>>> But for the data tables, OSPMs should use them in this way:
>>>>>>> 1. map the table
>>>>>>> 2. parse the table and convert it to OS specific structures
>>>>>>> 3. unmap the table
>>>>>>> This helps to shrink virtual memory address space usages.
>>>>>>>
>>>>>>> So from this point of view, all data tables should be unmapped right
>> after
>>>>>> being parsed.
>>>>>>> Why do you need the map to be persistent in the kernel address space?
>>>>>>> You can always map a small table, but what if the table size is very big?
>>>>>>>
>>>>>>>>
>>>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>>>
>>>>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> Just let me ask one more question.
>>>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>>>> You can check drivers/acpi/tbxxx.c.
>>>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>>>
>>>>>>>>> [Lv Zheng]
>>>>>>>>> One more thing is:
>>>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>> instead
>>>> of
>>>>>>>> early_acpi_os_unmap_memory(),
>>>>>>>>> then it implies that your driver does have a defect.
>>>>>>>>
>>>>>>>> I still don't understand what defect, sorry.
>>>>>>> [Lv Zheng]
>>>>>>> If you can't ensure this sequence for using the data tables:
>>>>>>> 1. map the table
>>>>>>> 2. parse the table and convert it to OS specific structure
>>>>>>> 3. unmap the table
>>>>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>>>>
>>>>>> Exactly.
>>>>> [Lv Zheng]
>>>>> So it looks to me:
>>>>> Changing __init to __ref here is entirely not acceptable.
>>>>> This API should stay being invoked during early stage.
>>>>> Otherwise, it may leave us untrackable code that maps tables during early
>>>> stage and leaks maps to the late stage.
>>>>> If Linux contains such kind of code, I'm afraid, it will become impossible to
>>>> introduce acpi_put_table() to clean up the mappings.
>>>>> Because when acpi_put_table() is called during the late stage to free a map
>>>> acquired during the early stage, it then obviously will end up with panic.
>>>>
>>>> Can you please sugggest a common method to access ACPI tables that
>>>> works both before *and* after acpi_gbl_permanent_mmap is set and __init
>>>> code
>>>> is removed?
>>> [Lv Zheng]
>>> Do not change __init for now.
>>>
>>> Currently you should:
>>> 1. before acpi_gbl_permanent_mmap is set:
>>> acpi_get_table_with_size()
>>> parse the table
>>> early_acpi_os_unmap_memory()
>>> Do your driver early stuff here
>>>
>>> 2. after acpi_gbl_permanent_mmap is set:
>>> acpi_get_table()
>>> Parse the table
>>> Do your driver late stuff here
>>> <- note there is no API now being an inverse of acpi_get_table().
>>
>> That's fine.  These are two different methods to access the table.
>> I need one that works in both cases.  Of course, they could be combined,
>> but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
>> seems to be an implementation detail of ACPI code.
>>
>> Instead I am going to use the 1st method once and cache the result like this:
>>
>>
>> static int __init parse(void)
>> {
>> 	static bool parsed;
>>
>> 	if (!parsed) {
>> 		acpi_get_table_with_size()
>> 		/* parse the table and cache the result */
>> 		early_acpi_os_unmap_memory()
>> 		parse = true;
>> 	}
>> }
>>
>> arch_initcal(parse());
>>
>> int __ref the_handler_where_I_need_the_parse_results(void)
>> {
>> 	parse();
>>
>> 	/* use the data */
>> }
>>
>> I hope you are OK with it.
>>
>>> Besides, I'm about to insert error messages between 1 and 2.
>>> If an early map is not release, error message will be prompted to the
>> developers.
>>
>> AFAICS, there is such an error message and I saw it.
>> Refer to check_early_ioremap_leak() at mm/early_ioremap.c
>>
>>> And if you don't follow the above rules, it mean you are trying to lay a mine,
>> waiting for me to step on it.
>>> That's why this change is entirely not acceptable.
>>
>> Ok, I see.
>>
>>> I'm about to send out the cleanup series in 1 week, and will Cc you.
>>> You can rebase your code on top of the cleanup series.
>>
>> Thank you
>> Aleksey Makarov
>>
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>>>>
>>>>>> What should be happening in this series is:
>>>>>> 1. early map SPCR
>>>>>> 2. parse the SPCR table
>>>>>> 3. call add_preferred_console() to add the SPCR console to the console
>>>> table
>>>>>> 4. unmap SPCR
>>>>>>
>>>>>> This trivial and unobtrusive method would already have a 8250 console
>>>>>> running via SPCR. I've already pointed this out in previous reviews.
>>>>>>
>>>>>> Further, the above method *will be required anyway* for the DBG2 table
>> to
>>>>>> start an earlycon, which I've already pointed out in previous reviews.
>>>>>>
>>>>>> Then to enable amba-pl011 console via ACPI, add a console match()
>> method
>>>>>> similar to the 8250 console match() method, univ8250_console_match().
>>>>>>
>>>>>> FWIW, PCI earlycon + console support was already submitted once before
>>>> but
>>>>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>>>>> you would know what to emit for console options in the
>>>>>> add_preferred_console().
>>>>>>
>>>>>>
>>>>>> Regards,
>>>>>> Peter Hurley
>>>>>>
>>>>>>
>>>>>>>>> There is an early bootup requirement in Linux.
>>>>>>>>> Maps acquired during the early stage should be freed by the driver
>> during
>>>>>> the
>>>>>>>> early stage.
>>>>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>>>>
>>>>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
>>>> that
>>>>>>>> that code can be
>>>>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
>>>> of
>>>>>> for
>>>>>>>> example 8250 console)
>>>>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
>>>> that
>>>>>>>> registers a console),
>>>>>>>> We just can not tell if the received table pointer should or sould not be
>>>> freed
>>>>>>>> with early_memunmap()
>>>>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>>>>> acpi_gbl_permanent_mmap,
>>>>>>>> but that's all too low level.
>>>>>>> [Lv Zheng]
>>>>>>> The driver should make sure that:
>>>>>>> Map/unmap is paired during early stage.
>>>>>>> For late stage, it should be another pair of map/unmap.
>>>>>>>
>>>>>>>>
>>>>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>>>>> [Lv Zheng]
>>>>>>> I mean you should free it early.
>>>>>>>
>>>>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>>>>> early_acpi_os_unmap_memory(), that's
>>>>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
>>>> the
>>>>>>>> persistent
>>>>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>>>>> acpi_gbl_permanent_mmap
>>>>>>>> to catch this exact moment.  And also accessing
>>>> acpi_gbl_permanent_mmap
>>>>>> is
>>>>>>>> not good as it probably is
>>>>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>>>>> Or I probably miss what you are suggesting.
>>>>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> I mean, you should:
>>>>>>> During early stage:
>>>>>>> acpi_os_map_memory()
>>>>>>> Parse the table.
>>>>>>> acpi_os_unmap_memory().
>>>>>>>
>>>>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>>>>> available for drivers to map memory.
>>>>>>>>> So by changing __init to __ref here, you probably will hide many such
>>>>>> defects.
>>>>>>>>
>>>>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>>>>> BTW, exactly the same thing is done in the beginning of
>>>>>>>> acpi_os_unmap_memory() and than's ok,
>>>>>>>> that function is __ref.
>>>>>>>>
>>>>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>>>>
>>>>>>>> Could you please tell me where I am wrong?  I still don't understand
>> your
>>>>>> point.
>>>>>>> [Lv Zheng]
>>>>>>> But anyway, the defect should be in ACPI subsystem core.
>>>>>>> The cause should be the API itself - acpi_get_table().
>>>>>>>
>>>>>>> So I agree you can use early_acpi_os_unmap_memory() during the
>> period
>>>> the
>>>>>> root causes are not cleaned up.
>>>>>>> But the bottom line is: the driver need to ensure that
>>>>>> early_acpi_os_unmap_memory() is always invoked.
>>>>>>> As long as you can ensure this, I don't have objections for deploying
>>>>>> early_acpi_os_unmap_memory()  for now.
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Thank you
>>>>>>>> Aleksey Makarov
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Thanks and best regards
>>>>>>>>> -Lv
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Thanks and best regards
>>>>>>>>>> -Lv
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>>>>> ---
>>>>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
>>>> *virt,
>>>>>>>>>>> acpi_size size)
>>>>>>>>>>>  }
>>>>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>>>>
>>>>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
>>>>>> acpi_size
>>>>>>>>>> size)
>>>>>>>>>>> +/*
>>>>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
>>>> anywhere
>>>>>>>>>>> + */
>>>>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
>>>>>> acpi_size
>>>>>>>>>> size)
>>>>>>>>>>>  {
>>>>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>>>>> --
>>>>>>>>>>> 2.7.1
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi"
>> in
>>>>>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
>>>> info.html
>>>>>>>>>> --
>>>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
>> info.html
>>>>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-02-26 10:33                         ` Aleksey Makarov
  0 siblings, 0 replies; 86+ messages in thread
From: Aleksey Makarov @ 2016-02-26 10:33 UTC (permalink / raw)
  To: linux-arm-kernel



On 02/26/2016 09:39 AM, Zheng, Lv wrote:
> Hi, Aleksey
> 
> Though I promised you to have this done in 1 week:
> https://github.com/zetalog/acpica/commit/a234569
> I implemented the idea and tried the cleanup in Linux.
> But unfortunately the cleanup triggered several locking issues inside of ACPICA table API users.
> So it doesn't seem to be so easy and quick to make it upstreamed.
> And I have to continue to test and improve the cleanup.
> 
> I'm sorry for that, hope you can find substitute solutions before the cleanup is upstreamed.

That's fine, I use the approach I described in the last mail, it works.

Thank you
Aleksey Makarov

> 
> Thanks and best regards
> -Lv
> 
>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>> Sent: Monday, February 22, 2016 10:58 PM
>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>> early_acpi_os_unmap_memory()
>>
>> Hi,
>>
>> On 02/22/2016 05:24 AM, Zheng, Lv wrote:
>>> Hi,
>>>
>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>> early_acpi_os_unmap_memory()
>>>>
>>>> Hi Lv,
>>>>
>>>> On 02/19/2016 05:58 AM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Peter Hurley [mailto:peter at hurleysoftware.com]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>>>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>>>> early_acpi_os_unmap_memory()
>>>>>>>>
>>>>>>>> Hi Lv,
>>>>>>>>
>>>>>>>> Thank you for review.
>>>>>>>>
>>>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>>>
>>>>>>>> [..]
>>>>>>>>
>>>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap
>> is
>>>> not
>>>>>>>> set.
>>>>>>>>>>>
>>>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>>>>
>>>>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port
>>>>>> Console
>>>>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>>>>> does.
>>>>>>>>>> [Lv Zheng]
>>>>>>>>>> Why don't you use another API instead of
>>>>>> early_acpi_os_unmap_memory()
>>>>>>>> in
>>>>>>>>>> case you want to unmap things in any cases.
>>>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>>>
>>>>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>>>>
>>>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>>>> acpi_get_table_with_size()
>>>>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer
>> it
>>>>>>>> should be unmapped.
>>>>>>>>
>>>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be
>>>>>> unmapped
>>>>>>>> at all.
>>>>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> This statement is wrong, this should be:
>>>>>>> As long as there is a __reference__ to the mapped table, the pointer
>> should
>>>>>> not be unmapped.
>>>>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>>>>> So your argument is wrong from very first point.
>>>>>>>
>>>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>>>> acpi_gbl_permanent_mmap.
>>>>>>>> If I had used acpi_os_unmap_memory() after
>> acpi_gbl_permanent_mmap
>>>>>> had
>>>>>>>> been set,
>>>>>>>> it would have tried to free that pointer with an oops (actually, I
>> checked
>>>> that
>>>>>>>> and got that oops).
>>>>>>>>
>>>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>>>> early_acpi_os_unmap_memory()
>>>>>>>> match perfectly.
>>>>>>> [Lv Zheng]
>>>>>>> I don't think so.
>>>>>>> For definition block tables, we know for sure there will always be
>>>> references,
>>>>>> until "Unload" opcode is invoked by the AML interpreter.
>>>>>>> But for the data tables, OSPMs should use them in this way:
>>>>>>> 1. map the table
>>>>>>> 2. parse the table and convert it to OS specific structures
>>>>>>> 3. unmap the table
>>>>>>> This helps to shrink virtual memory address space usages.
>>>>>>>
>>>>>>> So from this point of view, all data tables should be unmapped right
>> after
>>>>>> being parsed.
>>>>>>> Why do you need the map to be persistent in the kernel address space?
>>>>>>> You can always map a small table, but what if the table size is very big?
>>>>>>>
>>>>>>>>
>>>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>>>
>>>>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> Just let me ask one more question.
>>>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>>>> You can check drivers/acpi/tbxxx.c.
>>>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>>>
>>>>>>>>> [Lv Zheng]
>>>>>>>>> One more thing is:
>>>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory()
>> instead
>>>> of
>>>>>>>> early_acpi_os_unmap_memory(),
>>>>>>>>> then it implies that your driver does have a defect.
>>>>>>>>
>>>>>>>> I still don't understand what defect, sorry.
>>>>>>> [Lv Zheng]
>>>>>>> If you can't ensure this sequence for using the data tables:
>>>>>>> 1. map the table
>>>>>>> 2. parse the table and convert it to OS specific structure
>>>>>>> 3. unmap the table
>>>>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>>>>
>>>>>> Exactly.
>>>>> [Lv Zheng]
>>>>> So it looks to me:
>>>>> Changing __init to __ref here is entirely not acceptable.
>>>>> This API should stay being invoked during early stage.
>>>>> Otherwise, it may leave us untrackable code that maps tables during early
>>>> stage and leaks maps to the late stage.
>>>>> If Linux contains such kind of code, I'm afraid, it will become impossible to
>>>> introduce acpi_put_table() to clean up the mappings.
>>>>> Because when acpi_put_table() is called during the late stage to free a map
>>>> acquired during the early stage, it then obviously will end up with panic.
>>>>
>>>> Can you please sugggest a common method to access ACPI tables that
>>>> works both before *and* after acpi_gbl_permanent_mmap is set and __init
>>>> code
>>>> is removed?
>>> [Lv Zheng]
>>> Do not change __init for now.
>>>
>>> Currently you should:
>>> 1. before acpi_gbl_permanent_mmap is set:
>>> acpi_get_table_with_size()
>>> parse the table
>>> early_acpi_os_unmap_memory()
>>> Do your driver early stuff here
>>>
>>> 2. after acpi_gbl_permanent_mmap is set:
>>> acpi_get_table()
>>> Parse the table
>>> Do your driver late stuff here
>>> <- note there is no API now being an inverse of acpi_get_table().
>>
>> That's fine.  These are two different methods to access the table.
>> I need one that works in both cases.  Of course, they could be combined,
>> but I am not sure if I can access the acpi_gbl_permanent_mmap variable--it
>> seems to be an implementation detail of ACPI code.
>>
>> Instead I am going to use the 1st method once and cache the result like this:
>>
>>
>> static int __init parse(void)
>> {
>> 	static bool parsed;
>>
>> 	if (!parsed) {
>> 		acpi_get_table_with_size()
>> 		/* parse the table and cache the result */
>> 		early_acpi_os_unmap_memory()
>> 		parse = true;
>> 	}
>> }
>>
>> arch_initcal(parse());
>>
>> int __ref the_handler_where_I_need_the_parse_results(void)
>> {
>> 	parse();
>>
>> 	/* use the data */
>> }
>>
>> I hope you are OK with it.
>>
>>> Besides, I'm about to insert error messages between 1 and 2.
>>> If an early map is not release, error message will be prompted to the
>> developers.
>>
>> AFAICS, there is such an error message and I saw it.
>> Refer to check_early_ioremap_leak() at mm/early_ioremap.c
>>
>>> And if you don't follow the above rules, it mean you are trying to lay a mine,
>> waiting for me to step on it.
>>> That's why this change is entirely not acceptable.
>>
>> Ok, I see.
>>
>>> I'm about to send out the cleanup series in 1 week, and will Cc you.
>>> You can rebase your code on top of the cleanup series.
>>
>> Thank you
>> Aleksey Makarov
>>
>>>
>>> Thanks and best regards
>>> -Lv
>>>
>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>>>>
>>>>>> What should be happening in this series is:
>>>>>> 1. early map SPCR
>>>>>> 2. parse the SPCR table
>>>>>> 3. call add_preferred_console() to add the SPCR console to the console
>>>> table
>>>>>> 4. unmap SPCR
>>>>>>
>>>>>> This trivial and unobtrusive method would already have a 8250 console
>>>>>> running via SPCR. I've already pointed this out in previous reviews.
>>>>>>
>>>>>> Further, the above method *will be required anyway* for the DBG2 table
>> to
>>>>>> start an earlycon, which I've already pointed out in previous reviews.
>>>>>>
>>>>>> Then to enable amba-pl011 console via ACPI, add a console match()
>> method
>>>>>> similar to the 8250 console match() method, univ8250_console_match().
>>>>>>
>>>>>> FWIW, PCI earlycon + console support was already submitted once before
>>>> but
>>>>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>>>>> you would know what to emit for console options in the
>>>>>> add_preferred_console().
>>>>>>
>>>>>>
>>>>>> Regards,
>>>>>> Peter Hurley
>>>>>>
>>>>>>
>>>>>>>>> There is an early bootup requirement in Linux.
>>>>>>>>> Maps acquired during the early stage should be freed by the driver
>> during
>>>>>> the
>>>>>>>> early stage.
>>>>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>>>>
>>>>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is
>>>> that
>>>>>>>> that code can be
>>>>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization
>>>> of
>>>>>> for
>>>>>>>> example 8250 console)
>>>>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module
>>>> that
>>>>>>>> registers a console),
>>>>>>>> We just can not tell if the received table pointer should or sould not be
>>>> freed
>>>>>>>> with early_memunmap()
>>>>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>>>>> acpi_gbl_permanent_mmap,
>>>>>>>> but that's all too low level.
>>>>>>> [Lv Zheng]
>>>>>>> The driver should make sure that:
>>>>>>> Map/unmap is paired during early stage.
>>>>>>> For late stage, it should be another pair of map/unmap.
>>>>>>>
>>>>>>>>
>>>>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>>>>> [Lv Zheng]
>>>>>>> I mean you should free it early.
>>>>>>>
>>>>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>>>>> early_acpi_os_unmap_memory(), that's
>>>>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get
>>>> the
>>>>>>>> persistent
>>>>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>>>>> acpi_gbl_permanent_mmap
>>>>>>>> to catch this exact moment.  And also accessing
>>>> acpi_gbl_permanent_mmap
>>>>>> is
>>>>>>>> not good as it probably is
>>>>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>>>>> Or I probably miss what you are suggesting.
>>>>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> I mean, you should:
>>>>>>> During early stage:
>>>>>>> acpi_os_map_memory()
>>>>>>> Parse the table.
>>>>>>> acpi_os_unmap_memory().
>>>>>>>
>>>>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>>>>> available for drivers to map memory.
>>>>>>>>> So by changing __init to __ref here, you probably will hide many such
>>>>>> defects.
>>>>>>>>
>>>>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>>>>> BTW, exactly the same thing is done in the beginning of
>>>>>>>> acpi_os_unmap_memory() and than's ok,
>>>>>>>> that function is __ref.
>>>>>>>>
>>>>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>>>>
>>>>>>>> Could you please tell me where I am wrong?  I still don't understand
>> your
>>>>>> point.
>>>>>>> [Lv Zheng]
>>>>>>> But anyway, the defect should be in ACPI subsystem core.
>>>>>>> The cause should be the API itself - acpi_get_table().
>>>>>>>
>>>>>>> So I agree you can use early_acpi_os_unmap_memory() during the
>> period
>>>> the
>>>>>> root causes are not cleaned up.
>>>>>>> But the bottom line is: the driver need to ensure that
>>>>>> early_acpi_os_unmap_memory() is always invoked.
>>>>>>> As long as you can ensure this, I don't have objections for deploying
>>>>>> early_acpi_os_unmap_memory()  for now.
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Thank you
>>>>>>>> Aleksey Makarov
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Thanks and best regards
>>>>>>>>> -Lv
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Thanks and best regards
>>>>>>>>>> -Lv
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>>>>> ---
>>>>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void
>>>> *virt,
>>>>>>>>>>> acpi_size size)
>>>>>>>>>>>  }
>>>>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>>>>
>>>>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt,
>>>>>> acpi_size
>>>>>>>>>> size)
>>>>>>>>>>> +/*
>>>>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from
>>>> anywhere
>>>>>>>>>>> + */
>>>>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt,
>>>>>> acpi_size
>>>>>>>>>> size)
>>>>>>>>>>>  {
>>>>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>>>>> --
>>>>>>>>>>> 2.7.1
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi"
>> in
>>>>>>>>>>> the body of a message to majordomo at vger.kernel.org
>>>>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
>>>> info.html
>>>>>>>>>> --
>>>>>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>>>>>>>>>> the body of a message to majordomo at vger.kernel.org
>>>>>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-
>> info.html
>>>>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
  2016-02-22 14:35                   ` Aleksey Makarov
  (?)
@ 2016-03-01 15:24                     ` Peter Hurley
  -1 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-03-01 15:24 UTC (permalink / raw)
  To: Aleksey Makarov, Zheng, Lv, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

On 02/22/2016 06:35 AM, Aleksey Makarov wrote:
> On 02/19/2016 06:25 PM, Peter Hurley wrote:
>> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>>> Hi Peter,
>>>
>>> Thank you for review.
>>>
>>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng] 
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped right after being parsed.
>>>>> Why do you need the map to be persistent in the kernel address space?
>>>>> You can always map a small table, but what if the table size is very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng] 
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>>
>>>> Exactly.
>>>>
>>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the console table
>>>> 4. unmap SPCR
>>>
>>> This does not work.  
>>>
>>> SPCR specifies address of the console, but add_preferred_console() accepts
>>> name of console and its index.  There are no general method to translate address
>>> to name at such an early stage.
>>
>>
>> 	add_preferred_console(uart, 0, "io,0x3f8,115200");
> 
> First argument here should be (char *), the name of the console.
> We can not tell it just from the SPCR ACPI table without
> introducing new made up names and writting which/case that should be 
> supported all the linux lifetime.

As I explained before, you don't use "new made up names". You use the earlycon
name which will "be supported all the linux lifetime".


> I am also not quite shure I can tell the number of tty line (the 0 argument)
> just from the address.

Look at univ8250_console_match() for how that works.


> Did you mean "uart" here?  As far as I can see, this would match the *earlycon*,
> not a regular console, that is not what this patch is about.
> It is about selecting regular (non-boot) consoles.

Obviously.

But again, as I explained already, console matching is already performed
for existing firmware that specifies console by i/o type and address.

Back at your first version of this series, I told you to review
existing users of add_preferred_console() so you would understand how
this works. Please go do so, so that I don't need to keep explaining
how this works over and over again.


> I think translating address to string and then parsing it again is not
> unaceptable, but definitely worse than the approach in my patch, where
> I compare it directly.
> 
>> This will start a console with the 8250 driver. I've already pointed
>> this out to you in an earlier review. This is what existing firmware
>> already does.
>>
>> This is also the method you will use to start an earlycon from the
>> DBG2 table, by additionally calling setup_earlycon().
>>
>>
>>> There is another reason why I prefer to parse SPCR each time a console is registered.
>>> Some consoles can be registered very early in the initialization process and
>>> we have to be sure add_preferred_console() is called before that.
>>
>> However, since you're not adding a preferred console until uart driver
>> loads, there may already be a preferred console selected and running.
>>
>> This leads to weird issues like duplicated output on the serial console
>> when an earlycon is disabled by the dummy VGA/FB console then the
>> serial console starts and reprints the entire boot log on the same
>> terminal the earlycon already printed.
> 
> Yes, misconfigured systems often misbehave.

There's no misconfiguration.


> In this case I would
> question why there is an enabled console (we rely on ACPI to enable it).
> And I probably do not understand the scenario, but 
> - "earlycon is disabled by the dummy VGA/FB console"
> and
> - "earlycon already printed"
> seem a bit contradictory.

bootconsoles are disabled by normal consoles (you should already know this).
earlycon is a bootconsole.
dummy VGA console is a normal console.

So earlycon outputs messages for early boot to the serial console,
then dummy VGA console disables earlycon,
then normal serial console starts, but there's no bootconsole anymore,
so it reprints the boot messages that have accumulated so far, but
to the same serial console that earlycon already printed to.

Part of the reason this happens is because OF doesn't add the serial console
as the preferred console at console_init() but only later at driver probe.

You're repeating the same mistake.


>> Better just to parse both the DBG2 and SPCR tables before or at
>> early param, and add_preferred_consoles then.
> 
> I still don't see why it's better, but I think I explained why it's worse.
> 
>>> Of course, I could just parse it once and cache the results, but
>>> this still requires accessing SPCR before acpi_gbl_permanent_mmap
>>> is set *or* after that.
>>>
>>>> This trivial and unobtrusive method would already have a 8250 console
>>>> running via SPCR. I've already pointed this out in previous reviews.
>>>>
>>>> Further, the above method *will be required anyway* for the DBG2 table to
>>>> start an earlycon, which I've already pointed out in previous reviews.
>>>>
>>>> Then to enable amba-pl011 console via ACPI, add a console match() method
>>>> similar to the 8250 console match() method, univ8250_console_match().
>>>
>>> So are you suggesting a separate method for each possible console?
>>> This is not acceptable.
>>
>> All 1 of them???
> 
> DBG2 specifies these subtypes of serial drivers:
>
> - Fully 16550-compatible
> - 16550 subset compatible with DBGP Revision 1

These two are already done for you in the 8250 driver.
Just call

	add_preferred_console("uart", 0, "io,0x3f8,115200");

with the actual port options specified in the SPCR table.


> - ARM PL011 UART
> - (deprecated) ARM SBSA (2.x only) Generic UART supporting only 32-bit accesses
> - ARM SBSA Generic UART
> - ARM DCC
> - BCM2835

All of these except ARM DCC are variants of the pl011 console.
So write a console match() method for the pl011 console and you're done.

As I wrote, "all 1 of them".


> So it's at least 4 (or 3, I am not sure about ARM DCC) different types and
> the list is open.  We would have to support it.
> 
>> The 8250 driver already does this, so no work for you there.
> 
> "uart" is for boot console, so it is not relevant.  Or did you refer to something else?

Already have repeatedly explained what you need to do to get this
working in the existing framework. Not sure what else you expect here.


>> That leaves you needing to write a trivial match() method for just
>> the amba-pl011 driver.
> 
> Yes, that's probably OK, but in my series drivers should not be modified at all.
> I believe that's better.
> 
>>> Do you suggest making up separate new name (like "uart" for 8250) for each type
>>> of conosole SPCR can specify?
>>
>> These are the documented names of the earlycons, which you'll be using
>> when you add the DGB2 table parsing.
> 
> SPCR is not about earlycons.

Duh.

Again, once you understand how

	add_preferred_console("uart", 0, "io,0x3f8,115200");

starts a *normal console* on whatever tty corresponds to that i/o type
and address, then you'll stop writing statements like this.



>>>> FWIW, PCI earlycon + console support was already submitted once before but
>>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>>> you would know what to emit for console options in the add_preferred_console().
>>>
>>> Please do.  Or just send a link to to that submission.
>>
>> Ok, will dig through and find it.
>>
>>> Do you mean the Leif Lindholm's patches:
>>
>> No.
>>
>>> https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm@linaro.org
>>>
>>> He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
>>> (I just match SPCR against data that struct uart_port already has)
>>> 2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
>>> And that's why his submission is RFC: he had troubles with the order of initialization.
>>>
>>> Thank you
>>> Aleksey Makarov
>>>
>>>> Regards,
>>>> Peter Hurley
>>>>
>>>>
>>>>>>> There is an early bootup requirement in Linux.
>>>>>>> Maps acquired during the early stage should be freed by the driver during the
>>>>>> early stage.
>>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>>
>>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>>>> that code can be
>>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>>>>> example 8250 console)
>>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>>>> registers a console),
>>>>>> We just can not tell if the received table pointer should or sould not be freed
>>>>>> with early_memunmap()
>>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>>> acpi_gbl_permanent_mmap,
>>>>>> but that's all too low level.
>>>>> [Lv Zheng] 
>>>>> The driver should make sure that:
>>>>> Map/unmap is paired during early stage.
>>>>> For late stage, it should be another pair of map/unmap.
>>>>>
>>>>>>
>>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>>> [Lv Zheng] 
>>>>> I mean you should free it early.
>>>>>
>>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>>> early_acpi_os_unmap_memory(), that's
>>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>>>> persistent
>>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>>> acpi_gbl_permanent_mmap
>>>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>>>>> not good as it probably is
>>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>>> Or I probably miss what you are suggesting.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> I mean, you should:
>>>>> During early stage:
>>>>> acpi_os_map_memory()
>>>>> Parse the table.
>>>>> acpi_os_unmap_memory().
>>>>>
>>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>>> available for drivers to map memory.
>>>>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>>>>
>>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>>> BTW, exactly the same thing is done in the beginning of
>>>>>> acpi_os_unmap_memory() and than's ok,
>>>>>> that function is __ref.
>>>>>>
>>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>>
>>>>>> Could you please tell me where I am wrong?  I still don't understand your point.
>>>>> [Lv Zheng] 
>>>>> But anyway, the defect should be in ACPI subsystem core.
>>>>> The cause should be the API itself - acpi_get_table().
>>>>>
>>>>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>>>>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>>>>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thank you
>>>>>> Aleksey Makarov
>>>>>>
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Thanks and best regards
>>>>>>>> -Lv
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>>> ---
>>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>>>> acpi_size size)
>>>>>>>>>  }
>>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>>
>>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>>> size)
>>>>>>>>> +/*
>>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>> + */
>>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>>> size)
>>>>>>>>>  {
>>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>>> --
>>>>>>>>> 2.7.1
>>
>>


^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-03-01 15:24                     ` Peter Hurley
  0 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-03-01 15:24 UTC (permalink / raw)
  To: Aleksey Makarov, Zheng, Lv, linux-acpi
  Cc: linux-serial, linux-kernel, linux-arm-kernel, Russell King,
	Greg Kroah-Hartman, Rafael J . Wysocki, Leif Lindholm,
	Graeme Gregory, Al Stone, Christopher Covington, Len Brown

On 02/22/2016 06:35 AM, Aleksey Makarov wrote:
> On 02/19/2016 06:25 PM, Peter Hurley wrote:
>> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>>> Hi Peter,
>>>
>>> Thank you for review.
>>>
>>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov@linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng] 
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped right after being parsed.
>>>>> Why do you need the map to be persistent in the kernel address space?
>>>>> You can always map a small table, but what if the table size is very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng] 
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>>
>>>> Exactly.
>>>>
>>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the console table
>>>> 4. unmap SPCR
>>>
>>> This does not work.  
>>>
>>> SPCR specifies address of the console, but add_preferred_console() accepts
>>> name of console and its index.  There are no general method to translate address
>>> to name at such an early stage.
>>
>>
>> 	add_preferred_console(uart, 0, "io,0x3f8,115200");
> 
> First argument here should be (char *), the name of the console.
> We can not tell it just from the SPCR ACPI table without
> introducing new made up names and writting which/case that should be 
> supported all the linux lifetime.

As I explained before, you don't use "new made up names". You use the earlycon
name which will "be supported all the linux lifetime".


> I am also not quite shure I can tell the number of tty line (the 0 argument)
> just from the address.

Look at univ8250_console_match() for how that works.


> Did you mean "uart" here?  As far as I can see, this would match the *earlycon*,
> not a regular console, that is not what this patch is about.
> It is about selecting regular (non-boot) consoles.

Obviously.

But again, as I explained already, console matching is already performed
for existing firmware that specifies console by i/o type and address.

Back at your first version of this series, I told you to review
existing users of add_preferred_console() so you would understand how
this works. Please go do so, so that I don't need to keep explaining
how this works over and over again.


> I think translating address to string and then parsing it again is not
> unaceptable, but definitely worse than the approach in my patch, where
> I compare it directly.
> 
>> This will start a console with the 8250 driver. I've already pointed
>> this out to you in an earlier review. This is what existing firmware
>> already does.
>>
>> This is also the method you will use to start an earlycon from the
>> DBG2 table, by additionally calling setup_earlycon().
>>
>>
>>> There is another reason why I prefer to parse SPCR each time a console is registered.
>>> Some consoles can be registered very early in the initialization process and
>>> we have to be sure add_preferred_console() is called before that.
>>
>> However, since you're not adding a preferred console until uart driver
>> loads, there may already be a preferred console selected and running.
>>
>> This leads to weird issues like duplicated output on the serial console
>> when an earlycon is disabled by the dummy VGA/FB console then the
>> serial console starts and reprints the entire boot log on the same
>> terminal the earlycon already printed.
> 
> Yes, misconfigured systems often misbehave.

There's no misconfiguration.


> In this case I would
> question why there is an enabled console (we rely on ACPI to enable it).
> And I probably do not understand the scenario, but 
> - "earlycon is disabled by the dummy VGA/FB console"
> and
> - "earlycon already printed"
> seem a bit contradictory.

bootconsoles are disabled by normal consoles (you should already know this).
earlycon is a bootconsole.
dummy VGA console is a normal console.

So earlycon outputs messages for early boot to the serial console,
then dummy VGA console disables earlycon,
then normal serial console starts, but there's no bootconsole anymore,
so it reprints the boot messages that have accumulated so far, but
to the same serial console that earlycon already printed to.

Part of the reason this happens is because OF doesn't add the serial console
as the preferred console at console_init() but only later at driver probe.

You're repeating the same mistake.


>> Better just to parse both the DBG2 and SPCR tables before or at
>> early param, and add_preferred_consoles then.
> 
> I still don't see why it's better, but I think I explained why it's worse.
> 
>>> Of course, I could just parse it once and cache the results, but
>>> this still requires accessing SPCR before acpi_gbl_permanent_mmap
>>> is set *or* after that.
>>>
>>>> This trivial and unobtrusive method would already have a 8250 console
>>>> running via SPCR. I've already pointed this out in previous reviews.
>>>>
>>>> Further, the above method *will be required anyway* for the DBG2 table to
>>>> start an earlycon, which I've already pointed out in previous reviews.
>>>>
>>>> Then to enable amba-pl011 console via ACPI, add a console match() method
>>>> similar to the 8250 console match() method, univ8250_console_match().
>>>
>>> So are you suggesting a separate method for each possible console?
>>> This is not acceptable.
>>
>> All 1 of them???
> 
> DBG2 specifies these subtypes of serial drivers:
>
> - Fully 16550-compatible
> - 16550 subset compatible with DBGP Revision 1

These two are already done for you in the 8250 driver.
Just call

	add_preferred_console("uart", 0, "io,0x3f8,115200");

with the actual port options specified in the SPCR table.


> - ARM PL011 UART
> - (deprecated) ARM SBSA (2.x only) Generic UART supporting only 32-bit accesses
> - ARM SBSA Generic UART
> - ARM DCC
> - BCM2835

All of these except ARM DCC are variants of the pl011 console.
So write a console match() method for the pl011 console and you're done.

As I wrote, "all 1 of them".


> So it's at least 4 (or 3, I am not sure about ARM DCC) different types and
> the list is open.  We would have to support it.
> 
>> The 8250 driver already does this, so no work for you there.
> 
> "uart" is for boot console, so it is not relevant.  Or did you refer to something else?

Already have repeatedly explained what you need to do to get this
working in the existing framework. Not sure what else you expect here.


>> That leaves you needing to write a trivial match() method for just
>> the amba-pl011 driver.
> 
> Yes, that's probably OK, but in my series drivers should not be modified at all.
> I believe that's better.
> 
>>> Do you suggest making up separate new name (like "uart" for 8250) for each type
>>> of conosole SPCR can specify?
>>
>> These are the documented names of the earlycons, which you'll be using
>> when you add the DGB2 table parsing.
> 
> SPCR is not about earlycons.

Duh.

Again, once you understand how

	add_preferred_console("uart", 0, "io,0x3f8,115200");

starts a *normal console* on whatever tty corresponds to that i/o type
and address, then you'll stop writing statements like this.



>>>> FWIW, PCI earlycon + console support was already submitted once before but
>>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>>> you would know what to emit for console options in the add_preferred_console().
>>>
>>> Please do.  Or just send a link to to that submission.
>>
>> Ok, will dig through and find it.
>>
>>> Do you mean the Leif Lindholm's patches:
>>
>> No.
>>
>>> https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm@linaro.org
>>>
>>> He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
>>> (I just match SPCR against data that struct uart_port already has)
>>> 2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
>>> And that's why his submission is RFC: he had troubles with the order of initialization.
>>>
>>> Thank you
>>> Aleksey Makarov
>>>
>>>> Regards,
>>>> Peter Hurley
>>>>
>>>>
>>>>>>> There is an early bootup requirement in Linux.
>>>>>>> Maps acquired during the early stage should be freed by the driver during the
>>>>>> early stage.
>>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>>
>>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>>>> that code can be
>>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>>>>> example 8250 console)
>>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>>>> registers a console),
>>>>>> We just can not tell if the received table pointer should or sould not be freed
>>>>>> with early_memunmap()
>>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>>> acpi_gbl_permanent_mmap,
>>>>>> but that's all too low level.
>>>>> [Lv Zheng] 
>>>>> The driver should make sure that:
>>>>> Map/unmap is paired during early stage.
>>>>> For late stage, it should be another pair of map/unmap.
>>>>>
>>>>>>
>>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>>> [Lv Zheng] 
>>>>> I mean you should free it early.
>>>>>
>>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>>> early_acpi_os_unmap_memory(), that's
>>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>>>> persistent
>>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>>> acpi_gbl_permanent_mmap
>>>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>>>>> not good as it probably is
>>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>>> Or I probably miss what you are suggesting.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> I mean, you should:
>>>>> During early stage:
>>>>> acpi_os_map_memory()
>>>>> Parse the table.
>>>>> acpi_os_unmap_memory().
>>>>>
>>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>>> available for drivers to map memory.
>>>>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>>>>
>>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>>> BTW, exactly the same thing is done in the beginning of
>>>>>> acpi_os_unmap_memory() and than's ok,
>>>>>> that function is __ref.
>>>>>>
>>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>>
>>>>>> Could you please tell me where I am wrong?  I still don't understand your point.
>>>>> [Lv Zheng] 
>>>>> But anyway, the defect should be in ACPI subsystem core.
>>>>> The cause should be the API itself - acpi_get_table().
>>>>>
>>>>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>>>>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>>>>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thank you
>>>>>> Aleksey Makarov
>>>>>>
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Thanks and best regards
>>>>>>>> -Lv
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>>> ---
>>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>>>> acpi_size size)
>>>>>>>>>  }
>>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>>
>>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>>> size)
>>>>>>>>> +/*
>>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>> + */
>>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>>> size)
>>>>>>>>>  {
>>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>>> --
>>>>>>>>> 2.7.1
>>
>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory()
@ 2016-03-01 15:24                     ` Peter Hurley
  0 siblings, 0 replies; 86+ messages in thread
From: Peter Hurley @ 2016-03-01 15:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/22/2016 06:35 AM, Aleksey Makarov wrote:
> On 02/19/2016 06:25 PM, Peter Hurley wrote:
>> On 02/19/2016 02:42 AM, Aleksey Makarov wrote:
>>> Hi Peter,
>>>
>>> Thank you for review.
>>>
>>> On 02/19/2016 01:03 AM, Peter Hurley wrote:
>>>> On 02/17/2016 07:36 PM, Zheng, Lv wrote:
>>>>> Hi,
>>>>>
>>>>>> From: Aleksey Makarov [mailto:aleksey.makarov at linaro.org]
>>>>>> Subject: Re: [PATCH v3 1/5] ACPI: change __init to __ref for
>>>>>> early_acpi_os_unmap_memory()
>>>>>>
>>>>>> Hi Lv,
>>>>>>
>>>>>> Thank you for review.
>>>>>>
>>>>>> On 02/17/2016 05:51 AM, Zheng, Lv wrote:
>>>>>>
>>>>>> [..]
>>>>>>
>>>>>>>>> early_acpi_os_unmap_memory() is marked as __init because it calls
>>>>>>>>> __acpi_unmap_table(), but only when acpi_gbl_permanent_mmap is not
>>>>>> set.
>>>>>>>>>
>>>>>>>>> acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>>
>>>>>>>>> We need this function to be non-__init because we need access to
>>>>>>>>> some tables at unpredictable time--it may be before or after
>>>>>>>>> acpi_gbl_permanent_mmap is set.  For example, SPCR (Serial Port Console
>>>>>>>>> Redirection) table is needed each time a new console is registered.
>>>>>>>>> It can be quite early (console_initcall) or when a module is inserted.
>>>>>>>>> When this table accessed before acpi_gbl_permanent_mmap is set,
>>>>>>>>> the pointer should be unmapped.  This is exactly what this function
>>>>>>>>> does.
>>>>>>>> [Lv Zheng]
>>>>>>>> Why don't you use another API instead of early_acpi_os_unmap_memory()
>>>>>> in
>>>>>>>> case you want to unmap things in any cases.
>>>>>>>> acpi_os_unmap_memory() should be the one to match this purpose.
>>>>>>>> It checks acpi_gbl_ppermanent_mmap in acpi_os_unmap_iomem().
>>>>>>
>>>>>> As far as I understand, there exist two steps in ACPI initialization:
>>>>>>
>>>>>> 1. Before acpi_gbl_permanent_mmap is set, tables received with
>>>>>> acpi_get_table_with_size()
>>>>>>    are mapped by early_memremap().  If a subsystem gets such a pointer it
>>>>>> should be unmapped.
>>>>>>
>>>>>> 2  After acpi_gbl_permanent_mmap is set this pointer should not be unmapped
>>>>>> at all.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> This statement is wrong, this should be:
>>>>> As long as there is a __reference__ to the mapped table, the pointer should not be unmapped.
>>>>> In fact, we have a series to introduce acpi_put_table() to achieve this.
>>>>> So your argument is wrong from very first point.
>>>>>
>>>>>> That exactly what early_acpi_os_unmap_memory() does--it checks
>>>>>> acpi_gbl_permanent_mmap.
>>>>>> If I had used acpi_os_unmap_memory() after acpi_gbl_permanent_mmap had
>>>>>> been set,
>>>>>> it would have tried to free that pointer with an oops (actually, I checked that
>>>>>> and got that oops).
>>>>>>
>>>>>> So using acpi_os_unmap_memory() is not an option here, but
>>>>>> early_acpi_os_unmap_memory()
>>>>>> match perfectly.
>>>>> [Lv Zheng] 
>>>>> I don't think so.
>>>>> For definition block tables, we know for sure there will always be references, until "Unload" opcode is invoked by the AML interpreter.
>>>>> But for the data tables, OSPMs should use them in this way:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structures
>>>>> 3. unmap the table
>>>>> This helps to shrink virtual memory address space usages.
>>>>>
>>>>> So from this point of view, all data tables should be unmapped right after being parsed.
>>>>> Why do you need the map to be persistent in the kernel address space?
>>>>> You can always map a small table, but what if the table size is very big?
>>>>>
>>>>>>
>>>>>>>> And in fact early_acpi_os_unmap_memory() should be removed.
>>>>>>
>>>>>> I don't think so -- I have explained why.  It does different thing.
>>>>>> Probably it (and/or other functions in that api) should be renamed.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> Just let me ask one more question.
>>>>> eary_acpi_os_unmap_memory() is not used inside of ACPICA.
>>>>> How ACPICA can work with just acpi_os_unmap_memory()?
>>>>> You can check drivers/acpi/tbxxx.c.
>>>>> Especially: acpi_tb_release_temp_table() and the code invoking it.
>>>>>
>>>>>>> [Lv Zheng]
>>>>>>> One more thing is:
>>>>>>> If you can't switch your driver to use acpi_os_unmap_memory() instead of
>>>>>> early_acpi_os_unmap_memory(),
>>>>>>> then it implies that your driver does have a defect.
>>>>>>
>>>>>> I still don't understand what defect, sorry.
>>>>> [Lv Zheng] 
>>>>> If you can't ensure this sequence for using the data tables:
>>>>> 1. map the table
>>>>> 2. parse the table and convert it to OS specific structure
>>>>> 3. unmap the table
>>>>> It implies there is a bug in the driver or a bug in the ACPI subsystem core.
>>>>
>>>> Exactly.
>>>>
>>>> The central problem here is the way Aleksey is trying to hookup a console.
>>>>
>>>> What should be happening in this series is:
>>>> 1. early map SPCR
>>>> 2. parse the SPCR table
>>>> 3. call add_preferred_console() to add the SPCR console to the console table
>>>> 4. unmap SPCR
>>>
>>> This does not work.  
>>>
>>> SPCR specifies address of the console, but add_preferred_console() accepts
>>> name of console and its index.  There are no general method to translate address
>>> to name at such an early stage.
>>
>>
>> 	add_preferred_console(uart, 0, "io,0x3f8,115200");
> 
> First argument here should be (char *), the name of the console.
> We can not tell it just from the SPCR ACPI table without
> introducing new made up names and writting which/case that should be 
> supported all the linux lifetime.

As I explained before, you don't use "new made up names". You use the earlycon
name which will "be supported all the linux lifetime".


> I am also not quite shure I can tell the number of tty line (the 0 argument)
> just from the address.

Look at univ8250_console_match() for how that works.


> Did you mean "uart" here?  As far as I can see, this would match the *earlycon*,
> not a regular console, that is not what this patch is about.
> It is about selecting regular (non-boot) consoles.

Obviously.

But again, as I explained already, console matching is already performed
for existing firmware that specifies console by i/o type and address.

Back at your first version of this series, I told you to review
existing users of add_preferred_console() so you would understand how
this works. Please go do so, so that I don't need to keep explaining
how this works over and over again.


> I think translating address to string and then parsing it again is not
> unaceptable, but definitely worse than the approach in my patch, where
> I compare it directly.
> 
>> This will start a console with the 8250 driver. I've already pointed
>> this out to you in an earlier review. This is what existing firmware
>> already does.
>>
>> This is also the method you will use to start an earlycon from the
>> DBG2 table, by additionally calling setup_earlycon().
>>
>>
>>> There is another reason why I prefer to parse SPCR each time a console is registered.
>>> Some consoles can be registered very early in the initialization process and
>>> we have to be sure add_preferred_console() is called before that.
>>
>> However, since you're not adding a preferred console until uart driver
>> loads, there may already be a preferred console selected and running.
>>
>> This leads to weird issues like duplicated output on the serial console
>> when an earlycon is disabled by the dummy VGA/FB console then the
>> serial console starts and reprints the entire boot log on the same
>> terminal the earlycon already printed.
> 
> Yes, misconfigured systems often misbehave.

There's no misconfiguration.


> In this case I would
> question why there is an enabled console (we rely on ACPI to enable it).
> And I probably do not understand the scenario, but 
> - "earlycon is disabled by the dummy VGA/FB console"
> and
> - "earlycon already printed"
> seem a bit contradictory.

bootconsoles are disabled by normal consoles (you should already know this).
earlycon is a bootconsole.
dummy VGA console is a normal console.

So earlycon outputs messages for early boot to the serial console,
then dummy VGA console disables earlycon,
then normal serial console starts, but there's no bootconsole anymore,
so it reprints the boot messages that have accumulated so far, but
to the same serial console that earlycon already printed to.

Part of the reason this happens is because OF doesn't add the serial console
as the preferred console at console_init() but only later at driver probe.

You're repeating the same mistake.


>> Better just to parse both the DBG2 and SPCR tables before or at
>> early param, and add_preferred_consoles then.
> 
> I still don't see why it's better, but I think I explained why it's worse.
> 
>>> Of course, I could just parse it once and cache the results, but
>>> this still requires accessing SPCR before acpi_gbl_permanent_mmap
>>> is set *or* after that.
>>>
>>>> This trivial and unobtrusive method would already have a 8250 console
>>>> running via SPCR. I've already pointed this out in previous reviews.
>>>>
>>>> Further, the above method *will be required anyway* for the DBG2 table to
>>>> start an earlycon, which I've already pointed out in previous reviews.
>>>>
>>>> Then to enable amba-pl011 console via ACPI, add a console match() method
>>>> similar to the 8250 console match() method, univ8250_console_match().
>>>
>>> So are you suggesting a separate method for each possible console?
>>> This is not acceptable.
>>
>> All 1 of them???
> 
> DBG2 specifies these subtypes of serial drivers:
>
> - Fully 16550-compatible
> - 16550 subset compatible with DBGP Revision 1

These two are already done for you in the 8250 driver.
Just call

	add_preferred_console("uart", 0, "io,0x3f8,115200");

with the actual port options specified in the SPCR table.


> - ARM PL011 UART
> - (deprecated) ARM SBSA (2.x only) Generic UART supporting only 32-bit accesses
> - ARM SBSA Generic UART
> - ARM DCC
> - BCM2835

All of these except ARM DCC are variants of the pl011 console.
So write a console match() method for the pl011 console and you're done.

As I wrote, "all 1 of them".


> So it's at least 4 (or 3, I am not sure about ARM DCC) different types and
> the list is open.  We would have to support it.
> 
>> The 8250 driver already does this, so no work for you there.
> 
> "uart" is for boot console, so it is not relevant.  Or did you refer to something else?

Already have repeatedly explained what you need to do to get this
working in the existing framework. Not sure what else you expect here.


>> That leaves you needing to write a trivial match() method for just
>> the amba-pl011 driver.
> 
> Yes, that's probably OK, but in my series drivers should not be modified at all.
> I believe that's better.
> 
>>> Do you suggest making up separate new name (like "uart" for 8250) for each type
>>> of conosole SPCR can specify?
>>
>> These are the documented names of the earlycons, which you'll be using
>> when you add the DGB2 table parsing.
> 
> SPCR is not about earlycons.

Duh.

Again, once you understand how

	add_preferred_console("uart", 0, "io,0x3f8,115200");

starts a *normal console* on whatever tty corresponds to that i/o type
and address, then you'll stop writing statements like this.



>>>> FWIW, PCI earlycon + console support was already submitted once before but
>>>> never picked up by GregKH. I think I'll just grab that and re-submit so
>>>> you would know what to emit for console options in the add_preferred_console().
>>>
>>> Please do.  Or just send a link to to that submission.
>>
>> Ok, will dig through and find it.
>>
>>> Do you mean the Leif Lindholm's patches:
>>
>> No.
>>
>>> https://lkml.kernel.org/g/1441716217-23786-1-git-send-email-leif.lindholm at linaro.org
>>>
>>> He did same thing as I did in my v3 exept 1) he parses ACPI tree to match device
>>> (I just match SPCR against data that struct uart_port already has)
>>> 2) As you are suggesting, he parses SPCR once at a predefined point in initialization.
>>> And that's why his submission is RFC: he had troubles with the order of initialization.
>>>
>>> Thank you
>>> Aleksey Makarov
>>>
>>>> Regards,
>>>> Peter Hurley
>>>>
>>>>
>>>>>>> There is an early bootup requirement in Linux.
>>>>>>> Maps acquired during the early stage should be freed by the driver during the
>>>>>> early stage.
>>>>>>> And the driver should re-acquire the memory map after booting.
>>>>>>
>>>>>> Exactly.  That's why I use early_acpi_os_unmap_memory().  The point is that
>>>>>> that code can be
>>>>>> called *before* acpi_gbl_permanent_mmap is set (at early initialization of for
>>>>>> example 8250 console)
>>>>>> or *after* acpi_gbl_permanent_mmap is set (at insertion of a module that
>>>>>> registers a console),
>>>>>> We just can not tell if the received table pointer should or sould not be freed
>>>>>> with early_memunmap()
>>>>>> (actually __acpi_unmap_table() or whatever) without checking
>>>>>> acpi_gbl_permanent_mmap,
>>>>>> but that's all too low level.
>>>>> [Lv Zheng] 
>>>>> The driver should make sure that:
>>>>> Map/unmap is paired during early stage.
>>>>> For late stage, it should be another pair of map/unmap.
>>>>>
>>>>>>
>>>>>> Another option, as you describe, is to get this pointer early, don't free it
>>>>> [Lv Zheng] 
>>>>> I mean you should free it early.
>>>>>
>>>>>> untill acpi_gbl_permanent_mmap is set, then free it (with
>>>>>> early_acpi_os_unmap_memory(), that's
>>>>>> ok because acpi_gbl_permanent_mmap is set in an init code), then get the
>>>>>> persistent
>>>>>> pointer to the table.  The problem with it is that we can not just watch
>>>>>> acpi_gbl_permanent_mmap
>>>>>> to catch this exact moment.  And also accessing acpi_gbl_permanent_mmap is
>>>>>> not good as it probably is
>>>>>> an implementation detail (i. e. too lowlevel) of the ACPI code.
>>>>>> Or I probably miss what you are suggesting.
>>>>>>
>>>>> [Lv Zheng] 
>>>>> I mean, you should:
>>>>> During early stage:
>>>>> acpi_os_map_memory()
>>>>> Parse the table.
>>>>> acpi_os_unmap_memory().
>>>>>
>>>>>>> This is because, during early bootup stage, there are only limited slots
>>>>>> available for drivers to map memory.
>>>>>>> So by changing __init to __ref here, you probably will hide many such defects.
>>>>>>
>>>>>> What defects?  This funcions checks acpi_gbl_permanent_mmap.
>>>>>> BTW, exactly the same thing is done in the beginning of
>>>>>> acpi_os_unmap_memory() and than's ok,
>>>>>> that function is __ref.
>>>>>>
>>>>>>> And solving issues in this way doesn't seem to be an improvement.
>>>>>>
>>>>>> Could you please tell me where I am wrong?  I still don't understand your point.
>>>>> [Lv Zheng] 
>>>>> But anyway, the defect should be in ACPI subsystem core.
>>>>> The cause should be the API itself - acpi_get_table().
>>>>>
>>>>> So I agree you can use early_acpi_os_unmap_memory() during the period the root causes are not cleaned up.
>>>>> But the bottom line is: the driver need to ensure that early_acpi_os_unmap_memory() is always invoked.
>>>>> As long as you can ensure this, I don't have objections for deploying early_acpi_os_unmap_memory()  for now.
>>>>>
>>>>> Thanks and best regards
>>>>> -Lv
>>>>>
>>>>>>
>>>>>> Thank you
>>>>>> Aleksey Makarov
>>>>>>
>>>>>>>
>>>>>>> Thanks and best regards
>>>>>>> -Lv
>>>>>>>
>>>>>>>>
>>>>>>>> Thanks and best regards
>>>>>>>> -Lv
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
>>>>>>>>> ---
>>>>>>>>>  drivers/acpi/osl.c | 6 +++++-
>>>>>>>>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>>>>
>>>>>>>>> diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
>>>>>>>>> index 67da6fb..8a552cd 100644
>>>>>>>>> --- a/drivers/acpi/osl.c
>>>>>>>>> +++ b/drivers/acpi/osl.c
>>>>>>>>> @@ -497,7 +497,11 @@ void __ref acpi_os_unmap_memory(void *virt,
>>>>>>>>> acpi_size size)
>>>>>>>>>  }
>>>>>>>>>  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
>>>>>>>>>
>>>>>>>>> -void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>>> size)
>>>>>>>>> +/*
>>>>>>>>> + * acpi_gbl_permanent_mmap is set in __init acpi_early_init()
>>>>>>>>> + * so it is safe to call early_acpi_os_unmap_memory() from anywhere
>>>>>>>>> + */
>>>>>>>>> +void __ref early_acpi_os_unmap_memory(void __iomem *virt, acpi_size
>>>>>>>> size)
>>>>>>>>>  {
>>>>>>>>>  	if (!acpi_gbl_permanent_mmap)
>>>>>>>>>  		__acpi_unmap_table(virt, size);
>>>>>>>>> --
>>>>>>>>> 2.7.1
>>
>>

^ permalink raw reply	[flat|nested] 86+ messages in thread

end of thread, other threads:[~2016-03-01 15:24 UTC | newest]

Thread overview: 86+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-15 18:05 [PATCH v3 0/5] ACPI: parse the SPCR table Aleksey Makarov
2016-02-15 18:05 ` Aleksey Makarov
2016-02-15 18:05 ` [PATCH v3 1/5] ACPI: change __init to __ref for early_acpi_os_unmap_memory() Aleksey Makarov
2016-02-15 18:05   ` Aleksey Makarov
2016-02-17  2:44   ` Zheng, Lv
2016-02-17  2:44     ` Zheng, Lv
2016-02-17  2:44     ` Zheng, Lv
2016-02-17  2:51     ` Zheng, Lv
2016-02-17  2:51       ` Zheng, Lv
2016-02-17  2:51       ` Zheng, Lv
2016-02-17 13:08       ` Aleksey Makarov
2016-02-17 13:08         ` Aleksey Makarov
2016-02-17 13:08         ` Aleksey Makarov
2016-02-18  3:36         ` Zheng, Lv
2016-02-18  3:36           ` Zheng, Lv
2016-02-18  3:36           ` Zheng, Lv
2016-02-18 22:03           ` Peter Hurley
2016-02-18 22:03             ` Peter Hurley
2016-02-18 22:03             ` Peter Hurley
2016-02-19  2:58             ` Zheng, Lv
2016-02-19  2:58               ` Zheng, Lv
2016-02-19  2:58               ` Zheng, Lv
2016-02-19 11:02               ` Aleksey Makarov
2016-02-19 11:02                 ` Aleksey Makarov
2016-02-19 11:02                 ` Aleksey Makarov
2016-02-22  2:24                 ` Zheng, Lv
2016-02-22  2:24                   ` Zheng, Lv
2016-02-22  2:24                   ` Zheng, Lv
2016-02-22 14:58                   ` Aleksey Makarov
2016-02-22 14:58                     ` Aleksey Makarov
2016-02-22 14:58                     ` Aleksey Makarov
2016-02-23  0:19                     ` Zheng, Lv
2016-02-23  0:19                       ` Zheng, Lv
2016-02-23  0:19                       ` Zheng, Lv
2016-02-26  6:39                     ` Zheng, Lv
2016-02-26  6:39                       ` Zheng, Lv
2016-02-26  6:39                       ` Zheng, Lv
2016-02-26 10:33                       ` Aleksey Makarov
2016-02-26 10:33                         ` Aleksey Makarov
2016-02-26 10:33                         ` Aleksey Makarov
2016-02-19 10:42             ` Aleksey Makarov
2016-02-19 10:42               ` Aleksey Makarov
2016-02-19 10:42               ` Aleksey Makarov
2016-02-19 15:25               ` Peter Hurley
2016-02-19 15:25                 ` Peter Hurley
2016-02-19 15:25                 ` Peter Hurley
2016-02-19 17:20                 ` Christopher Covington
2016-02-19 17:20                   ` Christopher Covington
2016-02-19 17:20                   ` Christopher Covington
2016-02-22  5:37                   ` Peter Hurley
2016-02-22  5:37                     ` Peter Hurley
2016-02-22  5:37                     ` Peter Hurley
2016-02-22 14:43                   ` Aleksey Makarov
2016-02-22 14:43                     ` Aleksey Makarov
2016-02-22 14:43                     ` Aleksey Makarov
2016-02-22 14:35                 ` Aleksey Makarov
2016-02-22 14:35                   ` Aleksey Makarov
2016-02-22 14:35                   ` Aleksey Makarov
2016-03-01 15:24                   ` Peter Hurley
2016-03-01 15:24                     ` Peter Hurley
2016-03-01 15:24                     ` Peter Hurley
2016-02-15 18:05 ` [PATCH v3 2/5] ACPI: parse SPCR and enable matching console Aleksey Makarov
2016-02-15 18:05   ` Aleksey Makarov
2016-02-18 22:19   ` Peter Hurley
2016-02-18 22:19     ` Peter Hurley
2016-02-19 10:47     ` Aleksey Makarov
2016-02-19 10:47       ` Aleksey Makarov
2016-02-19 16:13       ` Peter Hurley
2016-02-19 16:13         ` Peter Hurley
2016-02-21  9:42   ` Yury Norov
2016-02-21  9:42     ` Yury Norov
2016-02-21  9:42     ` Yury Norov
2016-02-22 15:03     ` Aleksey Makarov
2016-02-22 15:03       ` Aleksey Makarov
2016-02-15 18:05 ` [PATCH v3 3/5] ACPI: enable ACPI_SPCR_TABLE on ARM64 Aleksey Makarov
2016-02-15 18:05   ` Aleksey Makarov
2016-02-15 18:05 ` [PATCH v3 4/5] ACPI: add definition of DBG2 subtypes Aleksey Makarov
2016-02-15 18:05   ` Aleksey Makarov
2016-02-15 18:05 ` [PATCH v3 5/5] serial: pl011: use SPCR to setup 32-bit access Aleksey Makarov
2016-02-15 18:05   ` Aleksey Makarov
2016-02-16 19:11 ` [PATCH v3 0/5] ACPI: parse the SPCR table Mark Salter
2016-02-16 19:11   ` Mark Salter
2016-02-17  2:36 ` Christopher Covington
2016-02-17  2:36   ` Christopher Covington
2016-02-18 21:15 ` Jeremy Linton
2016-02-18 21:15   ` Jeremy Linton

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.