All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH 0/3] add rtctime libs and rtc02 case
@ 2020-12-23  3:35 gengcixi
  2020-12-23  3:35 ` [LTP] [PATCH 1/3] lib: add tst_rtctime* for rtc test gengcixi
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: gengcixi @ 2020-12-23  3:35 UTC (permalink / raw)
  To: ltp

From: Cixi Geng <cixi.geng1@unisoc.com>

This file is a implementation for rtc test function
in tst_rtctime lib, support tst_rtc_gettime and tst_rtc_settime;
at the same file, also add rtctime and time_t convert functions.
in tst_wallclock.s, add tst_rtc_save and tst_rtc_restore for testcase
used in SETUP and CLEANUP.

the rtc02 testcase is verify set rtctime a exact timestamp.

Cixi Geng (3):
  lib: add tst_rtctime* for rtc test
  lib: implement rtctime_save and rtctime_restore function
  rtc02: add rtc set time verify case

 include/tst_rtctime.h                         |  15 ++
 include/tst_wallclock.h                       |   4 +
 lib/tst_rtctime.c                             | 161 ++++++++++++++++++
 lib/tst_wallclock.c                           |  42 +++++
 runtest/kernel_misc                           |   1 +
 .../kernel/device-drivers/rtc/.gitignore      |   1 +
 testcases/kernel/device-drivers/rtc/rtc02.c   | 108 ++++++++++++
 7 files changed, 332 insertions(+)
 create mode 100644 include/tst_rtctime.h
 create mode 100644 lib/tst_rtctime.c
 create mode 100644 testcases/kernel/device-drivers/rtc/rtc02.c

-- 
2.25.1


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

* [LTP] [PATCH 1/3] lib: add tst_rtctime* for rtc test
  2020-12-23  3:35 [LTP] [PATCH 0/3] add rtctime libs and rtc02 case gengcixi
@ 2020-12-23  3:35 ` gengcixi
  2021-01-07 13:50   ` Cyril Hrubis
  2020-12-23  3:35 ` [LTP] [PATCH 2/3] lib: implement rtctime_save and rtctime_restore function gengcixi
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: gengcixi @ 2020-12-23  3:35 UTC (permalink / raw)
  To: ltp

From: Cixi Geng <cixi.geng1@unisoc.com>

Add:
    get rtc time and set rtc time in default /dev/rtc;
    Implemented a function that covert rtc time to time_t
    this will be used in tst_rtc_save and tst_rtc_restore

Signed-off-by: Cixi Geng <cixi.geng1@unisoc.com>
---
 include/tst_rtctime.h |  15 ++++
 lib/tst_rtctime.c     | 161 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 176 insertions(+)
 create mode 100644 include/tst_rtctime.h
 create mode 100644 lib/tst_rtctime.c

diff --git a/include/tst_rtctime.h b/include/tst_rtctime.h
new file mode 100644
index 000000000..61ec6f0eb
--- /dev/null
+++ b/include/tst_rtctime.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 Unisoc Inc.
+ */
+
+#ifndef TST_RTCTIME
+#define TST_RTCTIME
+
+#include <linux/rtc.h>
+
+int tst_rtc_gettime(struct rtc_time *rtc_tm);
+
+int tst_rtc_settime(struct rtc_time *rtc_tm);
+
+#endif /* TST_RTCTIME */
diff --git a/lib/tst_rtctime.c b/lib/tst_rtctime.c
new file mode 100644
index 000000000..580ef0fdf
--- /dev/null
+++ b/lib/tst_rtctime.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Unisoc Communications Inc.
+ *
+ * Filename : tst_rtctime.c
+ * Abstract : This file is a implementation for rtc set read,covert to tm functions
+ */
+
+#include <linux/rtc.h>
+#include <stdbool.h>
+#include <limits.h>
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+#include "tst_rtctime.h"
+
+#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
+
+static const unsigned char rtc_days_in_month[] = {
+	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+static inline bool is_leap_year(unsigned int year)
+{
+	return (!(year % 4) && (year % 100)) || !(year % 400);
+}
+
+static long long tst_mktime(const unsigned int year0, const unsigned int mon0,
+		const unsigned int day, const unsigned int hour,
+		const unsigned int min, const unsigned int sec)
+{
+	unsigned int mon = mon0, year = year0;
+
+	/* 1..12 -> 11,12,1..10 */
+	mon -= 2;
+	if (0 >= (int) (mon)) {
+		mon += 12;	/* Puts Feb last since it has leap day */
+		year -= 1;
+	}
+
+	return ((((long long)
+		(year/4 - year/100 + year/400 + 367*mon/12 + day) +
+		year*365 - 719499
+		)*24 + hour /* now have hours - midnight tomorrow handled here */
+		)*60 + min /* now have minutes */
+		)*60 + sec; /* finally seconds */
+}
+
+/*
+ * The number of days in the month.
+ */
+static int rtc_month_days(unsigned int month, unsigned int year)
+{
+	return rtc_days_in_month[month] + (is_leap_year(year) && month == 1);
+}
+
+/*
+ * tst_rtc_time_to_tm - Converts time_t to rtc_time.
+ * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
+ */
+void tst_rtc_time_to_tm(long long time, struct rtc_time *tm)
+{
+	unsigned int month, year, secs;
+	int days;
+
+	/* time must be positive */
+	days = time / 86400;
+	secs = time % 86400;
+
+	/* day of the week, 1970-01-01 was a Thursday */
+	tm->tm_wday = (days + 4) % 7;
+
+	year = 1970 + days / 365;
+	days -= (year - 1970) * 365
+		+ LEAPS_THRU_END_OF(year - 1)
+		- LEAPS_THRU_END_OF(1970 - 1);
+	while (days < 0) {
+		year -= 1;
+		days += 365 + is_leap_year(year);
+	}
+	tm->tm_year = year - 1900;
+	tm->tm_yday = days + 1;
+
+	for (month = 0; month < 11; month++) {
+		int newdays;
+
+		newdays = days - rtc_month_days(month, year);
+		if (newdays < 0)
+			break;
+		days = newdays;
+	}
+	tm->tm_mon = month;
+	tm->tm_mday = days + 1;
+
+	tm->tm_hour = secs / 3600;
+	secs -= tm->tm_hour * 3600;
+	tm->tm_min = secs / 60;
+	tm->tm_sec = secs - tm->tm_min * 60;
+
+	tm->tm_isdst = 0;
+}
+
+/*
+ * tst_rtc_tm_to_time - Converts rtc_time to time_t.
+ * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
+ */
+long long tst_rtc_tm_to_time(struct rtc_time *tm)
+{
+	return tst_mktime(((unsigned int)tm->tm_year + 1900), tm->tm_mon + 1,
+			tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+}
+
+static int rtc_supported_by_kernel(const char *rtc_dev)
+{
+	int exists = access(rtc_dev, F_OK);
+
+	if (exists < 0)
+		tst_brk(TCONF, "RTC device %s not available", rtc_dev);
+	return 0;
+}
+
+static int tst_rtc_ioctl(unsigned long request, struct rtc_time *rtc_tm)
+{
+	int ret;
+	int rtc_fd = -1;
+	static const char *rtc_dev = "/dev/rtc";
+
+	if (!rtc_supported_by_kernel(rtc_dev))
+		rtc_fd = SAFE_OPEN(rtc_dev, O_RDONLY);
+
+	ret = ioctl(rtc_fd, request, rtc_tm);
+
+	if (ret != 0)
+		return -1;
+
+	if (rtc_fd > 0)
+		SAFE_CLOSE(rtc_fd);
+
+	return 0;
+}
+
+int tst_rtc_gettime(struct rtc_time *rtc_tm)
+{
+	int ret;
+
+	ret = tst_rtc_ioctl(RTC_RD_TIME, rtc_tm);
+
+	if (ret != 0)
+		return -1;
+	return 0;
+}
+
+int tst_rtc_settime(struct rtc_time *rtc_tm)
+{
+	int ret;
+
+	ret = tst_rtc_ioctl(RTC_SET_TIME, rtc_tm);
+
+	if (ret != 0)
+		return -1;
+	return 0;
+}
-- 
2.25.1


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

* [LTP] [PATCH 2/3] lib: implement rtctime_save and rtctime_restore function
  2020-12-23  3:35 [LTP] [PATCH 0/3] add rtctime libs and rtc02 case gengcixi
  2020-12-23  3:35 ` [LTP] [PATCH 1/3] lib: add tst_rtctime* for rtc test gengcixi
@ 2020-12-23  3:35 ` gengcixi
  2021-01-07 13:57   ` Cyril Hrubis
  2020-12-23  3:35 ` [LTP] [PATCH 3/3] rtc02: add rtc set time verify case gengcixi
  2021-01-07 14:33 ` [LTP] [PATCH 0/3] add rtctime libs and rtc02 case Cyril Hrubis
  3 siblings, 1 reply; 12+ messages in thread
From: gengcixi @ 2020-12-23  3:35 UTC (permalink / raw)
  To: ltp

From: Cixi Geng <cixi.geng1@unisoc.com>

* Reading the RTC in the setup as well as timestamping with monotonic
  timer
* Getting a second monotonic timestamp in the cleanup
* Setting the RTC to the value taken in setup plus the difference in
  the monotonic timer timestamps

Signed-off-by: Cixi Geng <cixi.geng1@unisoc.com>
---
 include/tst_wallclock.h |  4 ++++
 lib/tst_wallclock.c     | 42 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/include/tst_wallclock.h b/include/tst_wallclock.h
index 7d6723a7a..5103c8321 100644
--- a/include/tst_wallclock.h
+++ b/include/tst_wallclock.h
@@ -12,4 +12,8 @@ void tst_wallclock_save(void);
 
 void tst_wallclock_restore(void);
 
+void tst_rtctime_save(void);
+
+void tst_rtctime_restore(void);
+
 #endif	/* TST_WALLCLK_H__ */
diff --git a/lib/tst_wallclock.c b/lib/tst_wallclock.c
index 282d6ada3..5be1f46d8 100644
--- a/lib/tst_wallclock.c
+++ b/lib/tst_wallclock.c
@@ -11,11 +11,14 @@
 #include "tst_test.h"
 #include "tst_timer.h"
 #include "tst_clocks.h"
+#include "tst_rtctime.h"
 #include "tst_wallclock.h"
 #include "lapi/posix_clocks.h"
 
 static struct timespec real_begin, mono_begin;
 
+static struct rtc_time rtc_begin;
+
 static int clock_saved;
 
 void tst_wallclock_save(void)
@@ -58,3 +61,42 @@ void tst_wallclock_restore(void)
 	if (tst_clock_settime(CLOCK_REALTIME, &adjust))
 		tst_brk(TBROK | TERRNO, "tst_clock_settime() realtime failed");
 }
+
+void tst_rtctime_save(void)
+{
+	/* save initial monotonic time to restore it when needed */
+	if (tst_rtc_gettime(&rtc_begin))
+		tst_brk(TBROK | TERRNO, "tst_rtc_gettime() realtime failed");
+
+	if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_begin))
+		tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
+
+	clock_saved = 1;
+}
+
+void tst_rtctime_restore(void)
+{
+	static struct timespec mono_end, elapsed;
+	static struct timespec rtc_begin_tm, rtc_adjust;
+	static struct rtc_time rtc_restore;
+
+	if (!clock_saved)
+		return;
+
+	clock_saved = 0;
+
+	if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end))
+		tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
+
+	elapsed = tst_timespec_diff(mono_end, mono_begin);
+
+	rtc_begin_tm.tv_sec = tst_rtc_tm_to_time(&rtc_begin);
+
+	rtc_adjust = tst_timespec_add(rtc_begin_tm, elapsed);
+
+	tst_rtc_time_to_tm(rtc_adjust.tv_sec, &rtc_restore);
+
+	/* restore realtime clock based on monotonic delta */
+	if (tst_rtc_settime(&rtc_restore))
+		tst_brk(TBROK | TERRNO, "tst_rtc_settime() realtime failed");
+}
-- 
2.25.1


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

* [LTP] [PATCH 3/3] rtc02: add rtc set time verify case
  2020-12-23  3:35 [LTP] [PATCH 0/3] add rtctime libs and rtc02 case gengcixi
  2020-12-23  3:35 ` [LTP] [PATCH 1/3] lib: add tst_rtctime* for rtc test gengcixi
  2020-12-23  3:35 ` [LTP] [PATCH 2/3] lib: implement rtctime_save and rtctime_restore function gengcixi
@ 2020-12-23  3:35 ` gengcixi
  2021-01-07 14:32   ` Cyril Hrubis
  2021-01-07 14:33 ` [LTP] [PATCH 0/3] add rtctime libs and rtc02 case Cyril Hrubis
  3 siblings, 1 reply; 12+ messages in thread
From: gengcixi @ 2020-12-23  3:35 UTC (permalink / raw)
  To: ltp

From: Cixi Geng <cixi.geng1@unisoc.com>

Test for the Real Time Clock driver.
 * Veirify that,
 * 1) set a RTC time
 * 2) read the RTC time after set RTC time at once
 * 3) compare the set time and the read is identical

Signed-off-by: Cixi Geng <cixi.geng1@unisoc.com>
---
 runtest/kernel_misc                           |   1 +
 .../kernel/device-drivers/rtc/.gitignore      |   1 +
 testcases/kernel/device-drivers/rtc/rtc02.c   | 108 ++++++++++++++++++
 3 files changed, 110 insertions(+)
 create mode 100644 testcases/kernel/device-drivers/rtc/rtc02.c

diff --git a/runtest/kernel_misc b/runtest/kernel_misc
index 7937c7bbf..abb75ebaf 100644
--- a/runtest/kernel_misc
+++ b/runtest/kernel_misc
@@ -1,6 +1,7 @@
 kmsg01 kmsg01
 fw_load fw_load
 rtc01 rtc01
+rtc02 rtc02
 block_dev block_dev
 tpci tpci
 tbio tbio
diff --git a/testcases/kernel/device-drivers/rtc/.gitignore b/testcases/kernel/device-drivers/rtc/.gitignore
index 8412fe679..0c0161eba 100644
--- a/testcases/kernel/device-drivers/rtc/.gitignore
+++ b/testcases/kernel/device-drivers/rtc/.gitignore
@@ -1 +1,2 @@
 /rtc01
+/rtc02
diff --git a/testcases/kernel/device-drivers/rtc/rtc02.c b/testcases/kernel/device-drivers/rtc/rtc02.c
new file mode 100644
index 000000000..cb8f7fea0
--- /dev/null
+++ b/testcases/kernel/device-drivers/rtc/rtc02.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Unisoc Communications Inc.
+ *
+ * Filename : rtc02.c
+ * Abstract : This file is a implementation test rtc set function.
+ */
+
+/*
+ * Test description
+ *
+ * Test for the Real Time Clock driver.
+ * Veirify that,
+ * 1) set a RTC time
+ * 2) read the RTC time after set RTC time at once
+ * 3) compare the set time and the read is identical
+ *
+ */
+
+#include "tst_rtctime.h"
+#include "tst_wallclock.h"
+#include "tst_test.h"
+
+static struct rtc_time show_tm;
+
+static char *tst_show_rtctime(struct rtc_time *tm)
+{
+	static char rtctime_buf[20];
+
+	sprintf(rtctime_buf, "%04d-%02d-%02d %02d:%02d:%02d",
+		tm->tm_year + 1900,
+		tm->tm_mon + 1,
+		tm->tm_mday,
+		tm->tm_hour,
+		tm->tm_min,
+		tm->tm_sec);
+	return rtctime_buf;
+}
+
+static void rtc_setup(void)
+{
+	tst_rtctime_save();
+}
+
+static int rtc_tm_cmp(struct rtc_time *set_tm, struct rtc_time *read_tm)
+{
+	if ((set_tm->tm_sec == read_tm->tm_sec)
+		&& (set_tm->tm_min == read_tm->tm_min)
+		&& (set_tm->tm_hour == read_tm->tm_hour)
+		&& (set_tm->tm_mday == read_tm->tm_mday)
+		&& (set_tm->tm_mon == read_tm->tm_mon)
+		&& (set_tm->tm_year == read_tm->tm_year)) {
+		return 0;
+	}
+	return -1;
+}
+
+static void set_rtc_test(void)
+{
+	struct rtc_time read_tm;
+	int ret;
+
+	struct rtc_time set_tm = {
+		.tm_sec = 30,
+		.tm_min = 23,
+		.tm_hour = 13,
+		.tm_mday = 9,
+		.tm_mon = 9,
+		.tm_year = 120,
+	};
+
+	/* set rtc to 2020.10.9 13:23:30 */
+	tst_res(TINFO, "To set RTC date/time is: %s", tst_show_rtctime(&set_tm));
+
+	ret = tst_rtc_settime(&set_tm);
+	if (ret != 0) {
+		tst_res(TFAIL | TERRNO, "RTC_SET_TIME failed");
+		return;
+	}
+
+	/* Read current RTC Time */
+	ret = tst_rtc_gettime(&read_tm);
+	if (ret != 0) {
+		tst_res(TFAIL | TERRNO, "RTC_RD_TIME failed");
+		return;
+	}
+	tst_res(TINFO, "read RTC date/time is: %s", tst_show_rtctime(&read_tm));
+
+	if (rtc_tm_cmp(&set_tm, &read_tm)) {
+		tst_res(TFAIL | TERRNO, "RTC SET TEST Failed");
+		return;
+	}
+	tst_res(TPASS, "The read RTC time is consistent with set");
+
+}
+
+static void rtc_cleanup(void)
+{
+	tst_rtctime_restore();
+}
+
+static struct tst_test test = {
+	.setup = rtc_setup,
+	.test_all = set_rtc_test,
+	.cleanup = rtc_cleanup,
+	/* tests needs to run with UID=0 */
+	.needs_root = 1,
+};
-- 
2.25.1


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

* [LTP] [PATCH 1/3] lib: add tst_rtctime* for rtc test
  2020-12-23  3:35 ` [LTP] [PATCH 1/3] lib: add tst_rtctime* for rtc test gengcixi
@ 2021-01-07 13:50   ` Cyril Hrubis
  2021-01-08  8:30     ` Cixi Geng
  0 siblings, 1 reply; 12+ messages in thread
From: Cyril Hrubis @ 2021-01-07 13:50 UTC (permalink / raw)
  To: ltp

Hi!
>     get rtc time and set rtc time in default /dev/rtc;
>     Implemented a function that covert rtc time to time_t
>     this will be used in tst_rtc_save and tst_rtc_restore
> 
> Signed-off-by: Cixi Geng <cixi.geng1@unisoc.com>
> ---
>  include/tst_rtctime.h |  15 ++++
>  lib/tst_rtctime.c     | 161 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 176 insertions(+)
>  create mode 100644 include/tst_rtctime.h
>  create mode 100644 lib/tst_rtctime.c
> 
> diff --git a/include/tst_rtctime.h b/include/tst_rtctime.h
> new file mode 100644
> index 000000000..61ec6f0eb
> --- /dev/null
> +++ b/include/tst_rtctime.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 */

This is not correct format for the identifiers, the comment has to start
with //

Also the default license for new LTP code i GPL-2.0-or-later, so please
us that unless you have a reason to stick to GPL-2.0.

> +/*
> + * Copyright (C) 2020 Unisoc Inc.
> + */
> +
> +#ifndef TST_RTCTIME
> +#define TST_RTCTIME
> +
> +#include <linux/rtc.h>
> +
> +int tst_rtc_gettime(struct rtc_time *rtc_tm);
> +
> +int tst_rtc_settime(struct rtc_time *rtc_tm);

Should we add a path to the RTC device to these functions as well?

Are there any boards that have more than one RTC where we would need to
loop over all available devices during the test?

> +#endif /* TST_RTCTIME */
> diff --git a/lib/tst_rtctime.c b/lib/tst_rtctime.c
> new file mode 100644
> index 000000000..580ef0fdf
> --- /dev/null
> +++ b/lib/tst_rtctime.c
> @@ -0,0 +1,161 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Unisoc Communications Inc.
> + *
> + * Filename : tst_rtctime.c
> + * Abstract : This file is a implementation for rtc set read,covert to tm functions
> + */
> +
> +#include <linux/rtc.h>
> +#include <stdbool.h>
> +#include <limits.h>
> +#define TST_NO_DEFAULT_MAIN
> +#include "tst_test.h"
> +#include "tst_rtctime.h"
> +
> +#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
> +
> +static const unsigned char rtc_days_in_month[] = {
> +	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
> +};
> +
> +static inline bool is_leap_year(unsigned int year)
> +{
> +	return (!(year % 4) && (year % 100)) || !(year % 400);
> +}
> +
> +static long long tst_mktime(const unsigned int year0, const unsigned int mon0,
> +		const unsigned int day, const unsigned int hour,
> +		const unsigned int min, const unsigned int sec)
> +{
> +	unsigned int mon = mon0, year = year0;
> +
> +	/* 1..12 -> 11,12,1..10 */
> +	mon -= 2;
> +	if (0 >= (int) (mon)) {
> +		mon += 12;	/* Puts Feb last since it has leap day */
> +		year -= 1;
> +	}
> +
> +	return ((((long long)
> +		(year/4 - year/100 + year/400 + 367*mon/12 + day) +
> +		year*365 - 719499
> +		)*24 + hour /* now have hours - midnight tomorrow handled here */
> +		)*60 + min /* now have minutes */
> +		)*60 + sec; /* finally seconds */
> +}
> +
> +/*
> + * The number of days in the month.
> + */
> +static int rtc_month_days(unsigned int month, unsigned int year)
> +{
> +	return rtc_days_in_month[month] + (is_leap_year(year) && month == 1);
> +}
> +
> +/*
> + * tst_rtc_time_to_tm - Converts time_t to rtc_time.
> + * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
> + */
> +void tst_rtc_time_to_tm(long long time, struct rtc_time *tm)
> +{
> +	unsigned int month, year, secs;
> +	int days;
> +
> +	/* time must be positive */
> +	days = time / 86400;
> +	secs = time % 86400;
> +
> +	/* day of the week, 1970-01-01 was a Thursday */
> +	tm->tm_wday = (days + 4) % 7;
> +
> +	year = 1970 + days / 365;
> +	days -= (year - 1970) * 365
> +		+ LEAPS_THRU_END_OF(year - 1)
> +		- LEAPS_THRU_END_OF(1970 - 1);
> +	while (days < 0) {
> +		year -= 1;
> +		days += 365 + is_leap_year(year);
> +	}
> +	tm->tm_year = year - 1900;
> +	tm->tm_yday = days + 1;
> +
> +	for (month = 0; month < 11; month++) {
> +		int newdays;
> +
> +		newdays = days - rtc_month_days(month, year);
> +		if (newdays < 0)
> +			break;
> +		days = newdays;
> +	}
> +	tm->tm_mon = month;
> +	tm->tm_mday = days + 1;
> +
> +	tm->tm_hour = secs / 3600;
> +	secs -= tm->tm_hour * 3600;
> +	tm->tm_min = secs / 60;
> +	tm->tm_sec = secs - tm->tm_min * 60;
> +
> +	tm->tm_isdst = 0;
> +}
> +
> +/*
> + * tst_rtc_tm_to_time - Converts rtc_time to time_t.
> + * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
> + */
> +long long tst_rtc_tm_to_time(struct rtc_time *tm)
> +{
> +	return tst_mktime(((unsigned int)tm->tm_year + 1900), tm->tm_mon + 1,
> +			tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);

So I guess that the reason why we can't use libc mktime() and gmtime_r()
is that time_t is 32bit on older 32bit architectures, right?

> +}
> +
> +static int rtc_supported_by_kernel(const char *rtc_dev)
> +{
> +	int exists = access(rtc_dev, F_OK);
> +
> +	if (exists < 0)
> +		tst_brk(TCONF, "RTC device %s not available", rtc_dev);
> +	return 0;
> +}

This function should be called by the tests rather than from the test
library.

> +static int tst_rtc_ioctl(unsigned long request, struct rtc_time *rtc_tm)
> +{
> +	int ret;
> +	int rtc_fd = -1;
> +	static const char *rtc_dev = "/dev/rtc";
> +
> +	if (!rtc_supported_by_kernel(rtc_dev))
> +		rtc_fd = SAFE_OPEN(rtc_dev, O_RDONLY);
> +
> +	ret = ioctl(rtc_fd, request, rtc_tm);
> +
> +	if (ret != 0)
> +		return -1;
> +
> +	if (rtc_fd > 0)
> +		SAFE_CLOSE(rtc_fd);
> +
> +	return 0;
> +}
> +
> +int tst_rtc_gettime(struct rtc_time *rtc_tm)
> +{
> +	int ret;
> +
> +	ret = tst_rtc_ioctl(RTC_RD_TIME, rtc_tm);
> +
> +	if (ret != 0)
> +		return -1;
> +	return 0;
> +}
> +
> +int tst_rtc_settime(struct rtc_time *rtc_tm)
> +{
> +	int ret;
> +
> +	ret = tst_rtc_ioctl(RTC_SET_TIME, rtc_tm);
> +
> +	if (ret != 0)
> +		return -1;
> +	return 0;
> +}

These two functions can be static inline and declared in the header as:


static inline int tst_rtc_settime(struct rtc_time *rtc_tm)
{
	return tst_rtc_ioctl(RTC_SET_TIME, rtc_tm);
}

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH 2/3] lib: implement rtctime_save and rtctime_restore function
  2020-12-23  3:35 ` [LTP] [PATCH 2/3] lib: implement rtctime_save and rtctime_restore function gengcixi
@ 2021-01-07 13:57   ` Cyril Hrubis
  2021-01-08  9:19     ` Cixi Geng
  0 siblings, 1 reply; 12+ messages in thread
