Kexec Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
To: Simon Horman <horms@verge.net.au>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Vivek Goyal <vgoyal@redhat.com>
Cc: kexec@lists.infradead.org, Corey Minyard <minyard@acm.org>
Subject: [RFC v2 PATCH 1/7] purgatory: Introduce timeout API
Date: Mon, 22 Feb 2016 20:56:19 +0900	[thread overview]
Message-ID: <20160222115619.4231.6469.stgit@softrs> (raw)
In-Reply-To: <20160222115617.4231.50041.stgit@softrs>

This patch introduces timeout API for purgatory code.

Because we don't want to use interrupts in purgatory, this timeout
API is based on polling of the clock.

If you want to start a timer, call init_timeout() with seconds to
the timeout and an instance of struct timeout_info which manages the
timer virtually.  Then, you call EXIT_ON_TIMEOUT() macro periodically
to check if the timeout happens.  If it happens, the control jumps
to timed_out label to handle it.  This means you need to place
timed_out label in each caller function.

To make this timeout API work, an actual implementation of
get_unix_time() which returns the current UNIX epoch time is needed.

Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
---
 purgatory/Makefile       |    4 ++-
 purgatory/include/time.h |   33 ++++++++++++++++++++++++++
 purgatory/time.c         |   59 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 purgatory/include/time.h
 create mode 100644 purgatory/time.c

diff --git a/purgatory/Makefile b/purgatory/Makefile
index 2b5c061..4a30b94 100644
--- a/purgatory/Makefile
+++ b/purgatory/Makefile
@@ -12,10 +12,12 @@ PURGATORY_SRCS =
 PURGATORY_SRCS += purgatory/purgatory.c
 PURGATORY_SRCS += purgatory/printf.c
 PURGATORY_SRCS += purgatory/string.c
+PURGATORY_SRCS += purgatory/time.c
 PURGATORY_MAP = purgatory/purgatory.map
 
 dist += purgatory/Makefile $(PURGATORY_SRCS)				\
-	purgatory/include/purgatory.h purgatory/include/string.h
+	purgatory/include/purgatory.h purgatory/include/string.h	\
+	purgatory/include/time.h
 
 include $(srcdir)/purgatory/arch/alpha/Makefile
 include $(srcdir)/purgatory/arch/arm/Makefile
diff --git a/purgatory/include/time.h b/purgatory/include/time.h
new file mode 100644
index 0000000..5d63423
--- /dev/null
+++ b/purgatory/include/time.h
@@ -0,0 +1,33 @@
+#ifndef TIME_H
+#define TIME_H
+
+typedef long long time64_t;
+
+struct timeout_info {
+	time64_t start; /* Start time in second */
+	time64_t end;   /* Expiration time in second */
+	int timed_out;  /* Fast check flag. Set to 1 on the timeout */
+};
+
+time64_t date2unix(int year, int mon, int day, int hour, int min, int sec);
+int check_timeout(struct timeout_info *toi);
+void init_timeout(struct timeout_info *toi, time64_t left);
+
+/**
+ * Check if the timeout happens, and if so, jump to timed_out label.
+ *
+ * @toi: an instance of struct timeout_info initialized by init_timeout().
+ * @check_clock: if this value is 0, this macro doesn't check the actual
+ *               clock.  This is useful for the exit path after timeout.
+ */
+#define EXIT_ON_TIMEOUT(toi, check_clock)       	\
+do {                                    		\
+	if ((toi)->timed_out)				\
+		goto timed_out;				\
+	if ((check_clock) && check_timeout((toi))) {	\
+		(toi)->timed_out = 1;			\
+		goto timed_out;				\
+	}						\
+} while (0)
+
+#endif /* TIME_H */
diff --git a/purgatory/time.c b/purgatory/time.c
new file mode 100644
index 0000000..2d803f6
--- /dev/null
+++ b/purgatory/time.c
@@ -0,0 +1,59 @@
+#include "time.h"
+
+/* Calculate unix-epoch time based on Julian day number calculation. */
+time64_t date2unix(int year, int mon, int day, int hour, int min, int sec)
+{
+	time64_t days, seconds;
+
+	mon -= 3;
+	if (mon < 0) {
+		year--;
+		mon += 12;
+	}
+
+	/* days since 1970/1/1 (= 0 day) */
+	days = 365*year + year/4 - year/100 + year/400 + (153*mon + 2)/5 +
+		day - 719469;
+
+	seconds = ((days*24 + hour)*60 + min)*60 + sec;
+
+	return seconds;
+}
+
+/*
+ * Dummy for systems which doesn't have clock access implementation.
+ * You need to override this to enable the timeout mechanism.
+ */
+time64_t __attribute__((weak)) get_unix_time(void)
+{
+	/* This means it never times out. */
+	return 0;
+}
+
+/* Retrun 1 if the timeout has happend, otherwise 0. */
+int check_timeout(struct timeout_info *toi)
+{
+	time64_t now;
+
+	if (toi->timed_out)
+		return 1;
+
+	now = get_unix_time();
+	if (toi->end <= now)
+		toi->timed_out = 1;
+
+	return toi->timed_out;
+}
+
+void init_timeout(struct timeout_info *toi, time64_t left)
+{
+	toi->start = get_unix_time();
+
+	/*
+	 * The precision of RTC is one second.  To wait at least specified
+	 * seconds, we do +1.
+	 */
+	toi->end = toi->start + left + 1;
+
+	toi->timed_out = 0;
+}



_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

  reply	other threads:[~2016-02-22 12:01 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-22 11:56 [RFC v2 PATCH 0/7] purgatory: Say last words in kexec on panic case Hidehiro Kawai
2016-02-22 11:56 ` Hidehiro Kawai [this message]
2016-02-22 11:56 ` [RFC v2 PATCH 2/7] purgatory/x86: Support CMOS RTC Hidehiro Kawai
2016-02-22 11:56 ` [RFC v2 PATCH 3/7] purgatory/ipmi: Support IPMI KCS interface Hidehiro Kawai
2016-02-22 11:56 ` [RFC v2 PATCH 4/7] purgatory/ipmi: Support BMC watchdog timer start/stop in purgatory Hidehiro Kawai
2016-02-22 11:56 ` [RFC v2 PATCH 5/7] purgatory/ipmi: Add an option for purgatory to handle panic event with IPMI Hidehiro Kawai
2016-02-22 11:56 ` [RFC v2 PATCH 6/7] purgatory/x86: Add an option to output IP registers to console in panic case Hidehiro Kawai
2016-02-22 11:56 ` [RFC v2 PATCH 7/7] purgatory/ipmi/x86: Support logging of IP registers into SEL Hidehiro Kawai
2016-02-29  4:35 ` [RFC v2 PATCH 0/7] purgatory: Say last words in kexec on panic case 河合英宏 / KAWAI,HIDEHIRO

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160222115619.4231.6469.stgit@softrs \
    --to=hidehiro.kawai.ez@hitachi.com \
    --cc=ebiederm@xmission.com \
    --cc=horms@verge.net.au \
    --cc=kexec@lists.infradead.org \
    --cc=minyard@acm.org \
    --cc=vgoyal@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox