All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/7] kernel: Add support for restart notifier call chain
@ 2014-07-06 23:38 ` Guenter Roeck
  0 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-watchdog, linux-arm-kernel
  Cc: Wim Van Sebroeck, Catalin Marinas, Maxime Ripard, Will Deacon,
	Arnd Bergmann, Heiko Stuebner, Russell King, Jonas Jensen,
	Randy Dunlap, Andrew Morton, Steven Rostedt, Ingo Molnar,
	Dmitry Eremin-Solenikov, David Woodhouse, linux-doc,
	linux-kernel, Guenter Roeck

Various drivers implement architecture and/or device specific means
to restart (reset) the system. Various mechanisms have been implemented
to support those schemes. The best known mechanism is arm_pm_restart,
which is a function pointer to be set either from platform specific code
or from drivers. Another mechanism is to use hardware watchdogs to issue
a reset; this mechanism is used if there is no other method available
to reset a board or system. Two examples are alim7101_wdt, which currently
uses the reboot notifier to trigger a reset, and moxart_wdt, which registers
the arm_pm_restart function.

The existing mechanisms have a number of drawbacks. Typically only one scheme
to restart the system is supported (at least if arm_pm_restart is used).
At least in theory there can be mutliple means to restart the system, some of
which may be less desirable (for example one mechanism may only reset the CPU,
while another may reset the entire system). Using arm_pm_restart can also be
racy if the function pointer is set from a driver, as the driver may be in
the process of being unloaded when arm_pm_restart is called.
Using the reboot notifier is always racy, as it is unknown if and when
other functions using the reboot notifier have completed execution
by the time the watchdog fires.

To solve the problem, introduce a system restart notifier. This notifier
is expected to be called from the architecture specific machine_restart()
function. Drivers providing system restart functionality (such as the watchdog
drivers mentioned above) are expected to register with this notifier.

Patch 1 of this series implements the notifier function. Patches 2 and 3
implement calling the notifier chain from arm and arm64 restart code.

Patch 4 modifies the restart-poweroff driver to no longer call arm_pm_restart
directly but machine_restart. This is done to avoid calling arm_pm_restart
from more than one place. The change makes the driver architecture independent,
so it would be possible to drop the arm dependency from its Kconfig entry.

Patch 5 and 6 convert existing restart handlers in the watchdog subsystem
to use the restart notifier. Patch 7 unexports arm_pm_restart to ensure
that no one gets the idea to implement a restart handler as module.

---
v2: Add patch 4
    Only call blocking notifier call chain if arm_pm_restart was not set.

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

* [RFC PATCH v2 0/7] kernel: Add support for restart notifier call chain
@ 2014-07-06 23:38 ` Guenter Roeck
  0 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-arm-kernel

Various drivers implement architecture and/or device specific means
to restart (reset) the system. Various mechanisms have been implemented
to support those schemes. The best known mechanism is arm_pm_restart,
which is a function pointer to be set either from platform specific code
or from drivers. Another mechanism is to use hardware watchdogs to issue
a reset; this mechanism is used if there is no other method available
to reset a board or system. Two examples are alim7101_wdt, which currently
uses the reboot notifier to trigger a reset, and moxart_wdt, which registers
the arm_pm_restart function.

The existing mechanisms have a number of drawbacks. Typically only one scheme
to restart the system is supported (at least if arm_pm_restart is used).
At least in theory there can be mutliple means to restart the system, some of
which may be less desirable (for example one mechanism may only reset the CPU,
while another may reset the entire system). Using arm_pm_restart can also be
racy if the function pointer is set from a driver, as the driver may be in
the process of being unloaded when arm_pm_restart is called.
Using the reboot notifier is always racy, as it is unknown if and when
other functions using the reboot notifier have completed execution
by the time the watchdog fires.

To solve the problem, introduce a system restart notifier. This notifier
is expected to be called from the architecture specific machine_restart()
function. Drivers providing system restart functionality (such as the watchdog
drivers mentioned above) are expected to register with this notifier.

Patch 1 of this series implements the notifier function. Patches 2 and 3
implement calling the notifier chain from arm and arm64 restart code.

Patch 4 modifies the restart-poweroff driver to no longer call arm_pm_restart
directly but machine_restart. This is done to avoid calling arm_pm_restart
from more than one place. The change makes the driver architecture independent,
so it would be possible to drop the arm dependency from its Kconfig entry.

Patch 5 and 6 convert existing restart handlers in the watchdog subsystem
to use the restart notifier. Patch 7 unexports arm_pm_restart to ensure
that no one gets the idea to implement a restart handler as module.

---
v2: Add patch 4
    Only call blocking notifier call chain if arm_pm_restart was not set.

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

* [PATCH v2 1/7] kernel: Add support for restart notifier call chain
  2014-07-06 23:38 ` Guenter Roeck
@ 2014-07-06 23:38   ` Guenter Roeck
  -1 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-watchdog, linux-arm-kernel
  Cc: Wim Van Sebroeck, Catalin Marinas, Maxime Ripard, Will Deacon,
	Arnd Bergmann, Heiko Stuebner, Russell King, Jonas Jensen,
	Randy Dunlap, Andrew Morton, Steven Rostedt, Ingo Molnar,
	Dmitry Eremin-Solenikov, David Woodhouse, linux-doc,
	linux-kernel, Guenter Roeck

Various drivers implement architecture and/or device specific means
to restart (reset) the system. Various mechanisms have been implemented
to support those schemes. The best known mechanism is arm_pm_restart,
which is a function pointer to be set either from platform specific code
or from drivers. Another mechanism is to use hardware watchdogs to issue
a reset; this mechanism is used if there is no other method available
to reset a board or system. Two examples are alim7101_wdt, which currently
uses the reboot notifier to trigger a reset, and moxart_wdt, which registers
the arm_pm_restart function.

The existing mechanisms have a number of drawbacks. Typically only one scheme
to restart the system is supported (at least if arm_pm_restart is used).
At least in theory there can be mutliple means to restart the system, some of
which may be less desirable (for example one mechanism may only reset the CPU,
while another may reset the entire system). Using arm_pm_restart can also be
racy if the function pointer is set from a driver, as the driver may be in
the process of being unloaded when arm_pm_restart is called.
Using the reboot notifier is always racy, as it is unknown if and when
other functions using the reboot notifier have completed execution
by the time the watchdog fires.

To solve the problem, introduce a system restart notifier. This notifier
is expected to be called from the architecture specific machine_restart()
function. Drivers providing system restart functionality (such as the watchdog
drivers mentioned above) are expected to register with this notifier.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: No change

 include/linux/notifier.h |  1 +
 include/linux/reboot.h   |  2 ++
 kernel/notifier.c        |  6 ++++++
 kernel/reboot.c          | 32 ++++++++++++++++++++++++++++++++
 4 files changed, 41 insertions(+)

diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index d14a4c3..3d7d2fc 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -210,6 +210,7 @@ static inline int notifier_to_errno(int ret)
 #define KBD_POST_KEYSYM		0x0005 /* Called after keyboard keysym interpretation */
 
 extern struct blocking_notifier_head reboot_notifier_list;
+extern struct blocking_notifier_head restart_notifier_list;
 
 #endif /* __KERNEL__ */
 #endif /* _LINUX_NOTIFIER_H */
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 48bf152..f8e7e0a 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -38,6 +38,8 @@ extern int reboot_force;
 extern int register_reboot_notifier(struct notifier_block *);
 extern int unregister_reboot_notifier(struct notifier_block *);
 
+extern int register_restart_notifier(struct notifier_block *);
+extern int unregister_restart_notifier(struct notifier_block *);
 
 /*
  * Architecture-specific implementations of sys_reboot commands.
diff --git a/kernel/notifier.c b/kernel/notifier.c
index 4803da6..2f2b071 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -14,6 +14,12 @@
 BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
 
 /*
+ *	Notifier list for kernel code which wants to be called
+ *	to restart the system.
+ */
+BLOCKING_NOTIFIER_HEAD(restart_notifier_list);
+
+/*
  *	Notifier chain core routines.  The exported routines below
  *	are layered on top of these, with appropriate locking added.
  */
diff --git a/kernel/reboot.c b/kernel/reboot.c
index a3a9e24..374896f 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -104,6 +104,38 @@ int unregister_reboot_notifier(struct notifier_block *nb)
 }
 EXPORT_SYMBOL(unregister_reboot_notifier);
 
+/**
+ *	register_restart_notifier - Register function to be called to reset
+ *				    the system
+ *	@nb: Info about notifier function to be called
+ *
+ *	Registers a function with the list of functions
+ *	to be called to restart the system.
+ *
+ *	Currently always returns zero, as blocking_notifier_chain_register()
+ *	always returns zero.
+ */
+int register_restart_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&restart_notifier_list, nb);
+}
+EXPORT_SYMBOL(register_restart_notifier);
+
+/**
+ *	unregister_restart_notifier - Unregister previously registered
+ *				      restart notifier
+ *	@nb: Hook to be unregistered
+ *
+ *	Unregisters a previously registered restart notifier function.
+ *
+ *	Returns zero on success, or %-ENOENT on failure.
+ */
+int unregister_restart_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&restart_notifier_list, nb);
+}
+EXPORT_SYMBOL(unregister_restart_notifier);
+
 void migrate_to_reboot_cpu(void)
 {
 	/* The boot cpu is always logical cpu 0 */
-- 
1.9.1


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

* [PATCH v2 1/7] kernel: Add support for restart notifier call chain
@ 2014-07-06 23:38   ` Guenter Roeck
  0 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-arm-kernel

Various drivers implement architecture and/or device specific means
to restart (reset) the system. Various mechanisms have been implemented
to support those schemes. The best known mechanism is arm_pm_restart,
which is a function pointer to be set either from platform specific code
or from drivers. Another mechanism is to use hardware watchdogs to issue
a reset; this mechanism is used if there is no other method available
to reset a board or system. Two examples are alim7101_wdt, which currently
uses the reboot notifier to trigger a reset, and moxart_wdt, which registers
the arm_pm_restart function.

The existing mechanisms have a number of drawbacks. Typically only one scheme
to restart the system is supported (at least if arm_pm_restart is used).
At least in theory there can be mutliple means to restart the system, some of
which may be less desirable (for example one mechanism may only reset the CPU,
while another may reset the entire system). Using arm_pm_restart can also be
racy if the function pointer is set from a driver, as the driver may be in
the process of being unloaded when arm_pm_restart is called.
Using the reboot notifier is always racy, as it is unknown if and when
other functions using the reboot notifier have completed execution
by the time the watchdog fires.

To solve the problem, introduce a system restart notifier. This notifier
is expected to be called from the architecture specific machine_restart()
function. Drivers providing system restart functionality (such as the watchdog
drivers mentioned above) are expected to register with this notifier.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: No change

 include/linux/notifier.h |  1 +
 include/linux/reboot.h   |  2 ++
 kernel/notifier.c        |  6 ++++++
 kernel/reboot.c          | 32 ++++++++++++++++++++++++++++++++
 4 files changed, 41 insertions(+)

diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index d14a4c3..3d7d2fc 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -210,6 +210,7 @@ static inline int notifier_to_errno(int ret)
 #define KBD_POST_KEYSYM		0x0005 /* Called after keyboard keysym interpretation */
 
 extern struct blocking_notifier_head reboot_notifier_list;
+extern struct blocking_notifier_head restart_notifier_list;
 
 #endif /* __KERNEL__ */
 #endif /* _LINUX_NOTIFIER_H */
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 48bf152..f8e7e0a 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -38,6 +38,8 @@ extern int reboot_force;
 extern int register_reboot_notifier(struct notifier_block *);
 extern int unregister_reboot_notifier(struct notifier_block *);
 
+extern int register_restart_notifier(struct notifier_block *);
+extern int unregister_restart_notifier(struct notifier_block *);
 
 /*
  * Architecture-specific implementations of sys_reboot commands.
diff --git a/kernel/notifier.c b/kernel/notifier.c
index 4803da6..2f2b071 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -14,6 +14,12 @@
 BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
 
 /*
+ *	Notifier list for kernel code which wants to be called
+ *	to restart the system.
+ */
+BLOCKING_NOTIFIER_HEAD(restart_notifier_list);
+
+/*
  *	Notifier chain core routines.  The exported routines below
  *	are layered on top of these, with appropriate locking added.
  */
diff --git a/kernel/reboot.c b/kernel/reboot.c
index a3a9e24..374896f 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -104,6 +104,38 @@ int unregister_reboot_notifier(struct notifier_block *nb)
 }
 EXPORT_SYMBOL(unregister_reboot_notifier);
 
+/**
+ *	register_restart_notifier - Register function to be called to reset
+ *				    the system
+ *	@nb: Info about notifier function to be called
+ *
+ *	Registers a function with the list of functions
+ *	to be called to restart the system.
+ *
+ *	Currently always returns zero, as blocking_notifier_chain_register()
+ *	always returns zero.
+ */
+int register_restart_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&restart_notifier_list, nb);
+}
+EXPORT_SYMBOL(register_restart_notifier);
+
+/**
+ *	unregister_restart_notifier - Unregister previously registered
+ *				      restart notifier
+ *	@nb: Hook to be unregistered
+ *
+ *	Unregisters a previously registered restart notifier function.
+ *
+ *	Returns zero on success, or %-ENOENT on failure.
+ */
+int unregister_restart_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&restart_notifier_list, nb);
+}
+EXPORT_SYMBOL(unregister_restart_notifier);
+
 void migrate_to_reboot_cpu(void)
 {
 	/* The boot cpu is always logical cpu 0 */
-- 
1.9.1

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

* [PATCH v2 2/7] arm64: Support restart through restart notifier call chain
  2014-07-06 23:38 ` Guenter Roeck
@ 2014-07-06 23:38   ` Guenter Roeck
  -1 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-watchdog, linux-arm-kernel
  Cc: Wim Van Sebroeck, Catalin Marinas, Maxime Ripard, Will Deacon,
	Arnd Bergmann, Heiko Stuebner, Russell King, Jonas Jensen,
	Randy Dunlap, Andrew Morton, Steven Rostedt, Ingo Molnar,
	Dmitry Eremin-Solenikov, David Woodhouse, linux-doc,
	linux-kernel, Guenter Roeck

The kernel core now supports a notifier call chain to restart
the system. Call it if arm_pm_restart is not set.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: Only call notifier call chain if arm_pm_restart is not set
    Do not include linux/watchdog.h

 arch/arm64/kernel/process.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 43b7c34..585ebe2 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -174,6 +174,9 @@ void machine_restart(char *cmd)
 	/* Now call the architecture specific reboot code. */
 	if (arm_pm_restart)
 		arm_pm_restart(reboot_mode, cmd);
+	else
+		blocking_notifier_call_chain(&restart_notifier_list,
+					     reboot_mode, cmd);
 
 	/*
 	 * Whoops - the architecture was unable to reboot.
-- 
1.9.1


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

* [PATCH v2 2/7] arm64: Support restart through restart notifier call chain
@ 2014-07-06 23:38   ` Guenter Roeck
  0 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-arm-kernel

The kernel core now supports a notifier call chain to restart
the system. Call it if arm_pm_restart is not set.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: Only call notifier call chain if arm_pm_restart is not set
    Do not include linux/watchdog.h

 arch/arm64/kernel/process.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 43b7c34..585ebe2 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -174,6 +174,9 @@ void machine_restart(char *cmd)
 	/* Now call the architecture specific reboot code. */
 	if (arm_pm_restart)
 		arm_pm_restart(reboot_mode, cmd);
+	else
+		blocking_notifier_call_chain(&restart_notifier_list,
+					     reboot_mode, cmd);
 
 	/*
 	 * Whoops - the architecture was unable to reboot.
-- 
1.9.1

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

* [PATCH v2 3/7] arm: Support restart through restart notifier call chain
  2014-07-06 23:38 ` Guenter Roeck
@ 2014-07-06 23:38   ` Guenter Roeck
  -1 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-watchdog, linux-arm-kernel
  Cc: Wim Van Sebroeck, Catalin Marinas, Maxime Ripard, Will Deacon,
	Arnd Bergmann, Heiko Stuebner, Russell King, Jonas Jensen,
	Randy Dunlap, Andrew Morton, Steven Rostedt, Ingo Molnar,
	Dmitry Eremin-Solenikov, David Woodhouse, linux-doc,
	linux-kernel, Guenter Roeck

The kernel core now supports a notifier call chain for system
restart functions.

With this change, the arm_pm_restart callback is now optional,
so check if it is set before calling it. Only call the notifier
functions if arm_pm_restart is not set.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: Only call notifier call chain if arm_pm_restart is not set
    Do not include linux/watchdog.h

 arch/arm/kernel/process.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 81ef686..5108e45 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -230,7 +230,11 @@ void machine_restart(char *cmd)
 	local_irq_disable();
 	smp_send_stop();
 
-	arm_pm_restart(reboot_mode, cmd);
+	if (arm_pm_restart)
+		arm_pm_restart(reboot_mode, cmd);
+	else
+		blocking_notifier_call_chain(&restart_notifier_list,
+					     reboot_mode, cmd);
 
 	/* Give a grace period for failure to restart of 1s */
 	mdelay(1000);
-- 
1.9.1


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

* [PATCH v2 3/7] arm: Support restart through restart notifier call chain
@ 2014-07-06 23:38   ` Guenter Roeck
  0 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-arm-kernel

The kernel core now supports a notifier call chain for system
restart functions.

With this change, the arm_pm_restart callback is now optional,
so check if it is set before calling it. Only call the notifier
functions if arm_pm_restart is not set.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: Only call notifier call chain if arm_pm_restart is not set
    Do not include linux/watchdog.h

 arch/arm/kernel/process.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 81ef686..5108e45 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -230,7 +230,11 @@ void machine_restart(char *cmd)
 	local_irq_disable();
 	smp_send_stop();
 
-	arm_pm_restart(reboot_mode, cmd);
+	if (arm_pm_restart)
+		arm_pm_restart(reboot_mode, cmd);
+	else
+		blocking_notifier_call_chain(&restart_notifier_list,
+					     reboot_mode, cmd);
 
 	/* Give a grace period for failure to restart of 1s */
 	mdelay(1000);
-- 
1.9.1

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

* [PATCH v2 4/7] power/restart: Call machine_restart instead of arm_pm_restart
  2014-07-06 23:38 ` Guenter Roeck
@ 2014-07-06 23:38   ` Guenter Roeck
  -1 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-watchdog, linux-arm-kernel
  Cc: Wim Van Sebroeck, Catalin Marinas, Maxime Ripard, Will Deacon,
	Arnd Bergmann, Heiko Stuebner, Russell King, Jonas Jensen,
	Randy Dunlap, Andrew Morton, Steven Rostedt, Ingo Molnar,
	Dmitry Eremin-Solenikov, David Woodhouse, linux-doc,
	linux-kernel, Guenter Roeck

machine_restart is supported on non-ARM platforms, and and ultimately calls
arm_pm_restart, so dont call arm_pm_restart directly but use the more
generic function.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: Added patch.

 drivers/power/reset/restart-poweroff.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c
index 5758033..47f10eb 100644
--- a/drivers/power/reset/restart-poweroff.c
+++ b/drivers/power/reset/restart-poweroff.c
@@ -20,7 +20,8 @@
 
 static void restart_poweroff_do_poweroff(void)
 {
-	arm_pm_restart(REBOOT_HARD, NULL);
+	reboot_mode = REBOOT_HARD;
+	machine_restart(NULL);
 }
 
 static int restart_poweroff_probe(struct platform_device *pdev)
-- 
1.9.1


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

* [PATCH v2 4/7] power/restart: Call machine_restart instead of arm_pm_restart
@ 2014-07-06 23:38   ` Guenter Roeck
  0 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-arm-kernel

machine_restart is supported on non-ARM platforms, and and ultimately calls
arm_pm_restart, so dont call arm_pm_restart directly but use the more
generic function.

Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: Added patch.

 drivers/power/reset/restart-poweroff.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c
index 5758033..47f10eb 100644
--- a/drivers/power/reset/restart-poweroff.c
+++ b/drivers/power/reset/restart-poweroff.c
@@ -20,7 +20,8 @@
 
 static void restart_poweroff_do_poweroff(void)
 {
-	arm_pm_restart(REBOOT_HARD, NULL);
+	reboot_mode = REBOOT_HARD;
+	machine_restart(NULL);
 }
 
 static int restart_poweroff_probe(struct platform_device *pdev)
-- 
1.9.1

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

* [PATCH v2 5/7] watchdog: moxart: Register restart handler with restart notifier
  2014-07-06 23:38 ` Guenter Roeck
@ 2014-07-06 23:38   ` Guenter Roeck
  -1 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-watchdog, linux-arm-kernel
  Cc: Wim Van Sebroeck, Catalin Marinas, Maxime Ripard, Will Deacon,
	Arnd Bergmann, Heiko Stuebner, Russell King, Jonas Jensen,
	Randy Dunlap, Andrew Morton, Steven Rostedt, Ingo Molnar,
	Dmitry Eremin-Solenikov, David Woodhouse, linux-doc,
	linux-kernel, Guenter Roeck

The kernel now provides an API to trigger a system restart.
Register with it instead of setting arm_pm_restart.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: No change

 drivers/watchdog/moxart_wdt.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c
index 4aa3a8a..aef1121 100644
--- a/drivers/watchdog/moxart_wdt.c
+++ b/drivers/watchdog/moxart_wdt.c
@@ -15,12 +15,12 @@
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
+#include <linux/notifier.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/watchdog.h>
 #include <linux/moduleparam.h>
 
-#include <asm/system_misc.h>
-
 #define REG_COUNT			0x4
 #define REG_MODE			0x8
 #define REG_ENABLE			0xC
@@ -35,13 +35,20 @@ static struct moxart_wdt_dev *moxart_restart_ctx;
 
 static int heartbeat;
 
-static void moxart_wdt_restart(enum reboot_mode reboot_mode, const char *cmd)
+static int moxart_restart_notify(struct notifier_block *this,
+				 unsigned long mode, void *cmd)
 {
 	writel(1, moxart_restart_ctx->base + REG_COUNT);
 	writel(0x5ab9, moxart_restart_ctx->base + REG_MODE);
 	writel(0x03, moxart_restart_ctx->base + REG_ENABLE);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block moxart_restart_notifier = {
+	.notifier_call = moxart_restart_notify,
+};
+
 static int moxart_wdt_stop(struct watchdog_device *wdt_dev)
 {
 	struct moxart_wdt_dev *moxart_wdt = watchdog_get_drvdata(wdt_dev);
@@ -137,7 +144,9 @@ static int moxart_wdt_probe(struct platform_device *pdev)
 		return err;
 
 	moxart_restart_ctx = moxart_wdt;
-	arm_pm_restart = moxart_wdt_restart;
+	err = register_restart_notifier(&moxart_restart_notifier);
+	if (err)
+		dev_err(dev, "cannot register reset notifier (err=%d)\n", err);
 
 	dev_dbg(dev, "Watchdog enabled (heartbeat=%d sec, nowayout=%d)\n",
 		moxart_wdt->dev.timeout, nowayout);
@@ -149,9 +158,8 @@ static int moxart_wdt_remove(struct platform_device *pdev)
 {
 	struct moxart_wdt_dev *moxart_wdt = platform_get_drvdata(pdev);
 
-	arm_pm_restart = NULL;
+	unregister_restart_notifier(&moxart_restart_notifier);
 	moxart_wdt_stop(&moxart_wdt->dev);
-	watchdog_unregister_device(&moxart_wdt->dev);
 
 	return 0;
 }
-- 
1.9.1


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

* [PATCH v2 5/7] watchdog: moxart: Register restart handler with restart notifier
@ 2014-07-06 23:38   ` Guenter Roeck
  0 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-arm-kernel

The kernel now provides an API to trigger a system restart.
Register with it instead of setting arm_pm_restart.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: No change

 drivers/watchdog/moxart_wdt.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c
index 4aa3a8a..aef1121 100644
--- a/drivers/watchdog/moxart_wdt.c
+++ b/drivers/watchdog/moxart_wdt.c
@@ -15,12 +15,12 @@
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
+#include <linux/notifier.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/watchdog.h>
 #include <linux/moduleparam.h>
 
-#include <asm/system_misc.h>
-
 #define REG_COUNT			0x4
 #define REG_MODE			0x8
 #define REG_ENABLE			0xC
@@ -35,13 +35,20 @@ static struct moxart_wdt_dev *moxart_restart_ctx;
 
 static int heartbeat;
 
-static void moxart_wdt_restart(enum reboot_mode reboot_mode, const char *cmd)
+static int moxart_restart_notify(struct notifier_block *this,
+				 unsigned long mode, void *cmd)
 {
 	writel(1, moxart_restart_ctx->base + REG_COUNT);
 	writel(0x5ab9, moxart_restart_ctx->base + REG_MODE);
 	writel(0x03, moxart_restart_ctx->base + REG_ENABLE);
+
+	return NOTIFY_DONE;
 }
 
+static struct notifier_block moxart_restart_notifier = {
+	.notifier_call = moxart_restart_notify,
+};
+
 static int moxart_wdt_stop(struct watchdog_device *wdt_dev)
 {
 	struct moxart_wdt_dev *moxart_wdt = watchdog_get_drvdata(wdt_dev);
@@ -137,7 +144,9 @@ static int moxart_wdt_probe(struct platform_device *pdev)
 		return err;
 
 	moxart_restart_ctx = moxart_wdt;
-	arm_pm_restart = moxart_wdt_restart;
+	err = register_restart_notifier(&moxart_restart_notifier);
+	if (err)
+		dev_err(dev, "cannot register reset notifier (err=%d)\n", err);
 
 	dev_dbg(dev, "Watchdog enabled (heartbeat=%d sec, nowayout=%d)\n",
 		moxart_wdt->dev.timeout, nowayout);
@@ -149,9 +158,8 @@ static int moxart_wdt_remove(struct platform_device *pdev)
 {
 	struct moxart_wdt_dev *moxart_wdt = platform_get_drvdata(pdev);
 
-	arm_pm_restart = NULL;
+	unregister_restart_notifier(&moxart_restart_notifier);
 	moxart_wdt_stop(&moxart_wdt->dev);
-	watchdog_unregister_device(&moxart_wdt->dev);
 
 	return 0;
 }
-- 
1.9.1

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

* [PATCH v2 6/7] watchdog: alim7101: Register restart handler with restart notifier
  2014-07-06 23:38 ` Guenter Roeck
@ 2014-07-06 23:38   ` Guenter Roeck
  -1 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-watchdog, linux-arm-kernel
  Cc: Wim Van Sebroeck, Catalin Marinas, Maxime Ripard, Will Deacon,
	Arnd Bergmann, Heiko Stuebner, Russell King, Jonas Jensen,
	Randy Dunlap, Andrew Morton, Steven Rostedt, Ingo Molnar,
	Dmitry Eremin-Solenikov, David Woodhouse, linux-doc,
	linux-kernel, Guenter Roeck

The kernel core now provides an API to trigger a system restart.
Register with it to restart the system instead of misusing the
reboot notifier.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: No change

 drivers/watchdog/alim7101_wdt.c | 41 +++++++++++++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 10 deletions(-)

diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 996b2f7..239d6b2 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -301,6 +301,27 @@ static struct miscdevice wdt_miscdev = {
 	.fops	=	&wdt_fops,
 };
 
+static int wdt_restart_notify(struct notifier_block *this, unsigned long mode,
+			      void *cmd)
+{
+	/*
+	 * Cobalt devices have no way of rebooting themselves other
+	 * than getting the watchdog to pull reset, so we restart the
+	 * watchdog on reboot with no heartbeat.
+	 */
+	wdt_change(WDT_ENABLE);
+
+	/* loop until the watchdog fires */
+	while (true)
+		;
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block wdt_restart_notifier = {
+	.notifier_call = wdt_restart_notify,
+};
+
 /*
  *	Notifier for system down
  */
@@ -311,15 +332,6 @@ static int wdt_notify_sys(struct notifier_block *this,
 	if (code == SYS_DOWN || code == SYS_HALT)
 		wdt_turnoff();
 
-	if (code == SYS_RESTART) {
-		/*
-		 * Cobalt devices have no way of rebooting themselves other
-		 * than getting the watchdog to pull reset, so we restart the
-		 * watchdog on reboot with no heartbeat
-		 */
-		wdt_change(WDT_ENABLE);
-		pr_info("Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second\n");
-	}
 	return NOTIFY_DONE;
 }
 
@@ -338,6 +350,7 @@ static void __exit alim7101_wdt_unload(void)
 	/* Deregister */
 	misc_deregister(&wdt_miscdev);
 	unregister_reboot_notifier(&wdt_notifier);
+	unregister_restart_notifier(&wdt_restart_notifier);
 	pci_dev_put(alim7101_pmu);
 }
 
@@ -390,11 +403,17 @@ static int __init alim7101_wdt_init(void)
 		goto err_out;
 	}
 
+	rc = register_restart_notifier(&wdt_restart_notifier);
+	if (rc) {
+		pr_err("cannot register reboot notifier (err=%d)\n", rc);
+		goto err_out_reboot;
+	}
+
 	rc = misc_register(&wdt_miscdev);
 	if (rc) {
 		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
 		       wdt_miscdev.minor, rc);
-		goto err_out_reboot;
+		goto err_out_restart;
 	}
 
 	if (nowayout)
@@ -404,6 +423,8 @@ static int __init alim7101_wdt_init(void)
 		timeout, nowayout);
 	return 0;
 
+err_out_restart:
+	unregister_restart_notifier(&wdt_restart_notifier);
 err_out_reboot:
 	unregister_reboot_notifier(&wdt_notifier);
 err_out:
-- 
1.9.1


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

* [PATCH v2 6/7] watchdog: alim7101: Register restart handler with restart notifier
@ 2014-07-06 23:38   ` Guenter Roeck
  0 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-arm-kernel

The kernel core now provides an API to trigger a system restart.
Register with it to restart the system instead of misusing the
reboot notifier.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: No change

 drivers/watchdog/alim7101_wdt.c | 41 +++++++++++++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 10 deletions(-)

diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 996b2f7..239d6b2 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -301,6 +301,27 @@ static struct miscdevice wdt_miscdev = {
 	.fops	=	&wdt_fops,
 };
 
+static int wdt_restart_notify(struct notifier_block *this, unsigned long mode,
+			      void *cmd)
+{
+	/*
+	 * Cobalt devices have no way of rebooting themselves other
+	 * than getting the watchdog to pull reset, so we restart the
+	 * watchdog on reboot with no heartbeat.
+	 */
+	wdt_change(WDT_ENABLE);
+
+	/* loop until the watchdog fires */
+	while (true)
+		;
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block wdt_restart_notifier = {
+	.notifier_call = wdt_restart_notify,
+};
+
 /*
  *	Notifier for system down
  */
@@ -311,15 +332,6 @@ static int wdt_notify_sys(struct notifier_block *this,
 	if (code == SYS_DOWN || code == SYS_HALT)
 		wdt_turnoff();
 
-	if (code == SYS_RESTART) {
-		/*
-		 * Cobalt devices have no way of rebooting themselves other
-		 * than getting the watchdog to pull reset, so we restart the
-		 * watchdog on reboot with no heartbeat
-		 */
-		wdt_change(WDT_ENABLE);
-		pr_info("Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second\n");
-	}
 	return NOTIFY_DONE;
 }
 
@@ -338,6 +350,7 @@ static void __exit alim7101_wdt_unload(void)
 	/* Deregister */
 	misc_deregister(&wdt_miscdev);
 	unregister_reboot_notifier(&wdt_notifier);
+	unregister_restart_notifier(&wdt_restart_notifier);
 	pci_dev_put(alim7101_pmu);
 }
 
@@ -390,11 +403,17 @@ static int __init alim7101_wdt_init(void)
 		goto err_out;
 	}
 
+	rc = register_restart_notifier(&wdt_restart_notifier);
+	if (rc) {
+		pr_err("cannot register reboot notifier (err=%d)\n", rc);
+		goto err_out_reboot;
+	}
+
 	rc = misc_register(&wdt_miscdev);
 	if (rc) {
 		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
 		       wdt_miscdev.minor, rc);
-		goto err_out_reboot;
+		goto err_out_restart;
 	}
 
 	if (nowayout)
@@ -404,6 +423,8 @@ static int __init alim7101_wdt_init(void)
 		timeout, nowayout);
 	return 0;
 
+err_out_restart:
+	unregister_restart_notifier(&wdt_restart_notifier);
 err_out_reboot:
 	unregister_reboot_notifier(&wdt_notifier);
 err_out:
-- 
1.9.1

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

* [PATCH v2 7/7] arm/arm64: Unexport restart handlers
  2014-07-06 23:38 ` Guenter Roeck
@ 2014-07-06 23:38   ` Guenter Roeck
  -1 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-watchdog, linux-arm-kernel
  Cc: Wim Van Sebroeck, Catalin Marinas, Maxime Ripard, Will Deacon,
	Arnd Bergmann, Heiko Stuebner, Russell King, Jonas Jensen,
	Randy Dunlap, Andrew Morton, Steven Rostedt, Ingo Molnar,
	Dmitry Eremin-Solenikov, David Woodhouse, linux-doc,
	linux-kernel, Guenter Roeck

Implementing a restart handler in a module don't make sense
as there would be no guarantee that the module is loaded when
a restart is needed. Unexport arm_pm_restart to ensure that
no one gets the idea to do it anyway.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: No change

 arch/arm/kernel/process.c   | 1 -
 arch/arm64/kernel/process.c | 1 -
 2 files changed, 2 deletions(-)

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 5108e45..09854d5 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -125,7 +125,6 @@ void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
 void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd) = null_restart;
-EXPORT_SYMBOL_GPL(arm_pm_restart);
 
 /*
  * This is our default idle handler.
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 585ebe2..d7948f7 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -92,7 +92,6 @@ void (*pm_power_off)(void);
 EXPORT_SYMBOL_GPL(pm_power_off);
 
 void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
-EXPORT_SYMBOL_GPL(arm_pm_restart);
 
 /*
  * This is our default idle handler.
-- 
1.9.1


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

* [PATCH v2 7/7] arm/arm64: Unexport restart handlers
@ 2014-07-06 23:38   ` Guenter Roeck
  0 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-06 23:38 UTC (permalink / raw)
  To: linux-arm-kernel

Implementing a restart handler in a module don't make sense
as there would be no guarantee that the module is loaded when
a restart is needed. Unexport arm_pm_restart to ensure that
no one gets the idea to do it anyway.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v2: No change

 arch/arm/kernel/process.c   | 1 -
 arch/arm64/kernel/process.c | 1 -
 2 files changed, 2 deletions(-)

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 5108e45..09854d5 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -125,7 +125,6 @@ void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
 void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd) = null_restart;
-EXPORT_SYMBOL_GPL(arm_pm_restart);
 
 /*
  * This is our default idle handler.
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 585ebe2..d7948f7 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -92,7 +92,6 @@ void (*pm_power_off)(void);
 EXPORT_SYMBOL_GPL(pm_power_off);
 
 void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
-EXPORT_SYMBOL_GPL(arm_pm_restart);
 
 /*
  * This is our default idle handler.
-- 
1.9.1

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

* Re: [PATCH v2 1/7] kernel: Add support for restart notifier call chain
  2014-07-06 23:38   ` Guenter Roeck
@ 2014-07-07 21:14     ` Andrew Morton
  -1 siblings, 0 replies; 24+ messages in thread
From: Andrew Morton @ 2014-07-07 21:14 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: linux-watchdog, linux-arm-kernel, Wim Van Sebroeck,
	Catalin Marinas, Maxime Ripard, Will Deacon, Arnd Bergmann,
	Heiko Stuebner, Russell King, Jonas Jensen, Randy Dunlap,
	Steven Rostedt, Ingo Molnar, Dmitry Eremin-Solenikov,
	David Woodhouse, linux-doc, linux-kernel

On Sun,  6 Jul 2014 16:38:14 -0700 Guenter Roeck <linux@roeck-us.net> wrote:

> Various drivers implement architecture and/or device specific means
> to restart (reset) the system. Various mechanisms have been implemented
> to support those schemes. The best known mechanism is arm_pm_restart,
> which is a function pointer to be set either from platform specific code
> or from drivers. Another mechanism is to use hardware watchdogs to issue
> a reset; this mechanism is used if there is no other method available
> to reset a board or system. Two examples are alim7101_wdt, which currently
> uses the reboot notifier to trigger a reset, and moxart_wdt, which registers
> the arm_pm_restart function.
> 
> The existing mechanisms have a number of drawbacks. Typically only one scheme
> to restart the system is supported (at least if arm_pm_restart is used).
> At least in theory there can be mutliple means to restart the system, some of
> which may be less desirable (for example one mechanism may only reset the CPU,
> while another may reset the entire system). Using arm_pm_restart can also be
> racy if the function pointer is set from a driver, as the driver may be in
> the process of being unloaded when arm_pm_restart is called.
> Using the reboot notifier is always racy, as it is unknown if and when
> other functions using the reboot notifier have completed execution
> by the time the watchdog fires.
> 
> To solve the problem, introduce a system restart notifier. This notifier
> is expected to be called from the architecture specific machine_restart()
> function. Drivers providing system restart functionality (such as the watchdog
> drivers mentioned above) are expected to register with this notifier.

It all looks sane to my unfamiliar eye.

>  /*
> + *	Notifier list for kernel code which wants to be called
> + *	to restart the system.
> + */