From: Cyril Hrubis @ 2021-01-07 13:57 UTC (permalink / raw)
  To: ltp

>  static struct timespec real_begin, mono_begin;
>  
> +static struct rtc_time rtc_begin;
> +
>  static int clock_saved;
>  
>  void tst_wallclock_save(void)
> @@ -58,3 +61,42 @@ void tst_wallclock_restore(void)
>  	if (tst_clock_settime(CLOCK_REALTIME, &adjust))
>  		tst_brk(TBROK | TERRNO, "tst_clock_settime() realtime failed");
>  }
> +
> +void tst_rtctime_save(void)
> +{
> +	/* save initial monotonic time to restore it when needed */
> +	if (tst_rtc_gettime(&rtc_begin))
> +		tst_brk(TBROK | TERRNO, "tst_rtc_gettime() realtime failed");
> +
> +	if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_begin))
> +		tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
> +
> +	clock_saved = 1;

It would be better if we defined rtc_clock_saved for the rtc* functions
instead.

> +}
> +
> +void tst_rtctime_restore(void)
> +{
> +	static struct timespec mono_end, elapsed;
> +	static struct timespec rtc_begin_tm, rtc_adjust;
> +	static struct rtc_time rtc_restore;
> +
> +	if (!clock_saved)
> +		return;
> +
> +	clock_saved = 0;
> +
> +	if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end))
> +		tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
> +
> +	elapsed = tst_timespec_diff(mono_end, mono_begin);
> +
> +	rtc_begin_tm.tv_sec = tst_rtc_tm_to_time(&rtc_begin);

We should clear the tv_nsec here otherwise it will contain garbage.

> +	rtc_adjust = tst_timespec_add(rtc_begin_tm, elapsed);
> +
> +	tst_rtc_time_to_tm(rtc_adjust.tv_sec, &rtc_restore);
> +
> +	/* restore realtime clock based on monotonic delta */
> +	if (tst_rtc_settime(&rtc_restore))
> +		tst_brk(TBROK | TERRNO, "tst_rtc_settime() realtime failed");
> +}

Other than this, it looks good.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH 3/3] rtc02: add rtc set time verify case
  2020-12-23  3:35 ` [LTP] [PATCH 3/3] rtc02: add rtc set time verify case gengcixi
@ 2021-01-07 14:32   ` Cyril Hrubis
  0 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2021-01-07 14:32 UTC (permalink / raw)
  To: ltp

Hi!
> Test for the Real Time Clock driver.
>  * Veirify that,
>  * 1) set a RTC time
>  * 2) read the RTC time after set RTC time at once
>  * 3) compare the set time and the read is identical
> 
> Signed-off-by: Cixi Geng <cixi.geng1@unisoc.com>
> ---
>  runtest/kernel_misc                           |   1 +
>  .../kernel/device-drivers/rtc/.gitignore      |   1 +
>  testcases/kernel/device-drivers/rtc/rtc02.c   | 108 ++++++++++++++++++
>  3 files changed, 110 insertions(+)
>  create mode 100644 testcases/kernel/device-drivers/rtc/rtc02.c
> 
> diff --git a/runtest/kernel_misc b/runtest/kernel_misc
> index 7937c7bbf..abb75ebaf 100644
> --- a/runtest/kernel_misc
> +++ b/runtest/kernel_misc
> @@ -1,6 +1,7 @@
>  kmsg01 kmsg01
>  fw_load fw_load
>  rtc01 rtc01
> +rtc02 rtc02
>  block_dev block_dev
>  tpci tpci
>  tbio tbio
> diff --git a/testcases/kernel/device-drivers/rtc/.gitignore b/testcases/kernel/device-drivers/rtc/.gitignore
> index 8412fe679..0c0161eba 100644
> --- a/testcases/kernel/device-drivers/rtc/.gitignore
> +++ b/testcases/kernel/device-drivers/rtc/.gitignore
> @@ -1 +1,2 @@
>  /rtc01
> +/rtc02
> diff --git a/testcases/kernel/device-drivers/rtc/rtc02.c b/testcases/kernel/device-drivers/rtc/rtc02.c
> new file mode 100644
> index 000000000..cb8f7fea0
> --- /dev/null
> +++ b/testcases/kernel/device-drivers/rtc/rtc02.c
> @@ -0,0 +1,108 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Unisoc Communications Inc.
> + *
> + * Filename : rtc02.c

This is pretty much useless information.

> + * Abstract : This file is a implementation test rtc set function.

And this as well as we do have a test description in the separate
comment.

> + */
> +
> +/*
> + * Test description
> + *
> + * Test for the Real Time Clock driver.
> + * Veirify that,
> + * 1) set a RTC time
> + * 2) read the RTC time after set RTC time at once
> + * 3) compare the set time and the read is identical
> + *
> + */

Can you please reformat this into special asciidoc formatted comment so
that it's picked up correctly by the documentation parser?

Have a look for example at top level comment in syscalls/ipc/shmctl/shmctl01.c

> +#include "tst_rtctime.h"
> +#include "tst_wallclock.h"
> +#include "tst_test.h"
> +
> +static struct rtc_time show_tm;
> +
> +static char *tst_show_rtctime(struct rtc_time *tm)

This function should be rather named rtctime_to_str() or something along
these lines, also test functions must not start with tst_ that prefix is
reserved to test library.

