All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Mateusz Jończyk" <mat.jonczyk@o2.pl>
To: linux-kernel@vger.kernel.org, linux-rtc@vger.kernel.org,
	linux-kselftest@vger.kernel.org
Cc: "Mateusz Jończyk" <mat.jonczyk@o2.pl>,
	"Alessandro Zummo" <a.zummo@towertech.it>,
	"Alexandre Belloni" <alexandre.belloni@bootlin.com>,
	"Shuah Khan" <shuah@kernel.org>
Subject: [PATCH 2/2] [RFC] selftests/rtc: read RTC alarm time many times in a row
Date: Thu, 31 Mar 2022 21:06:12 +0200	[thread overview]
Message-ID: <20220331190612.22162-2-mat.jonczyk@o2.pl> (raw)
In-Reply-To: <20220331190612.22162-1-mat.jonczyk@o2.pl>

This is the userspace part of the test unit.

This patch depends on
commit 2aaa36e95ea5 ("selftests/rtc: continuously read RTC in a loop for 30s")

Existing code casts "struct rtc_time *" to "struct tm *", like so:

	gmtime_r(&secs, (struct tm *)&tm);

This is incorrect, because sizeof(struct tm) > sizeof(struct rtc_time)
(on Ubuntu 20.04 at least) and gmtime_r overwrites part of the stack.
I'll submit a fix for this in mainline soon, but for now I'm defining
timestamp_to_rtc_time() here.

TODO:
- some logic improvements, without much impact on the core algorithm.

Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Shuah Khan <shuah@kernel.org>
---
 tools/testing/selftests/rtc/rtctest.c | 81 ++++++++++++++++++++++++++-
 tools/testing/selftests/rtc/settings  |  2 +-
 2 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/rtc/rtctest.c b/tools/testing/selftests/rtc/rtctest.c
index 2b9d929a24ed..7e5f2f1c00ef 100644
--- a/tools/testing/selftests/rtc/rtctest.c
+++ b/tools/testing/selftests/rtc/rtctest.c
@@ -62,7 +62,21 @@ static time_t rtc_time_to_timestamp(struct rtc_time *rtc_time)
 	       .tm_year = rtc_time->tm_year,
 	};
 
-	return mktime(&tm_time);
+	return timegm(&tm_time);
+}
+
+static void timestamp_to_rtc_time(time_t timestamp, struct rtc_time *rtc_time)
+{
+	struct tm tm_time;
+
+	gmtime_r(&timestamp, &tm_time);
+
+	rtc_time->tm_sec = tm_time.tm_sec;
+	rtc_time->tm_min = tm_time.tm_min;
+	rtc_time->tm_hour = tm_time.tm_hour;
+	rtc_time->tm_mday = tm_time.tm_mday;
+	rtc_time->tm_mon = tm_time.tm_mon;
+	rtc_time->tm_year = tm_time.tm_year;
 }
 
 static void nanosleep_with_retries(long ns)
@@ -228,6 +242,71 @@ TEST_F(rtc, alarm_alm_set) {
 	ASSERT_EQ(new, secs);
 }
 
+TEST_F_TIMEOUT(rtc, alarm_read_loop, READ_LOOP_DURATION_SEC + 2) {
+	int rc;
+	long iter_count = 0;
+	struct rtc_time tm;
+	struct timeval start, curr;
+	time_t secs;
+
+	rc = ioctl(self->fd, RTC_RD_TIME, &tm);
+	ASSERT_NE(-1, rc);
+
+	// 60s is for clocks that only support minute resolution of RTC alarm
+	secs = rtc_time_to_timestamp(&tm) + READ_LOOP_DURATION_SEC + 60 + 2;
+	timestamp_to_rtc_time(secs, &tm);
+
+	rc = ioctl(self->fd, RTC_ALM_SET, &tm);
+	if (rc == -1) {
+		ASSERT_EQ(EINVAL, errno);
+		TH_LOG("skip alarms are not supported.");
+		return;
+	}
+
+	rc = ioctl(self->fd, RTC_AIE_ON, NULL);
+	ASSERT_NE(-1, rc);
+
+	TH_LOG("Continuously reading RTC alarm time for %ds (with %dms breaks after every read).",
+	       READ_LOOP_DURATION_SEC, READ_LOOP_SLEEP_MS);
+
+	gettimeofday(&start, NULL);
+
+	secs = 0;
+
+	do {
+		// TODO: use appropriate directory
+		// TODO: fail gracefully if the kernel support does not exist
+		FILE *wkalarm_file = fopen("/sys/kernel/debug/rtc/rtc0/wakealarm_raw", "r");
+		long long wkalarm_time;
+
+		ASSERT_NE(wkalarm_file, NULL);
+
+		rc = fscanf(wkalarm_file, "%lld", &wkalarm_time);
+		fclose(wkalarm_file);
+
+		ASSERT_EQ(rc, 1);
+		ASSERT_NE(secs, -1);
+		// TODO: use another value as placeholder,
+		// TODO: check if wkalarm_time matches alarm time we set
+		// previously
+		if (secs == 0)
+			secs = wkalarm_time;
+
+		ASSERT_EQ(wkalarm_time, secs);
+
+		// Sleep 11ms to avoid killing / overheating the RTC
+		nanosleep_with_retries(READ_LOOP_SLEEP_MS * 1000000);
+
+		gettimeofday(&curr, NULL);
+		iter_count++;
+	} while (curr.tv_sec <= start.tv_sec + READ_LOOP_DURATION_SEC);
+
+	TH_LOG("Performed %ld RTC alarm time reads.", iter_count);
+
+	rc = ioctl(self->fd, RTC_AIE_OFF, NULL);
+	ASSERT_NE(-1, rc);
+}
+
 TEST_F(rtc, alarm_wkalm_set) {
 	struct timeval tv = { .tv_sec = ALARM_DELTA + 2 };
 	struct rtc_wkalrm alarm = { 0 };
diff --git a/tools/testing/selftests/rtc/settings b/tools/testing/selftests/rtc/settings
index 0c1a2075d5f3..b478e684846a 100644
--- a/tools/testing/selftests/rtc/settings
+++ b/tools/testing/selftests/rtc/settings
@@ -1 +1 @@
-timeout=210
+timeout=240
-- 
2.25.1


  reply	other threads:[~2022-03-31 19:13 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-31 19:06 [PATCH 1/2] [RFC] rtc: expose direct access to hardware alarm time in debugfs Mateusz Jończyk
2022-03-31 19:06 ` Mateusz Jończyk [this message]
2022-03-31 19:21 ` Greg KH
2022-03-31 19:43   ` Mateusz Jończyk
2022-03-31 19:36 ` Alexandre Belloni
2022-03-31 19:52   ` Mateusz Jończyk
2022-03-31 20:59     ` Alexandre Belloni

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=20220331190612.22162-2-mat.jonczyk@o2.pl \
    --to=mat.jonczyk@o2.pl \
    --cc=a.zummo@towertech.it \
    --cc=alexandre.belloni@bootlin.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-rtc@vger.kernel.org \
    --cc=shuah@kernel.org \
    /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 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.