hm, is this all we have to say?

> --- a/kernel/reboot.c
> +++ b/kernel/reboot.c
> @@ -104,6 +104,38 @@ int unregister_reboot_notifier(struct notifier_block *nb)
>  }
>  EXPORT_SYMBOL(unregister_reboot_notifier);
>  
> +/**
> + *	register_restart_notifier - Register function to be called to reset
> + *				    the system
> + *	@nb: Info about notifier function to be called
> + *
> + *	Registers a function with the list of functions
> + *	to be called to restart the system.
> + *
> + *	Currently always returns zero, as blocking_notifier_chain_register()
> + *	always returns zero.
> + */

This would be a good place to describe what those notifier callbacks
actually do.  Why they exist, what their role is, under what
circumstances they are called, what values they should return, etc.



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

* [PATCH v2 1/7] kernel: Add support for restart notifier call chain
@ 2014-07-07 21:14     ` Andrew Morton
  0 siblings, 0 replies; 24+ messages in thread
From: Andrew Morton @ 2014-07-07 21:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun,  6 Jul 2014 16:38:14 -0700 Guenter Roeck <linux@roeck-us.net> wrote:

> Various drivers implement architecture and/or device specific means
> to restart (reset) the system. Various mechanisms have been implemented
> to support those schemes. The best known mechanism is arm_pm_restart,
> which is a function pointer to be set either from platform specific code
> or from drivers. Another mechanism is to use hardware watchdogs to issue
> a reset; this mechanism is used if there is no other method available
> to reset a board or system. Two examples are alim7101_wdt, which currently
> uses the reboot notifier to trigger a reset, and moxart_wdt, which registers
> the arm_pm_restart function.
> 
> The existing mechanisms have a number of drawbacks. Typically only one scheme
> to restart the system is supported (at least if arm_pm_restart is used).
> At least in theory there can be mutliple means to restart the system, some of
> which may be less desirable (for example one mechanism may only reset the CPU,
> while another may reset the entire system). Using arm_pm_restart can also be
> racy if the function pointer is set from a driver, as the driver may be in
> the process of being unloaded when arm_pm_restart is called.
> Using the reboot notifier is always racy, as it is unknown if and when
> other functions using the reboot notifier have completed execution
> by the time the watchdog fires.
> 
> To solve the problem, introduce a system restart notifier. This notifier
> is expected to be called from the architecture specific machine_restart()
> function. Drivers providing system restart functionality (such as the watchdog
> drivers mentioned above) are expected to register with this notifier.

It all looks sane to my unfamiliar eye.

>  /*
> + *	Notifier list for kernel code which wants to be called
> + *	to restart the system.
> + */

hm, is this all we have to say?

> --- a/kernel/reboot.c
> +++ b/kernel/reboot.c
> @@ -104,6 +104,38 @@ int unregister_reboot_notifier(struct notifier_block *nb)
>  }
>  EXPORT_SYMBOL(unregister_reboot_notifier);
>  
> +/**
> + *	register_restart_notifier - Register function to be called to reset
> + *				    the system
> + *	@nb: Info about notifier function to be called
> + *
> + *	Registers a function with the list of functions
> + *	to be called to restart the system.
> + *
> + *	Currently always returns zero, as blocking_notifier_chain_register()
> + *	always returns zero.
> + */

This would be a good place to describe what those notifier callbacks
actually do.  Why they exist, what their role is, under what
circumstances they are called, what values they should return, etc.

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

* Re: [PATCH v2 2/7] arm64: Support restart through restart notifier call chain
  2014-07-06 23:38   ` Guenter Roeck