> +{
> +	static char rtctime_buf[20];
> +
> +	sprintf(rtctime_buf, "%04d-%02d-%02d %02d:%02d:%02d",
> +		tm->tm_year + 1900,
> +		tm->tm_mon + 1,
> +		tm->tm_mday,
> +		tm->tm_hour,
> +		tm->tm_min,
> +		tm->tm_sec);
> +	return rtctime_buf;
> +}
> +
> +static void rtc_setup(void)
> +{
> +	tst_rtctime_save();
> +}
> +
> +static int rtc_tm_cmp(struct rtc_time *set_tm, struct rtc_time *read_tm)
> +{
> +	if ((set_tm->tm_sec == read_tm->tm_sec)
> +		&& (set_tm->tm_min == read_tm->tm_min)
> +		&& (set_tm->tm_hour == read_tm->tm_hour)
> +		&& (set_tm->tm_mday == read_tm->tm_mday)
> +		&& (set_tm->tm_mon == read_tm->tm_mon)
> +		&& (set_tm->tm_year == read_tm->tm_year)) {
> +		return 0;
> +	}
> +	return -1;

This can be just:

	return !((set_tm->tm_sec == read_tm->tm_sec) &&
	         ...);

> +}
> +
> +static void set_rtc_test(void)
> +{
> +	struct rtc_time read_tm;
> +	int ret;
> +
> +	struct rtc_time set_tm = {
> +		.tm_sec = 30,
> +		.tm_min = 23,
> +		.tm_hour = 13,
> +		.tm_mday = 9,
> +		.tm_mon = 9,
> +		.tm_year = 120,
> +	};
> +
> +	/* set rtc to 2020.10.9 13:23:30 */
> +	tst_res(TINFO, "To set RTC date/time is: %s", tst_show_rtctime(&set_tm));
> +
> +	ret = tst_rtc_settime(&set_tm);
> +	if (ret != 0) {
> +		tst_res(TFAIL | TERRNO, "RTC_SET_TIME failed");
> +		return;
> +	}
> +
> +	/* Read current RTC Time */
> +	ret = tst_rtc_gettime(&read_tm);
> +	if (ret != 0) {
> +		tst_res(TFAIL | TERRNO, "RTC_RD_TIME failed");
> +		return;
> +	}
> +	tst_res(TINFO, "read RTC date/time is: %s", tst_show_rtctime(&read_tm));
> +
> +	if (rtc_tm_cmp(&set_tm, &read_tm)) {
> +		tst_res(TFAIL | TERRNO, "RTC SET TEST Failed");
> +		return;
> +	}
> +	tst_res(TPASS, "The read RTC time is consistent with set");
> +
> +}
> +
> +static void rtc_cleanup(void)
> +{
> +	tst_rtctime_restore();
> +}
> +
> +static struct tst_test test = {
> +	.setup = rtc_setup,
> +	.test_all = set_rtc_test,
> +	.cleanup = rtc_cleanup,
> +	/* tests needs to run with UID=0 */
> +	.needs_root = 1,
> +};
> -- 
> 2.25.1
> 

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH 0/3] add rtctime libs and rtc02 case
  2020-12-23  3:35 [LTP] [PATCH 0/3] add rtctime libs and rtc02 case gengcixi
                   ` (2 preceding siblings ...)
  2020-12-23  3:35 ` [LTP] [PATCH 3/3] rtc02: add rtc set time verify case gengcixi
@ 2021-01-07 14:33 ` Cyril Hrubis
  3 siblings, 0 replies; 12+ messages in thread
From: Cyril Hrubis @ 2021-01-07 14:33 UTC (permalink / raw)
  To: ltp

Hi!
Overall this version looks good, there are a few things that should be
fixed, but it's getting close to a final version.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH 1/3] lib: add tst_rtctime* for rtc test
  2021-01-07 13:50   ` Cyril Hrubis
