Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/proc: Assert clock_gettime(CLOCK_BOOTTIME) VS /proc/uptime monotonicity

The first field of /proc/uptime relies on the CLOCK_BOOTTIME clock which
can also be fetched from clock_gettime() API.

Improve the test coverage while verifying the monotonicity of
CLOCK_BOOTTIME accross both interfaces.

Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20230222144649.624380-9-frederic@kernel.org

authored by

Frederic Weisbecker and committed by
Thomas Gleixner
263dda24 270b2a67

+47 -8
+17 -4
tools/testing/selftests/proc/proc-uptime-001.c
··· 13 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 15 */ 16 - // Test that boottime value in /proc/uptime increments monotonically. 17 - // We don't test idle time monotonicity due to broken iowait task 18 - // counting, cf: comment above get_cpu_idle_time_us() 16 + // Test that boottime value in /proc/uptime and CLOCK_BOOTTIME increment 17 + // monotonically. We don't test idle time monotonicity due to broken iowait 18 + // task counting, cf: comment above get_cpu_idle_time_us() 19 19 #undef NDEBUG 20 20 #include <assert.h> 21 21 #include <stdint.h> ··· 27 27 28 28 int main(void) 29 29 { 30 - uint64_t start, u0, u1; 30 + uint64_t start, u0, u1, c0, c1; 31 31 int fd; 32 32 33 33 fd = open("/proc/uptime", O_RDONLY); ··· 35 35 36 36 u0 = proc_uptime(fd); 37 37 start = u0; 38 + c0 = clock_boottime(); 39 + 38 40 do { 39 41 u1 = proc_uptime(fd); 42 + c1 = clock_boottime(); 43 + 44 + /* Is /proc/uptime monotonic ? */ 40 45 assert(u1 >= u0); 46 + 47 + /* Is CLOCK_BOOTTIME monotonic ? */ 48 + assert(c1 >= c0); 49 + 50 + /* Is CLOCK_BOOTTIME VS /proc/uptime monotonic ? */ 51 + assert(c0 >= u0); 52 + 41 53 u0 = u1; 54 + c0 = c1; 42 55 } while (u1 - start < 100); 43 56 44 57 return 0;
+18 -4
tools/testing/selftests/proc/proc-uptime-002.c
··· 13 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 15 */ 16 - // Test that boottime value in /proc/uptime increments monotonically 17 - // while shifting across CPUs. We don't test idle time monotonicity 18 - // due to broken iowait task counting, cf: comment above get_cpu_idle_time_us() 16 + // Test that boottime value in /proc/uptime and CLOCK_BOOTTIME increment 17 + // monotonically while shifting across CPUs. We don't test idle time 18 + // monotonicity due to broken iowait task counting, cf: comment above 19 + // get_cpu_idle_time_us() 19 20 #undef NDEBUG 20 21 #include <assert.h> 21 22 #include <errno.h> ··· 44 43 45 44 int main(void) 46 45 { 46 + uint64_t u0, u1, c0, c1; 47 47 unsigned int len; 48 48 unsigned long *m; 49 49 unsigned int cpu; 50 - uint64_t u0, u1; 51 50 int fd; 52 51 53 52 /* find out "nr_cpu_ids" */ ··· 63 62 assert(fd >= 0); 64 63 65 64 u0 = proc_uptime(fd); 65 + c0 = clock_boottime(); 66 + 66 67 for (cpu = 0; cpu < len * 8; cpu++) { 67 68 memset(m, 0, len); 68 69 m[cpu / (8 * sizeof(unsigned long))] |= 1UL << (cpu % (8 * sizeof(unsigned long))); ··· 73 70 sys_sched_setaffinity(0, len, m); 74 71 75 72 u1 = proc_uptime(fd); 73 + c1 = clock_boottime(); 74 + 75 + /* Is /proc/uptime monotonic ? */ 76 76 assert(u1 >= u0); 77 + 78 + /* Is CLOCK_BOOTTIME monotonic ? */ 79 + assert(c1 >= c0); 80 + 81 + /* Is CLOCK_BOOTTIME VS /proc/uptime monotonic ? */ 82 + assert(c0 >= u0); 83 + 77 84 u0 = u1; 85 + c0 = c1; 78 86 } 79 87 80 88 return 0;
+12
tools/testing/selftests/proc/proc-uptime.h
··· 19 19 #include <string.h> 20 20 #include <stdlib.h> 21 21 #include <unistd.h> 22 + #include <time.h> 22 23 23 24 #include "proc.h" 25 + 26 + static uint64_t clock_boottime(void) 27 + { 28 + struct timespec ts; 29 + int err; 30 + 31 + err = clock_gettime(CLOCK_BOOTTIME, &ts); 32 + assert(err >= 0); 33 + 34 + return (ts.tv_sec * 100) + (ts.tv_nsec / 10000000); 35 + } 24 36 25 37 static uint64_t proc_uptime(int fd) 26 38 {