@ 2014-07-07 21:16     ` Andrew Morton
  -1 siblings, 0 replies; 24+ messages in thread
From: Andrew Morton @ 2014-07-07 21:16 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: linux-watchdog, linux-arm-kernel, Wim Van Sebroeck,
	Catalin Marinas, Maxime Ripard, Will Deacon, Arnd Bergmann,
	Heiko Stuebner, Russell King, Jonas Jensen, Randy Dunlap,
	Steven Rostedt, Ingo Molnar, Dmitry Eremin-Solenikov,
	David Woodhouse, linux-doc, linux-kernel

On Sun,  6 Jul 2014 16:38:15 -0700 Guenter Roeck <linux@roeck-us.net> wrote:

> The kernel core now supports a notifier call chain to restart
> the system. Call it if arm_pm_restart is not set.
> 
> ...
>
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -174,6 +174,9 @@ void machine_restart(char *cmd)
>  	/* Now call the architecture specific reboot code. */
>  	if (arm_pm_restart)
>  		arm_pm_restart(reboot_mode, cmd);
> +	else
> +		blocking_notifier_call_chain(&restart_notifier_list,
> +					     reboot_mode, cmd);

It would be a bit neater to have a helper function to perform the call,
rather than directly accessing the notifier list.  Apart from anything
else, this hides the fact that the core code (presently!) uses the
blocking_ style notifiers.


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

* [PATCH v2 2/7] arm64: Support restart through restart notifier call chain
@ 2014-07-07 21:16     ` Andrew Morton
  0 siblings, 0 replies; 24+ messages in thread
From: Andrew Morton @ 2014-07-07 21:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun,  6 Jul 2014 16:38:15 -0700 Guenter Roeck <linux@roeck-us.net> wrote:

> The kernel core now supports a notifier call chain to restart
> the system. Call it if arm_pm_restart is not set.
> 
> ...
>
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -174,6 +174,9 @@ void machine_restart(char *cmd)
>  	/* Now call the architecture specific reboot code. */
>  	if (arm_pm_restart)
>  		arm_pm_restart(reboot_mode, cmd);
> +	else
> +		blocking_notifier_call_chain(&restart_notifier_list,
> +					     reboot_mode, cmd);

It would be a bit neater to have a helper function to perform the call,
rather than directly accessing the notifier list.  Apart from anything
else, this hides the fact that the core code (presently!) uses the
blocking_ style notifiers.

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

* Re: [PATCH v2 1/7] kernel: Add support for restart notifier call chain
  2014-07-07 21:14     ` Andrew Morton
@ 2014-07-08  1:10       ` Guenter Roeck
  -1 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-08  1:10 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-watchdog, linux-arm-kernel, Wim Van Sebroeck,
	Catalin Marinas, Maxime Ripard, Will Deacon, Arnd Bergmann,
	Heiko Stuebner, Russell King, Jonas Jensen, Randy Dunlap,
	Steven Rostedt, Ingo Molnar, Dmitry Eremin-Solenikov,
	David Woodhouse, linux-doc, linux-kernel

On 07/07/2014 02:14 PM, Andrew Morton wrote:
> On Sun,  6 Jul 2014 16:38:14 -0700 Guenter Roeck <linux@roeck-us.net> wrote:
>
>> Various drivers implement architecture and/or device specific means
>> to restart (reset) the system. Various mechanisms have been implemented
>> to support those schemes. The best known mechanism is arm_pm_restart,
>> which is a function pointer to be set either from platform specific code
>> or from drivers. Another mechanism is to use hardware watchdogs to issue
>> a reset; this mechanism is used if there is no other method available
>> to reset a board or system. Two examples are alim7101_wdt, which currently
>> uses the reboot notifier to trigger a reset, and moxart_wdt, which registers
>> the arm_pm_restart function.
>>
>> The existing mechanisms have a number of drawbacks. Typically only one scheme
>> to restart the system is supported (at least if arm_pm_restart is used).
>> At least in theory there can be mutliple means to restart the system, some of
>> which may be less desirable (for example one mechanism may only reset the CPU,
>> while another may reset the entire system). Using arm_pm_restart can also be
>> racy if the function pointer is set from a driver, as the driver may be in
>> the process of being unloaded when arm_pm_restart is called.
>> Using the reboot notifier is always racy, as it is unknown if and when
>> other functions using the reboot notifier have completed execution
>> by the time the watchdog fires.
>>
>> To solve the problem, introduce a system restart notifier. This notifier
>> is expected to be called from the architecture specific machine_restart()
>> function. Drivers providing system restart functionality (such as the watchdog
>> drivers mentioned above) are expected to register with this notifier.
>
> It all looks sane to my unfamiliar eye.
>
>>   /*
>> + *	Notifier list for kernel code which wants to be called
>> + *	to restart the system.
>> + */
>
> hm, is this all we have to say?
>
>> --- a/kernel/reboot.c
>> +++ b/kernel/reboot.c
>> @@ -104,6 +104,38 @@ int unregister_reboot_notifier(struct notifier_block *nb)
>>   }
>>   EXPORT_SYMBOL(unregister_reboot_notifier);
>>
>> +/**
>> + *	register_restart_notifier - Register function to be called to reset
>> + *				    the system
>> + *	@nb: Info about notifier function to be called
>> + *
>> + *	Registers a function with the list of functions
>> + *	to be called to restart the system.
>> + *
>> + *	Currently always returns zero, as blocking_notifier_chain_register()
>> + *	always returns zero.
>> + */
>
> This would be a good place to describe what those notifier callbacks
> actually do.  Why they exist, what their role is, under what
> circumstances they are called, what values they should return, etc.
>

Makes sense. Done.

Guenter



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