@ 2021-01-08  8:30     ` Cixi Geng
  0 siblings, 0 replies; 12+ messages in thread
From: Cixi Geng @ 2021-01-08  8:30 UTC (permalink / raw)
  To: ltp

Cyril Hrubis <chrubis@suse.cz> ?2021?1?7??? ??9:49???
>
> Hi!
> >     get rtc time and set rtc time in default /dev/rtc;
> >     Implemented a function that covert rtc time to time_t
> >     this will be used in tst_rtc_save and tst_rtc_restore
> >
> > Signed-off-by: Cixi Geng <cixi.geng1@unisoc.com>
> > ---
> >  include/tst_rtctime.h |  15 ++++
> >  lib/tst_rtctime.c     | 161 ++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 176 insertions(+)
> >  create mode 100644 include/tst_rtctime.h
> >  create mode 100644 lib/tst_rtctime.c
> >
> > diff --git a/include/tst_rtctime.h b/include/tst_rtctime.h
> > new file mode 100644
> > index 000000000..61ec6f0eb
> > --- /dev/null
> > +++ b/include/tst_rtctime.h
> > @@ -0,0 +1,15 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
>
> This is not correct format for the identifiers, the comment has to start
> with //
>
> Also the default license for new LTP code i GPL-2.0-or-later, so please
> us that unless you have a reason to stick to GPL-2.0.
>
> > +/*
> > + * Copyright (C) 2020 Unisoc Inc.
> > + */
> > +
> > +#ifndef TST_RTCTIME
> > +#define TST_RTCTIME
> > +
> > +#include <linux/rtc.h>
> > +
> > +int tst_rtc_gettime(struct rtc_time *rtc_tm);
> > +
> > +int tst_rtc_settime(struct rtc_time *rtc_tm);
>
> Should we add a path to the RTC device to these functions as well?
>
> Are there any boards that have more than one RTC where we would need to
> loop over all available devices during the test?

I test this case in x86_64 and arm64, in these machines? I check the /dev/rtc is
a linked file which link to /dev/rtc0.  so I use the /dev/rtc0 as
default device. but I
wiil take adopt your suggestion, add a device path parameter.
>
> > +#endif /* TST_RTCTIME */
> > diff --git a/lib/tst_rtctime.c b/lib/tst_rtctime.c
> > new file mode 100644
> > index 000000000..580ef0fdf
> > --- /dev/null
> > +++ b/lib/tst_rtctime.c
> > @@ -0,0 +1,161 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2020 Unisoc Communications Inc.
> > + *
> > + * Filename : tst_rtctime.c
> > + * Abstract : This file is a implementation for rtc set read,covert to tm functions
> > + */
> > +
> > +#include <linux/rtc.h>
> > +#include <stdbool.h>
> > +#include <limits.h>
> > +#define TST_NO_DEFAULT_MAIN
> > +#include "tst_test.h"
> > +#include "tst_rtctime.h"
> > +
> > +#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
> > +
> > +static const unsigned char rtc_days_in_month[] = {
> > +     31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
> > +};
> > +
> > +static inline bool is_leap_year(unsigned int year)
> > +{
> > +     return (!(year % 4) && (year % 100)) || !(year % 400);
> > +}
> > +
> > +static long long tst_mktime(const unsigned int year0, const unsigned int mon0,
> > +             const unsigned int day, const unsigned int hour,
> > +             const unsigned int min, const unsigned int sec)
> > +{
> > +     unsigned int mon = mon0, year = year0;
> > +
> > +     /* 1..12 -> 11,12,1..10 */
> > +     mon -= 2;
> > +     if (0 >= (int) (mon)) {
> > +             mon += 12;      /* Puts Feb last since it has leap day */
> > +             year -= 1;
> > +     }
> > +
> > +     return ((((long long)
> > +             (year/4 - year/100 + year/400 + 367*mon/12 + day) +
> > +             year*365 - 719499
> > +             )*24 + hour /* now have hours - midnight tomorrow handled here */
> > +             )*60 + min /* now have minutes */
> > +             )*60 + sec; /* finally seconds */
> > +}
> > +
> > +/*
> > + * The number of days in the month.
> > + */
> > +static int rtc_month_days(unsigned int month, unsigned int year)
> > +{
> > +     return rtc_days_in_month[month] + (is_leap_year(year) && month == 1);
> > +}
> > +
> > +/*
> > + * tst_rtc_time_to_tm - Converts time_t to rtc_time.
> > + * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
> > + */
> > +void tst_rtc_time_to_tm(long long time, struct rtc_time *tm)
> > +{
> > +     unsigned int month, year, secs;
> > +     int days;
> > +
> > +     /* time must be positive */
> > +     days = time / 86400;
> > +     secs = time % 86400;
> > +
> > +     /* day of the week, 1970-01-01 was a Thursday */
> > +     tm->tm_wday = (days + 4) % 7;
> > +
> > +     year = 1970 + days / 365;
> > +     days -= (year - 1970) * 365
> > +             + LEAPS_THRU_END_OF(year - 1)
> > +             - LEAPS_THRU_END_OF(1970 - 1);
> > +     while (days < 0) {
> > +             year -= 1;
> > +             days += 365 + is_leap_year(year);
> > +     }
> > +     tm->tm_year = year - 1900;
> > +     tm->tm_yday = days + 1;
> > +
> > +     for (month = 0; month < 11; month++) {
> > +             int newdays;
> > +
> > +             newdays = days - rtc_month_days(month, year);
> > +             if (newdays < 0)
> > +                     break;
> > +             days = newdays;
> > +     }
> > +     tm->tm_mon = month;
> > +     tm->tm_mday = days + 1;
> > +
> > +     tm->tm_hour = secs / 3600;
> > +     secs -= tm->tm_hour * 3600;
> > +     tm->tm_min = secs / 60;
> > +     tm->tm_sec = secs - tm->tm_min * 60;
> > +
> > +     tm->tm_isdst = 0;
> > +}
> > +
> > +/*
> > + * tst_rtc_tm_to_time - Converts rtc_time to time_t.
> > + * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
> > + */
> > +long long tst_rtc_tm_to_time(struct rtc_time *tm)
> > +{
> > +     return tst_mktime(((unsigned int)tm->tm_year + 1900), tm->tm_mon + 1,
> > +                     tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
>
> So I guess that the reason why we can't use libc mktime() and gmtime_r()
> is that time_t is 32bit on older 32bit architectures, right?

these functions is porting int kernel rtc-lib.c  rtc_tm_to_time64() which defaut
retrun is time64_t, mktime64. so I convert time64_t to long long type

>
> > +}
> > +
> > +static int rtc_supported_by_kernel(const char *rtc_dev)
> > +{
> > +     int exists = access(rtc_dev, F_OK);
> > +
> > +     if (exists < 0)
> > +             tst_brk(TCONF, "RTC device %s not available", rtc_dev);
> > +     return 0;
> > +}
>
> This function should be called by the tests rather than from the test
> library.

next version modify it.

>
> > +static int tst_rtc_ioctl(unsigned long request, struct rtc_time *rtc_tm)
> > +{
> > +     int ret;
> > +     int rtc_fd = -1;
> > +     static const char *rtc_dev = "/dev/rtc";
> > +
> > +     if (!rtc_supported_by_kernel(rtc_dev))
> > +             rtc_fd = SAFE_OPEN(rtc_dev, O_RDONLY);
> > +
> > +     ret = ioctl(rtc_fd, request, rtc_tm);
> > +
> > +     if (ret != 0)
> > +             return -1;
> > +
> > +     if (rtc_fd > 0)
> > +             SAFE_CLOSE(rtc_fd);
> > +
> > +     return 0;
> > +}
> > +
> > +int tst_rtc_gettime(struct rtc_time *rtc_tm)
> > +{
> > +     int ret;
> > +
> > +     ret = tst_rtc_ioctl(RTC_RD_TIME, rtc_tm);
> > +
> > +     if (ret != 0)
> > +             return -1;
> > +     return 0;
> > +}
> > +
> > +int tst_rtc_settime(struct rtc_time *rtc_tm)
> > +{
> > +     int ret;
> > +
> > +     ret = tst_rtc_ioctl(RTC_SET_TIME, rtc_tm);
> > +
> > +     if (ret != 0)
> > +             return -1;
> > +     return 0;
> > +}
>
> These two functions can be static inline and declared in the header as:
>
>
> static inline int tst_rtc_settime(struct rtc_time *rtc_tm)
> {
>         return tst_rtc_ioctl(RTC_SET_TIME, rtc_tm);
> }
>
> --
> Cyril Hrubis
> chrubis@suse.cz

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

* [LTP] [PATCH 2/3] lib: implement rtctime_save and rtctime_restore function
  2021-01-07 13:57   ` Cyril Hrubis
@ 2021-01-08  9:19     ` Cixi Geng
  2021-01-08  9:34       ` Cyril Hrubis
  0 siblings, 1 reply; 12+ messages in thread
From: Cixi Geng @ 2021-01-08  9:19 UTC (permalink / raw)
  To: ltp

Cyril Hrubis <chrubis@suse.cz> ?2021?1?7??? ??9:56???
>
> >  static struct timespec real_begin, mono_begin;
> >
> > +static struct rtc_time rtc_begin;
> > +
> >  static int clock_saved;
> >
> >  void tst_wallclock_save(void)
> > @@ -58,3 +61,42 @@ void tst_wallclock_restore(void)
> >       if (tst_clock_settime(CLOCK_REALTIME, &adjust))
> >               tst_brk(TBROK | TERRNO, "tst_clock_settime() realtime failed");
> >  }
> > +
> > +void tst_rtctime_save(void)
> > +{
> > +     /* save initial monotonic time to restore it when needed */
> > +     if (tst_rtc_gettime(&rtc_begin))
> > +             tst_brk(TBROK | TERRNO, "tst_rtc_gettime() realtime failed");
> > +
> > +     if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_begin))
> > +             tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
> > +
> > +     clock_saved = 1;
>
> It would be better if we defined rtc_clock_saved for the rtc* functions
> instead.
>
> > +}
> > +
> > +void tst_rtctime_restore(void)
> > +{
> > +     static struct timespec mono_end, elapsed;
> > +     static struct timespec rtc_begin_tm, rtc_adjust;
> > +     static struct rtc_time rtc_restore;
> > +
> > +     if (!clock_saved)
> > +             return;
> > +
> > +     clock_saved = 0;
> > +
> > +     if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end))
> > +             tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
> > +
> > +     elapsed = tst_timespec_diff(mono_end, mono_begin);
> > +
> > +     rtc_begin_tm.tv_sec = tst_rtc_tm_to_time(&rtc_begin);
>
> We should clear the tv_nsec here otherwise it will contain garbage.
The rtc_begin_tm is defined in this function? and tv_nsec never assigned?
so I think it will not produce any garbage.
>
> > +     rtc_adjust = tst_timespec_add(rtc_begin_tm, elapsed);
> > +
> > +     tst_rtc_time_to_tm(rtc_adjust.tv_sec, &rtc_restore);
> > +
> > +     /* restore realtime clock based on monotonic delta */
> > +     if (tst_rtc_settime(&rtc_restore))
> > +             tst_brk(TBROK | TERRNO, "tst_rtc_settime() realtime failed");
> > +}
>
> Other than this, it looks good.
>
> --
> Cyril Hrubis
> chrubis@suse.cz

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