* [PATCH v2 1/7] kernel: Add support for restart notifier call chain
@ 2014-07-08  1:10       ` Guenter Roeck
  0 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-08  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/07/2014 02:14 PM, Andrew Morton wrote:
> On Sun,  6 Jul 2014 16:38:14 -0700 Guenter Roeck <linux@roeck-us.net> wrote:
>
>> Various drivers implement architecture and/or device specific means
>> to restart (reset) the system. Various mechanisms have been implemented
>> to support those schemes. The best known mechanism is arm_pm_restart,
>> which is a function pointer to be set either from platform specific code
>> or from drivers. Another mechanism is to use hardware watchdogs to issue
>> a reset; this mechanism is used if there is no other method available
>> to reset a board or system. Two examples are alim7101_wdt, which currently
>> uses the reboot notifier to trigger a reset, and moxart_wdt, which registers
>> the arm_pm_restart function.
>>
>> The existing mechanisms have a number of drawbacks. Typically only one scheme
>> to restart the system is supported (at least if arm_pm_restart is used).
>> At least in theory there can be mutliple means to restart the system, some of
>> which may be less desirable (for example one mechanism may only reset the CPU,
>> while another may reset the entire system). Using arm_pm_restart can also be
>> racy if the function pointer is set from a driver, as the driver may be in
>> the process of being unloaded when arm_pm_restart is called.
>> Using the reboot notifier is always racy, as it is unknown if and when
>> other functions using the reboot notifier have completed execution
>> by the time the watchdog fires.
>>
>> To solve the problem, introduce a system restart notifier. This notifier
>> is expected to be called from the architecture specific machine_restart()
>> function. Drivers providing system restart functionality (such as the watchdog
>> drivers mentioned above) are expected to register with this notifier.
>
> It all looks sane to my unfamiliar eye.
>
>>   /*
>> + *	Notifier list for kernel code which wants to be called
>> + *	to restart the system.
>> + */
>
> hm, is this all we have to say?
>
>> --- a/kernel/reboot.c
>> +++ b/kernel/reboot.c
>> @@ -104,6 +104,38 @@ int unregister_reboot_notifier(struct notifier_block *nb)
>>   }
>>   EXPORT_SYMBOL(unregister_reboot_notifier);
>>
>> +/**
>> + *	register_restart_notifier - Register function to be called to reset
>> + *				    the system
>> + *	@nb: Info about notifier function to be called
>> + *
>> + *	Registers a function with the list of functions
>> + *	to be called to restart the system.
>> + *
>> + *	Currently always returns zero, as blocking_notifier_chain_register()
>> + *	always returns zero.
>> + */
>
> This would be a good place to describe what those notifier callbacks
> actually do.  Why they exist, what their role is, under what
> circumstances they are called, what values they should return, etc.
>

Makes sense. Done.

Guenter

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

* Re: [PATCH v2 2/7] arm64: Support restart through restart notifier call chain
  2014-07-07 21:16     ` Andrew Morton
@ 2014-07-08  1:12       ` Guenter Roeck
  -1 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-08  1:12 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-watchdog, linux-arm-kernel, Wim Van Sebroeck,
	Catalin Marinas, Maxime Ripard, Will Deacon, Arnd Bergmann,
	Heiko Stuebner, Russell King, Jonas Jensen, Randy Dunlap,
	Steven Rostedt, Ingo Molnar, Dmitry Eremin-Solenikov,
	David Woodhouse, linux-doc, linux-kernel

On 07/07/2014 02:16 PM, Andrew Morton wrote:
> On Sun,  6 Jul 2014 16:38:15 -0700 Guenter Roeck <linux@roeck-us.net> wrote:
>
>> The kernel core now supports a notifier call chain to restart
>> the system. Call it if arm_pm_restart is not set.
>>
>> ...
>>
>> --- a/arch/arm64/kernel/process.c
>> +++ b/arch/arm64/kernel/process.c
>> @@ -174,6 +174,9 @@ void machine_restart(char *cmd)
>>   	/* Now call the architecture specific reboot code. */
>>   	if (arm_pm_restart)
>>   		arm_pm_restart(reboot_mode, cmd);
>> +	else
>> +		blocking_notifier_call_chain(&restart_notifier_list,
>> +					     reboot_mode, cmd);
>
> It would be a bit neater to have a helper function to perform the call,
> rather than directly accessing the notifier list.  Apart from anything
> else, this hides the fact that the core code (presently!) uses the
> blocking_ style notifiers.
>

Introduced kernel_restart_notify (proposals for better names welcome).
As a side effect, moved restart_notifier_list into kernel/reboot.c and
made it static.

Thanks,
Guenter


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

* [PATCH v2 2/7] arm64: Support restart through restart notifier call chain
@ 2014-07-08  1:12       ` Guenter Roeck
  0 siblings, 0 replies; 24+ messages in thread
From: Guenter Roeck @ 2014-07-08  1:12 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/07/2014 02:16 PM, Andrew Morton wrote:
> On Sun,  6 Jul 2014 16:38:15 -0700 Guenter Roeck <linux@roeck-us.net> wrote:
>
>> The kernel core now supports a notifier call chain to restart
>> the system. Call it if arm_pm_restart is not set.
>>
>> ...
>>
>> --- a/arch/arm64/kernel/process.c
>> +++ b/arch/arm64/kernel/process.c
>> @@ -174,6 +174,9 @@ void machine_restart(char *cmd)
>>   	/* Now call the architecture specific reboot code. */
>>   	if (arm_pm_restart)
>>   		arm_pm_restart(reboot_mode, cmd);
>> +	else
>> +		blocking_notifier_call_chain(&restart_notifier_list,
>> +					     reboot_mode, cmd);
>
> It would be a bit neater to have a helper function to perform the call,
> rather than directly accessing the notifier list.  Apart from anything
> else, this hides the fact that the core code (presently!) uses the
> blocking_ style notifiers.
>

Introduced kernel_restart_notify (proposals for better names welcome).
As a side effect, moved restart_notifier_list into kernel/reboot.c and
made it static.

Thanks,
Guenter

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

end of thread, other threads:[~2014-07-08  1:12 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-06 23:38 [RFC PATCH v2 0/7] kernel: Add support for restart notifier call chain Guenter Roeck
2014-07-06 23:38 ` Guenter Roeck
2014-07-06 23:38 ` [PATCH v2 1/7] " Guenter Roeck
2014-07-06 23:38   ` Guenter Roeck
2014-07-07 21:14   ` Andrew Morton
2014-07-07 21:14     ` Andrew Morton
2014-07-08  1:10     ` Guenter Roeck
2014-07-08  1:10       ` Guenter Roeck
2014-07-06 23:38 ` [PATCH v2 2/7] arm64: Support restart through " Guenter Roeck
2014-07-06 23:38   ` Guenter Roeck
2014-07-07 21:16   ` Andrew Morton
2014-07-07 21:16     ` Andrew Morton
2014-07-08  1:12     ` Guenter Roeck
2014-07-08  1:12       ` Guenter Roeck
2014-07-06 23:38 ` [PATCH v2 3/7] arm: " Guenter Roeck
2014-07-06 23:38   ` Guenter Roeck
2014-07-06 23:38 ` [PATCH v2 4/7] power/restart: Call machine_restart instead of arm_pm_restart Guenter Roeck
2014-07-06 23:38   ` Guenter Roeck
2014-07-06 23:38 ` [PATCH v2 5/7] watchdog: moxart: Register restart handler with restart notifier Guenter Roeck
2014-07-06 23:38   ` Guenter Roeck
2014-07-06 23:38 ` [PATCH v2 6/7] watchdog: alim7101: " Guenter Roeck
2014-07-06 23:38   ` Guenter Roeck
2014-07-06 23:38 ` [PATCH v2 7/7] arm/arm64: Unexport restart handlers Guenter Roeck
2014-07-06 23:38   ` Guenter Roeck

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.