* [LTP] [PATCH 2/3] lib: implement rtctime_save and rtctime_restore function
  2021-01-08  9:19     ` Cixi Geng
@ 2021-01-08  9:34       ` Cyril Hrubis
  2021-01-08  9:45         ` Cixi Geng
  0 siblings, 1 reply; 12+ messages in thread
From: Cyril Hrubis @ 2021-01-08  9:34 UTC (permalink / raw)
  To: ltp

Hi!
> > > +void tst_rtctime_restore(void)
> > > +{
> > > +     static struct timespec mono_end, elapsed;
> > > +     static struct timespec rtc_begin_tm, rtc_adjust;
> > > +     static struct rtc_time rtc_restore;
> > > +
> > > +     if (!clock_saved)
> > > +             return;
> > > +
> > > +     clock_saved = 0;
> > > +
> > > +     if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end))
> > > +             tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
> > > +
> > > +     elapsed = tst_timespec_diff(mono_end, mono_begin);
> > > +
> > > +     rtc_begin_tm.tv_sec = tst_rtc_tm_to_time(&rtc_begin);
> >
> > We should clear the tv_nsec here otherwise it will contain garbage.
> The rtc_begin_tm is defined in this function??? and tv_nsec never assigned???
> so I think it will not produce any garbage.

It's never assigned and declared on stack, so it will contain garbage
which will be eventually added to the rtc_adjust.tv_sec. Technically
the tv_nsec is long, so on 64 bit platform it may add up to 10^10
seconds to the result if we are unlucky and upper bits are set. On 32
bit there is not much room for error btw, up to 2 seconds since long is
only 4bytes there.

> > > +     rtc_adjust = tst_timespec_add(rtc_begin_tm, elapsed);
> > > +
> > > +     tst_rtc_time_to_tm(rtc_adjust.tv_sec, &rtc_restore);
> > > +
> > > +     /* restore realtime clock based on monotonic delta */
> > > +     if (tst_rtc_settime(&rtc_restore))
> > > +             tst_brk(TBROK | TERRNO, "tst_rtc_settime() realtime failed");
> > > +}
> >
> > Other than this, it looks good.
> >
> > --
> > Cyril Hrubis
> > chrubis@suse.cz

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH 2/3] lib: implement rtctime_save and rtctime_restore function
  2021-01-08  9:34       ` Cyril Hrubis
@ 2021-01-08  9:45         ` Cixi Geng
  0 siblings, 0 replies; 12+ messages in thread
From: Cixi Geng @ 2021-01-08  9:45 UTC (permalink / raw)
  To: ltp

Cyril Hrubis <chrubis@suse.cz> ?2021?1?8??? ??5:33???
>
> Hi!
> > > > +void tst_rtctime_restore(void)
> > > > +{
> > > > +     static struct timespec mono_end, elapsed;
> > > > +     static struct timespec rtc_begin_tm, rtc_adjust;
> > > > +     static struct rtc_time rtc_restore;
> > > > +
> > > > +     if (!clock_saved)
> > > > +             return;
> > > > +
> > > > +     clock_saved = 0;
> > > > +
> > > > +     if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end))
> > > > +             tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
> > > > +
> > > > +     elapsed = tst_timespec_diff(mono_end, mono_begin);
> > > > +
> > > > +     rtc_begin_tm.tv_sec = tst_rtc_tm_to_time(&rtc_begin);
> > >
> > > We should clear the tv_nsec here otherwise it will contain garbage.
> > The rtc_begin_tm is defined in this function??? and tv_nsec never assigned???
> > so I think it will not produce any garbage.
>
> It's never assigned and declared on stack, so it will contain garbage
> which will be eventually added to the rtc_adjust.tv_sec. Technically
> the tv_nsec is long, so on 64 bit platform it may add up to 10^10
> seconds to the result if we are unlucky and upper bits are set. On 32
> bit there is not much room for error btw, up to 2 seconds since long is
> only 4bytes there.
>

ok,I got it, thanks for you explain, I will fixed this issue

> > > > +     rtc_adjust = tst_timespec_add(rtc_begin_tm, elapsed);
> > > > +
> > > > +     tst_rtc_time_to_tm(rtc_adjust.tv_sec, &rtc_restore);
> > > > +
> > > > +     /* restore realtime clock based on monotonic delta */
> > > > +     if (tst_rtc_settime(&rtc_restore))
> > > > +             tst_brk(TBROK | TERRNO, "tst_rtc_settime() realtime failed");
> > > > +}
> > >
> > > Other than this, it looks good.
> > >
> > > --
> > > Cyril Hrubis
> > > chrubis@suse.cz
>
> --
> Cyril Hrubis
> chrubis@suse.cz

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

end of thread, other threads:[~2021-01-08  9:45 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-23  3:35 [LTP] [PATCH 0/3] add rtctime libs and rtc02 case gengcixi
2020-12-23  3:35 ` [LTP] [PATCH 1/3] lib: add tst_rtctime* for rtc test gengcixi
2021-01-07 13:50   ` Cyril Hrubis
2021-01-08  8:30     ` Cixi Geng
2020-12-23  3:35 ` [LTP] [PATCH 2/3] lib: implement rtctime_save and rtctime_restore function gengcixi
2021-01-07 13:57   ` Cyril Hrubis
2021-01-08  9:19     ` Cixi Geng
2021-01-08  9:34       ` Cyril Hrubis
2021-01-08  9:45         ` Cixi Geng
2020-12-23  3:35 ` [LTP] [PATCH 3/3] rtc02: add rtc set time verify case gengcixi
2021-01-07 14:32   ` Cyril Hrubis
2021-01-07 14:33 ` [LTP] [PATCH 0/3] add rtctime libs and rtc02 case Cyril Hrubis

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.