[PATCH 27/27] score: Add _Timecounter_Set_NTP_update_second()
From: Sebastian Huber Allow the installation of an NTP update second handler which may be used by an NTP service. Update #4549. --- cpukit/include/rtems/score/timecounter.h | 24 +++- cpukit/score/src/kern_tc.c | 23 +-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/cpukit/include/rtems/score/timecounter.h b/cpukit/include/rtems/score/timecounter.h index b71ccd3948..64429eae7b 100644 --- a/cpukit/include/rtems/score/timecounter.h +++ b/cpukit/include/rtems/score/timecounter.h @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2015 embedded brains GmbH. All rights reserved. + * Copyright (c) 2015, 2021 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -247,6 +247,28 @@ extern volatile int32_t _Timecounter_Time_uptime; */ extern struct timecounter *_Timecounter; +/** + * @brief Handler doing the NTP update second processing shall have this type. + * + * @param[in, out] adjustment is the NTP time adjustment. + * + * @param[in, out] newsec is the number of seconds since Unix epoch. + */ +typedefvoid ( *Timecounter_NTP_update_second )( + int64_t *adjustment, + time_t *newsec +); + +/** + * @brief Sets the NTP update second handler. + * + * @param handler is the new NTP update second handler used to carry out the + * NTP update second processing. + */ +void _Timecounter_Set_NTP_update_second( + Timecounter_NTP_update_second handler +); + /** @} */ #ifdef __cplusplus diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 1161463a0e..56ec4751ce 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -80,8 +80,6 @@ ISR_LOCK_DEFINE(, _Timecounter_Lock, "Timecounter") #define hz rtems_clock_get_ticks_per_second() #define printf(...) #define log(...) -/* FIXME: https://devel.rtems.org/ticket/2348 */ -#define ntp_update_second(a, b) do { (void) a; (void) b; } while (0) static inline void atomic_thread_fence_acq(void) @@ -117,6 +115,17 @@ atomic_load_ptr(void *ptr) return ((void *)_Atomic_Load_uintptr(ptr, ATOMIC_ORDER_RELAXED)); } + +static Timecounter_NTP_update_second _Timecounter_NTP_update_second; + +void +_Timecounter_Set_NTP_update_second(Timecounter_NTP_update_second handler) +{ + + _Timecounter_NTP_update_second = handler; +} + +#definentp_update_second(a, b) (*ntp_update_second_handler)(a, b) #endif /* __rtems__ */ /* @@ -1605,6 +1614,9 @@ _Timecounter_Windup(struct bintime *new_boottimebin, #endif int i; time_t t; +#ifdef __rtems__ + Timecounter_NTP_update_second ntp_update_second_handler; +#endif /* * Make the next timehands a copy of the current one, but do @@ -1680,6 +1692,10 @@ _Timecounter_Windup(struct bintime *new_boottimebin, */ bt = th->th_offset; bintime_add(, >th_boottime); +#ifdef __rtems__ + ntp_update_second_handler = _Timecounter_NTP_update_second; + if (ntp_update_second_handler != NULL) { +#endif /* __rtems__ */ i = bt.sec - tho->th_microtime.tv_sec; if (i > 0) { if (i > LARGE_STEP) @@ -1695,6 +1711,9 @@ _Timecounter_Windup(struct bintime *new_boottimebin, recalculate_scaling_factor_and_large_delta(th); } +#ifdef __rtems__ + } +#endif /* __rtems__ */ /* Update the UTC timestamps used by the get*() functions. */ th->th_bintime = bt; -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 25/27] score: Port large time delta support to RTEMS
From: Sebastian Huber --- cpukit/score/src/kern_tc.c| 25 --- testsuites/sptests/sptimecounter01/init.c | 4 ++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 52ae6aa034..00645600a1 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -158,7 +158,7 @@ struct timehands { struct timecounter *th_counter; int64_t th_adjustment; uint64_tth_scale; - u_int th_large_delta; + uint32_tth_large_delta; uint32_tth_offset_count; struct bintime th_offset; struct bintime th_bintime; @@ -218,6 +218,7 @@ static struct timehands th0 = { .th_counter = _timecounter, .th_scale = (uint64_t)-1 / 100, .th_offset = { .sec = 1 }, + .th_large_delta = 100, .th_generation = UINT_MAX, #ifdef __rtems__ .th_bintime = { .sec = TOD_SECONDS_1970_THROUGH_1988 }, @@ -373,7 +374,12 @@ bintime_off(struct bintime *bt, u_int off) struct timehands *th; struct bintime *btp; uint64_t scale, x; +#ifndef __rtems__ u_int delta, gen, large_delta; +#else /* __rtems__ */ + uint32_t delta, large_delta; + u_int gen; +#endif /* __rtems__ */ do { th = timehands; @@ -536,17 +542,30 @@ sbintime_t _Timecounter_Sbinuptime(void) { struct timehands *th; - uint32_t gen; sbintime_t sbt; + uint64_t scale; + uint32_t delta; + uint32_t large_delta; + u_int gen; do { th = timehands; gen = atomic_load_acq_int(>th_generation); sbt = bttosbt(th->th_offset); - sbt += (th->th_scale * tc_delta(th)) >> 32; + scale = th->th_scale; + delta = tc_delta(th); + large_delta = th->th_large_delta; atomic_thread_fence_acq(); } while (gen == 0 || gen != th->th_generation); + if (__predict_false(delta >= large_delta)) { + /* Avoid overflow for scale * delta. */ + sbt += (scale >> 32) * delta; + sbt += ((scale & 0x) * delta) >> 32; + } else { + sbt += (scale * delta) >> 32; + } + return (sbt); } #endif /* __rtems__ */ diff --git a/testsuites/sptests/sptimecounter01/init.c b/testsuites/sptests/sptimecounter01/init.c index 81b705473e..12d5a7820d 100644 --- a/testsuites/sptests/sptimecounter01/init.c +++ b/testsuites/sptests/sptimecounter01/init.c @@ -196,11 +196,11 @@ void boot_card(const char *cmdline) assert(bt.sec == 1); assert(bt.frac == 18446744073708); - /* Ensure that the fraction overflows and the second remains constant */ + /* Check that a large delta yields a correct time */ ctx->counter = (0xf000 | 1) + TEST_FREQ; rtems_bsd_binuptime(); assert(ctx->counter == (0xf000 | 2) + TEST_FREQ); - assert(bt.sec == 1); + assert(bt.sec == 2); assert(bt.frac == 18446742522092); test_install(ctx); -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 26/27] score: Optimize timehand updates for non-SMP
From: Sebastian Huber In uniprocessor configurations, the timehand updates are done with interrupts disabled. So, it is impossible to observe a generation number of zero. --- cpukit/score/src/kern_tc.c | 44 +++--- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 00645600a1..1161463a0e 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -390,7 +390,11 @@ bintime_off(struct bintime *bt, u_int off) delta = tc_delta(th); large_delta = th->th_large_delta; atomic_thread_fence_acq(); +#if defined(RTEMS_SMP) } while (gen == 0 || gen != th->th_generation); +#else + } while (gen != th->th_generation); +#endif if (__predict_false(delta >= large_delta)) { /* Avoid overflow for scale * delta. */ @@ -421,7 +425,11 @@ getthmember(void *out, size_t out_size, u_int off) gen = atomic_load_acq_int(>th_generation); memcpy(out, (char *)th + off, out_size); atomic_thread_fence_acq(); +#if defined(RTEMS_SMP) } while (gen == 0 || gen != th->th_generation); +#else + } while (gen != th->th_generation); +#endif } #defineGETTHMEMBER(dst, member) \ do { \ @@ -556,7 +564,11 @@ _Timecounter_Sbinuptime(void) delta = tc_delta(th); large_delta = th->th_large_delta; atomic_thread_fence_acq(); +#if defined(RTEMS_SMP) } while (gen == 0 || gen != th->th_generation); +#else + } while (gen != th->th_generation); +#endif if (__predict_false(delta >= large_delta)) { /* Avoid overflow for scale * delta. */ @@ -1587,7 +1599,10 @@ _Timecounter_Windup(struct bintime *new_boottimebin, struct bintime bt; struct timecounter *tc; struct timehands *th, *tho; - uint32_t delta, ncount, ogen; + uint32_t delta, ncount; +#if defined(RTEMS_SMP) + u_int ogen; +#endif int i; time_t t; @@ -1603,14 +1618,12 @@ _Timecounter_Windup(struct bintime *new_boottimebin, tho = timehands; #if defined(RTEMS_SMP) th = tho->th_next; -#else - th = tho; -#endif ogen = th->th_generation; th->th_generation = 0; atomic_thread_fence_rel(); -#if defined(RTEMS_SMP) memcpy(th, tho, offsetof(struct timehands, th_generation)); +#else + th = tho; #endif if (new_boottimebin != NULL) th->th_boottime = *new_boottimebin; @@ -1710,6 +1723,7 @@ _Timecounter_Windup(struct bintime *new_boottimebin, #endif } +#if defined(RTEMS_SMP) /* * Now that the struct timehands is again consistent, set the new * generation number, making sure to not make it zero. @@ -1717,6 +1731,9 @@ _Timecounter_Windup(struct bintime *new_boottimebin, if (++ogen == 0) ogen = 1; atomic_store_rel_int(>th_generation, ogen); +#else + atomic_store_rel_int(>th_generation, th->th_generation + 1); +#endif /* Go live with the new struct timehands. */ #ifdef FFCLOCK @@ -2209,27 +2226,38 @@ _Timecounter_Tick_simple(uint32_t delta, uint32_t offset, { struct bintime bt; struct timehands *th; - uint32_t ogen; +#if defined(RTEMS_SMP) + u_int ogen; +#endif th = timehands; +#if defined(RTEMS_SMP) ogen = th->th_generation; + th->th_generation = 0; + atomic_thread_fence_rel(); +#endif + th->th_offset_count = offset; bintime_addx(>th_offset, th->th_scale * delta); - bt = th->th_offset; bintime_add(, >th_boottime); + /* Update the UTC timestamps used by the get*() functions. */ th->th_bintime = bt; bintime2timeval(, >th_microtime); bintime2timespec(, >th_nanotime); +#if defined(RTEMS_SMP) /* * Now that the struct timehands is again consistent, set the new * generation number, making sure to not make it zero. */ if (++ogen == 0) ogen = 1; - th->th_generation = ogen; + atomic_store_rel_int(>th_generation, ogen); +#else + atomic_store_rel_int(>th_generation, th->th_generation + 1); +#endif /* Go live with the new struct timehands. */ time_second = th->th_microtime.tv_sec; -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 23/27] timecounter: Load the currently selected tc once in tc_windup()
From: Mark Johnston Reported by:Sebastian Huber Reviewed by:kib MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D32729 --- cpukit/score/src/kern_tc.c | 23 --- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 513341f4dc..0e6d98d117 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -110,6 +110,13 @@ atomic_store_rel_int(Atomic_Uint *i, u_int val) _Atomic_Store_uint(i, val, ATOMIC_ORDER_RELEASE); } + +static inline void * +atomic_load_ptr(void *ptr) +{ + + return ((void *)_Atomic_Load_uintptr(ptr, ATOMIC_ORDER_RELAXED)); +} #endif /* __rtems__ */ /* @@ -1559,6 +1566,7 @@ _Timecounter_Windup(struct bintime *new_boottimebin, #endif /* __rtems__ */ { struct bintime bt; + struct timecounter *tc; struct timehands *th, *tho; uint32_t delta, ncount, ogen; int i; @@ -1593,9 +1601,10 @@ _Timecounter_Windup(struct bintime *new_boottimebin, * changing timecounters, a counter value from the new timecounter. * Update the offset fields accordingly. */ + tc = atomic_load_ptr(); delta = tc_delta(th); - if (th->th_counter != timecounter) - ncount = timecounter->tc_get_timecount(timecounter); + if (th->th_counter != tc) + ncount = tc->tc_get_timecount(tc); else ncount = 0; #ifdef FFCLOCK @@ -1661,20 +1670,20 @@ _Timecounter_Windup(struct bintime *new_boottimebin, bintime2timespec(, >th_nanotime); /* Now is a good time to change timecounters. */ - if (th->th_counter != timecounter) { + if (th->th_counter != tc) { #ifndef __rtems__ #ifndef __arm__ - if ((timecounter->tc_flags & TC_FLAGS_C2STOP) != 0) + if ((tc->tc_flags & TC_FLAGS_C2STOP) != 0) cpu_disable_c2_sleep++; if ((th->th_counter->tc_flags & TC_FLAGS_C2STOP) != 0) cpu_disable_c2_sleep--; #endif #endif /* __rtems__ */ - th->th_counter = timecounter; + th->th_counter = tc; th->th_offset_count = ncount; #ifndef __rtems__ - tc_min_ticktock_freq = max(1, timecounter->tc_frequency / - (((uint64_t)timecounter->tc_counter_mask + 1) / 3)); + tc_min_ticktock_freq = max(1, tc->tc_frequency / + (((uint64_t)tc->tc_counter_mask + 1) / 3)); #endif /* __rtems__ */ recalculate_scaling_factor_and_large_delta(th); #ifdef FFCLOCK -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 19/27] Remove "All Rights Reserved" from
From: Ed Maste FreeBSD Foundation sys/ copyrights These ones were unambiguous cases where the Foundation was the only listed copyright holder (in the associated license block). Sponsored by: The FreeBSD Foundation --- cpukit/score/src/kern_tc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 076139ebfb..7ea38e2694 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -9,7 +9,6 @@ * * * Copyright (c) 2011, 2015, 2016 The FreeBSD Foundation - * All rights reserved. * * Portions of this software were developed by Julien Ridoux at the University * of Melbourne under sponsorship from the FreeBSD Foundation. -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 21/27] timecounter: Lock the timecounter list
From: Mark Johnston Timecounter registration is dynamic, i.e., there is no requirement that timecounters must be registered during single-threaded boot. Loadable drivers may in principle register timecounters (which can be switched to automatically). Timecounters cannot be unregistered, though this could be implemented. Registered timecounters belong to a global linked list. Add a mutex to synchronize insertions and the traversals done by (mpsafe) sysctl handlers. No functional change intended. Reviewed by:imp, kib MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D32511 --- cpukit/score/src/kern_tc.c | 40 -- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 2b131bb423..a2bf056e3a 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -182,6 +182,10 @@ static struct timehands *volatile timehands = [0]; struct timecounter *timecounter = _timecounter; static struct timecounter *timecounters = _timecounter; +/* Mutex to protect the timecounter list. */ +static struct mtx tc_lock; +MTX_SYSINIT(tc_lock, _lock, "tc", MTX_DEF); + int tc_min_ticktock_freq = 1; #else /* __rtems__ */ /* @@ -1356,8 +1360,6 @@ tc_init(struct timecounter *tc) tc->tc_quality); } - tc->tc_next = timecounters; - timecounters = tc; /* * Set up sysctl tree for this counter. */ @@ -1379,6 +1381,11 @@ tc_init(struct timecounter *tc) SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO, "quality", CTLFLAG_RD, &(tc->tc_quality), 0, "goodness of time counter"); + + mtx_lock(_lock); + tc->tc_next = timecounters; + timecounters = tc; + /* * Do not automatically switch if the current tc was specifically * chosen. Never automatically use a timecounter with negative quality. @@ -1386,22 +1393,24 @@ tc_init(struct timecounter *tc) * worse since this timecounter may not be monotonic. */ if (tc_chosen) - return; + goto unlock; if (tc->tc_quality < 0) - return; + goto unlock; if (tc_from_tunable[0] != '\0' && strcmp(tc->tc_name, tc_from_tunable) == 0) { tc_chosen = 1; tc_from_tunable[0] = '\0'; } else { if (tc->tc_quality < timecounter->tc_quality) - return; + goto unlock; if (tc->tc_quality == timecounter->tc_quality && tc->tc_frequency < timecounter->tc_frequency) - return; + goto unlock; } (void)tc->tc_get_timecount(tc); timecounter = tc; +unlock: + mtx_unlock(_lock); #else /* __rtems__ */ if (tc->tc_quality < timecounter->tc_quality) return; @@ -1705,16 +1714,22 @@ sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS) struct timecounter *newtc, *tc; int error; + mtx_lock(_lock); tc = timecounter; strlcpy(newname, tc->tc_name, sizeof(newname)); + mtx_unlock(_lock); error = sysctl_handle_string(oidp, [0], sizeof(newname), req); if (error != 0 || req->newptr == NULL) return (error); + + mtx_lock(_lock); /* Record that the tc in use now was specifically chosen. */ tc_chosen = 1; - if (strcmp(newname, tc->tc_name) == 0) + if (strcmp(newname, tc->tc_name) == 0) { + mtx_unlock(_lock); return (0); + } for (newtc = timecounters; newtc != NULL; newtc = newtc->tc_next) { if (strcmp(newname, newtc->tc_name) != 0) continue; @@ -1732,11 +1747,11 @@ sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS) * use any locking and that it can be called in hard interrupt * context via 'tc_windup()'. */ - return (0); + break; } - return (EINVAL); + mtx_unlock(_lock); + return (newtc != NULL ? 0 : EINVAL); } - SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_NOFETCH | CTLFLAG_MPSAFE, 0, 0, sysctl_kern_timecounter_hardware, "A", @@ -1750,12 +1765,17 @@ sysctl_kern_timecounter_choice(SYSCTL_HANDLER_ARGS) struct timecounter *tc; int error; + error = sysctl_wire_old_buffer(req, 0); + if (error != 0) + return (error); sbuf_new_for_sysctl(, NULL, 0, req); + mtx_lock(_lock); for (tc = timecounters; tc != NULL; tc = tc->tc_next) { if (tc != timecounters) sbuf_putc(, ' '); sbuf_printf(, "%s(%d)", tc->tc_name,
[PATCH 24/27] score: Initialize timehand generation to UINT_MAX
From: Sebastian Huber This leads to a timehand generation overflow right at the system start and helps to get code coverage in test programs. --- cpukit/score/src/kern_tc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 0e6d98d117..52ae6aa034 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -218,7 +218,7 @@ static struct timehands th0 = { .th_counter = _timecounter, .th_scale = (uint64_t)-1 / 100, .th_offset = { .sec = 1 }, - .th_generation = 1, + .th_generation = UINT_MAX, #ifdef __rtems__ .th_bintime = { .sec = TOD_SECONDS_1970_THROUGH_1988 }, .th_microtime = { TOD_SECONDS_1970_THROUGH_1988, 0 }, -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 22/27] kern_tc.c: Scaling/large delta recalculation
From: Sebastian Huber This change is a slight performance optimization for systems with a slow 64-bit division. The th->th_scale and th->th_large_delta values only depend on the timecounter frequency and the th->th_adjustment. The timecounter frequency of a timehand only changes when a new timecounter is activated for the timehand. The th->th_adjustment is only changed by the NTP second update. The NTP second update is not done for every call of tc_windup(). Move the code block to recalculate the scaling factor and the large delta of a timehand to the new helper function recalculate_scaling_factor_and_large_delta(). Call recalculate_scaling_factor_and_large_delta() when a new timecounter is activated and a NTP second update occurred. MFC after: 1 week --- cpukit/score/src/kern_tc.c | 88 ++ 1 file changed, 50 insertions(+), 38 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index a2bf056e3a..513341f4dc 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -1504,6 +1504,40 @@ _Timecounter_Set_clock(const struct bintime *_bt, #endif /* __rtems__ */ } +/* + * Recalculate the scaling factor. We want the number of 1/2^64 + * fractions of a second per period of the hardware counter, taking + * into account the th_adjustment factor which the NTP PLL/adjtime(2) + * processing provides us with. + * + * The th_adjustment is nanoseconds per second with 32 bit binary + * fraction and we want 64 bit binary fraction of second: + * + * x = a * 2^32 / 10^9 = a * 4.294967296 + * + * The range of th_adjustment is +/- 5000PPM so inside a 64bit int + * we can only multiply by about 850 without overflowing, that + * leaves no suitably precise fractions for multiply before divide. + * + * Divide before multiply with a fraction of 2199/512 results in a + * systematic undercompensation of 10PPM of th_adjustment. On a + * 5000PPM adjustment this is a 0.05PPM error. This is acceptable. + * + * We happily sacrifice the lowest of the 64 bits of our result + * to the goddess of code clarity. + */ +static void +recalculate_scaling_factor_and_large_delta(struct timehands *th) +{ + uint64_t scale; + + scale = (uint64_t)1 << 63; + scale += (th->th_adjustment / 1024) * 2199; + scale /= th->th_counter->tc_frequency; + th->th_scale = scale * 2; + th->th_large_delta = MIN(((uint64_t)1 << 63) / scale, UINT_MAX); +} + /* * Initialize the next struct timehands in the ring and make * it the active timehands. Along the way we might switch to a different @@ -1526,7 +1560,6 @@ _Timecounter_Windup(struct bintime *new_boottimebin, { struct bintime bt; struct timehands *th, *tho; - uint64_t scale; uint32_t delta, ncount, ogen; int i; time_t t; @@ -1596,7 +1629,7 @@ _Timecounter_Windup(struct bintime *new_boottimebin, #endif /* __rtems__ */ /* -* Deal with NTP second processing. The for loop normally +* Deal with NTP second processing. The loop normally * iterates at most once, but in extreme situations it might * keep NTP sane if timeouts are not run for several seconds. * At boot, the time step can be large when the TOD hardware @@ -1607,14 +1640,21 @@ _Timecounter_Windup(struct bintime *new_boottimebin, bt = th->th_offset; bintime_add(, >th_boottime); i = bt.sec - tho->th_microtime.tv_sec; - if (i > LARGE_STEP) - i = 2; - for (; i > 0; i--) { - t = bt.sec; - ntp_update_second(>th_adjustment, ); - if (bt.sec != t) - th->th_boottime.sec += bt.sec - t; + if (i > 0) { + if (i > LARGE_STEP) + i = 2; + + do { + t = bt.sec; + ntp_update_second(>th_adjustment, ); + if (bt.sec != t) + th->th_boottime.sec += bt.sec - t; + --i; + } while (i > 0); + + recalculate_scaling_factor_and_large_delta(th); } + /* Update the UTC timestamps used by the get*() functions. */ th->th_bintime = bt; bintime2timeval(, >th_microtime); @@ -1636,40 +1676,12 @@ _Timecounter_Windup(struct bintime *new_boottimebin, tc_min_ticktock_freq = max(1, timecounter->tc_frequency / (((uint64_t)timecounter->tc_counter_mask + 1) / 3)); #endif /* __rtems__ */ + recalculate_scaling_factor_and_large_delta(th); #ifdef FFCLOCK ffclock_change_tc(th); #endif } - /*- -* Recalculate the scaling factor. We want the number of 1/2^64 -* fractions of a second per period of the hardware counter, taking -* into account the th_adjustment factor which the NTP PLL/adjtime(2) -* processing provides
[PATCH 20/27] timecounter: Let kern.timecounter.stepwarnings be set as a tunable
From: Mark Johnston MFC after: 1 week --- cpukit/score/src/kern_tc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 7ea38e2694..2b131bb423 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -253,7 +253,7 @@ static SYSCTL_NODE(_kern_timecounter, OID_AUTO, tc, ""); static int timestepwarnings; -SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW, +SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RWTUN, , 0, "Log time steps"); static int timehands_count = 2; -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 17/27] Make kern.timecounter.hardware tunable
From: Konstantin Belousov Noted and reviewed by: kevans MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D29122 --- cpukit/score/src/kern_tc.c | 23 ++- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 6fbb59038a..5e0b6fa227 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -273,6 +273,7 @@ SYSCTL_PROC(_kern_timecounter, OID_AUTO, alloweddeviation, volatile int rtc_generation = 1; static int tc_chosen; /* Non-zero if a specific tc was chosen via sysctl. */ +static char tc_from_tunable[16]; #endif /* __rtems__ */ static void tc_windup(struct bintime *new_boottimebin); @@ -1383,17 +1384,26 @@ tc_init(struct timecounter *tc) return; if (tc->tc_quality < 0) return; -#endif /* __rtems__ */ + if (tc_from_tunable[0] != '\0' && + strcmp(tc->tc_name, tc_from_tunable) == 0) { + tc_chosen = 1; + tc_from_tunable[0] = '\0'; + } else { + if (tc->tc_quality < timecounter->tc_quality) + return; + if (tc->tc_quality == timecounter->tc_quality && + tc->tc_frequency < timecounter->tc_frequency) + return; + } + (void)tc->tc_get_timecount(tc); + timecounter = tc; +#else /* __rtems__ */ if (tc->tc_quality < timecounter->tc_quality) return; if (tc->tc_quality == timecounter->tc_quality && tc->tc_frequency < timecounter->tc_frequency) return; -#ifndef __rtems__ - (void)tc->tc_get_timecount(tc); -#endif /* __rtems__ */ timecounter = tc; -#ifdef __rtems__ tc_windup(NULL); #endif /* __rtems__ */ } @@ -2224,6 +2234,9 @@ inittimehands(void *dummy) for (i = 1, thp = [0]; i < timehands_count; thp = [i++]) thp->th_next = [i]; thp->th_next = [0]; + + TUNABLE_STR_FETCH("kern.timecounter.hardware", tc_from_tunable, + sizeof(tc_from_tunable)); } SYSINIT(timehands, SI_SUB_TUNABLES, SI_ORDER_ANY, inittimehands, NULL); -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 15/27] Changes that improve DTrace FBT reliability
From: Robert Watson on freebsd/arm64: - Implement a dtrace_getnanouptime(), matching the existing dtrace_getnanotime(), to avoid DTrace calling out to a potentially instrumentable function. (These should probably both be under KDTRACE_HOOKS. Also, it's not clear to me that they are correct implementations for the DTrace thread time functions they are used in .. fixes for another commit.) - Don't allow FBT to instrument functions involved in EL1 exception handling that are involved in FBT trap processing: handle_el1h_sync() and do_el1h_sync(). - Don't allow FBT to instrument DDB and KDB functions, as that makes it rather harder to debug FBT problems. Prior to these changes, use of FBT on FreeBSD/arm64 rapidly led to kernel panics due to recursion in DTrace. Reliable FBT on FreeBSD/arm64 is reliant on another change from @andrew to have the aarch64 instrumentor more carefully check that instructions it replaces are against the stack pointer, which can otherwise lead to memory corruption. That change remains under review. MFC after: 2 weeks Reviewed by:andrew, kp, markj (earlier version), jrtc27 (earlier version) Differential revision: https://reviews.freebsd.org/D27766 --- cpukit/score/src/kern_tc.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 69af591d91..6df3894caf 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -284,6 +284,7 @@ static void _Timecounter_Windup(struct bintime *new_boottimebin, #endif /* __rtems__ */ void dtrace_getnanotime(struct timespec *tsp); +void dtrace_getnanouptime(struct timespec *tsp); #ifndef __rtems__ static int @@ -1156,6 +1157,20 @@ dtrace_getnanotime(struct timespec *tsp) GETTHMEMBER(tsp, th_nanotime); } + +/* + * This is a clone of getnanouptime used for time since boot. + * The dtrace_ prefix prevents fbt from creating probes for + * it so an uptime that can be safely used in all fbt probes. + */ +void +dtrace_getnanouptime(struct timespec *tsp) +{ + struct bintime bt; + + GETTHMEMBER(, th_offset); + bintime2timespec(, tsp); +} #endif /* __rtems__ */ #ifdef FFCLOCK -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 12/27] Consolidate read code for timecounters
From: Konstantin Belousov and fix possible overflow in bintime()/binuptime(). The algorithm to read the consistent snapshot of current timehand is repeated in each accessor, including the details proper rollup detection and synchronization with the writer. In fact there are only two different kind of readers: one for bintime()/binuptime() which has to do the in-place calculation, and another kind which fetches some member from struct timehand. Extract the logic into type-checked macros, GETTHBINTIME() for bintime calculation, and GETTHMEMBER() for safe read of a structure' member. This way, the synchronization is only written in bintime_off() and getthmember(). In bintime_off(), use overflow-safe calculation of th_scale * delta(timecounter). In tc_windup, pre-calculate the min delta value which overflows and require slow algorithm, into the new timehands th_large_delta member. This part with overflow fix was written by Bruce Evans. Reported by:Mark Millard (the overflow issue) Tested by: pho Discussed with: emaste Sponsored by: The FreeBSD Foundation (kib) MFC after: 3 weeks --- cpukit/score/src/kern_tc.c | 232 ++--- 1 file changed, 87 insertions(+), 145 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index a72abaca35..ed8dc00ac1 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -152,6 +152,7 @@ struct timehands { struct timecounter *th_counter; int64_t th_adjustment; uint64_tth_scale; + u_int th_large_delta; uint32_tth_offset_count; struct bintime th_offset; struct bintime th_bintime; @@ -172,6 +173,7 @@ static struct timehands ths[16] = { [0] = { .th_counter = _timecounter, .th_scale = (uint64_t)-1 / 100, + .th_large_delta = 100, .th_offset = { .sec = 1 }, .th_generation = 1, }, @@ -342,20 +344,72 @@ tc_delta(struct timehands *th) * the comment in for a description of these 12 functions. */ -#ifdef FFCLOCK -void -fbclock_binuptime(struct bintime *bt) +static __inline void +bintime_off(struct bintime *bt, u_int off) { struct timehands *th; - unsigned int gen; + struct bintime *btp; + uint64_t scale, x; + u_int delta, gen, large_delta; do { th = timehands; gen = atomic_load_acq_int(>th_generation); - *bt = th->th_offset; - bintime_addx(bt, th->th_scale * tc_delta(th)); + btp = (struct bintime *)((vm_offset_t)th + off); + *bt = *btp; + scale = th->th_scale; + delta = tc_delta(th); + large_delta = th->th_large_delta; atomic_thread_fence_acq(); } while (gen == 0 || gen != th->th_generation); + + if (__predict_false(delta >= large_delta)) { + /* Avoid overflow for scale * delta. */ + x = (scale >> 32) * delta; + bt->sec += x >> 32; + bintime_addx(bt, x << 32); + bintime_addx(bt, (scale & 0x) * delta); + } else { + bintime_addx(bt, scale * delta); + } +} +#defineGETTHBINTIME(dst, member) \ +do { \ + _Static_assert(_Generic(((struct timehands *)NULL)->member, \ + struct bintime: 1, default: 0) == 1,\ + "struct timehands member is not of struct bintime type"); \ + bintime_off(dst, __offsetof(struct timehands, member)); \ +} while (0) + +static __inline void +getthmember(void *out, size_t out_size, u_int off) +{ + struct timehands *th; + u_int gen; + + do { + th = timehands; + gen = atomic_load_acq_int(>th_generation); + memcpy(out, (char *)th + off, out_size); + atomic_thread_fence_acq(); + } while (gen == 0 || gen != th->th_generation); +} +#defineGETTHMEMBER(dst, member) \ +do { \ + _Static_assert(_Generic(*dst, \ + __typeof(((struct timehands *)NULL)->member): 1,\ + default: 0) == 1, \ + "*dst and struct timehands member have different types"); \ + getthmember(dst, sizeof(*dst), __offsetof(struct timehands, \ + member)); \ +} while (0) + +#ifdef FFCLOCK +void +fbclock_binuptime(struct bintime *bt) +{ + + GETTHBINTIME(bt, th_offset); } void @@ -379,16 +433,8 @@ fbclock_microuptime(struct timeval *tvp) void
[PATCH 16/27] Add ddb 'show timecounter' command.
From: Konstantin Belousov MFC after: 1 week Sponsored by: The FreeBSD Foundation --- cpukit/score/src/kern_tc.c | 32 +++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 6df3894caf..6fbb59038a 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -2447,7 +2447,6 @@ tc_fill_vdso_timehands(struct vdso_timehands *vdso_th) enabled = 0; return (enabled); } -#endif /* __rtems__ */ #ifdef COMPAT_FREEBSD32 uint32_t @@ -2474,3 +2473,34 @@ tc_fill_vdso_timehands32(struct vdso_timehands32 *vdso_th32) return (enabled); } #endif + +#include "opt_ddb.h" +#ifdef DDB +#include + +DB_SHOW_COMMAND(timecounter, db_show_timecounter) +{ + struct timehands *th; + struct timecounter *tc; + u_int val1, val2; + + th = timehands; + tc = th->th_counter; + val1 = tc->tc_get_timecount(tc); + __compiler_membar(); + val2 = tc->tc_get_timecount(tc); + + db_printf("timecounter %p %s\n", tc, tc->tc_name); + db_printf(" mask %#x freq %ju qual %d flags %#x priv %p\n", + tc->tc_counter_mask, (uintmax_t)tc->tc_frequency, tc->tc_quality, + tc->tc_flags, tc->tc_priv); + db_printf(" val %#x %#x\n", val1, val2); + db_printf("timehands adj %#jx scale %#jx ldelta %d off_cnt %d gen %d\n", + (uintmax_t)th->th_adjustment, (uintmax_t)th->th_scale, + th->th_large_delta, th->th_offset_count, th->th_generation); + db_printf(" offset %jd %jd boottime %jd %jd\n", + (intmax_t)th->th_offset.sec, (uintmax_t)th->th_offset.frac, + (intmax_t)th->th_boottime.sec, (uintmax_t)th->th_boottime.frac); +} +#endif +#endif /* __rtems__ */ -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 18/27] kern: clarify boot time
From: Warner Losh In FreeBSD, the current time is computed from uptime + boottime. Uptime is a continuous, smooth function that's monotonically increasing. To effect changes to the current time, boottime is adjusted. boottime is mutable and shouldn't be cached against future need. Document the current implementation, with the caveat that we may stop stepping boottime on resume in the future and will step uptime instead (noted in the commit message, but not in the code). Sponsored by: Netflix Reviewed by:phk, rpokala Differential Revision: https://reviews.freebsd.org/D30116 --- cpukit/score/src/kern_tc.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 5e0b6fa227..076139ebfb 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -235,11 +235,17 @@ volatile int32_t time_uptime = 1; #endif /* __rtems__ */ #ifndef __rtems__ +/* + * The system time is always computed by summing the estimated boot time and the + * system uptime. The timehands track boot time, but it changes when the system + * time is set by the user, stepped by ntpd or adjusted when resuming. It + * is set to new_time - uptime. + */ static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS); SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, sysctl_kern_boottime, "S,timeval", -"System boottime"); +"Estimated system boottime"); SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, ""); -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 08/27] Instead of using an incomplete list of platforms
From: Olivier Houchard that uses 64bits time_t in 32bits mode, special case amd64, as i386 is the only arch that still uses 32bits time_t. --- cpukit/score/src/kern_tc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 747ce7edb3..21d018a671 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -256,7 +256,8 @@ sysctl_kern_boottime(SYSCTL_HANDLER_ARGS) getboottime(); -#ifndef __mips__ +/* i386 is the only arch which uses a 32bits time_t */ +#ifdef __amd64__ #ifdef SCTL_MASK32 int tv[2]; -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 14/27] Remove double-calls to tc_get_timecount()
From: Konstantin Belousov to warm timecounters. It seems that second call does not add any useful state change for all implemented timecounters. Discussed with: bde Sponsored by: The FreeBSD Foundation MFC after: 3 weeks --- cpukit/score/src/kern_tc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 1756ac1cb8..69af591d91 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -1376,7 +1376,6 @@ tc_init(struct timecounter *tc) return; #ifndef __rtems__ (void)tc->tc_get_timecount(tc); - (void)tc->tc_get_timecount(tc); #endif /* __rtems__ */ timecounter = tc; #ifdef __rtems__ @@ -1692,7 +1691,6 @@ sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS) /* Warm up new timecounter. */ (void)newtc->tc_get_timecount(newtc); - (void)newtc->tc_get_timecount(newtc); timecounter = newtc; @@ -2247,7 +2245,6 @@ inittimecounter(void *dummy) /* warm up new timecounter (again) and get rolling. */ (void)timecounter->tc_get_timecount(timecounter); - (void)timecounter->tc_get_timecount(timecounter); mtx_lock_spin(_setclock_mtx); tc_windup(NULL); mtx_unlock_spin(_setclock_mtx); -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 13/27] Mark more nodes as CTLFLAG_MPSAFE
From: Pawel Biernacki or CTLFLAG_NEEDGIANT (17 of many) r357614 added CTLFLAG_NEEDGIANT to make it easier to find nodes that are still not MPSAFE (or already are but aren’t properly marked). Use it in preparation for a general review of all nodes. This is non-functional change that adds annotations to SYSCTL_NODE and SYSCTL_PROC nodes using one of the soon-to-be-required flags. Mark all obvious cases as MPSAFE. All entries that haven't been marked as MPSAFE before are by default marked as NEEDGIANT Approved by:kib (mentor, blanket) Commented by: kib, gallatin, melifaro Differential Revision: https://reviews.freebsd.org/D23718 --- cpukit/score/src/kern_tc.c | 37 - 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index ed8dc00ac1..1756ac1cb8 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -236,11 +236,16 @@ volatile int32_t time_uptime = 1; #ifndef __rtems__ static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS); -SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, CTLTYPE_STRUCT|CTLFLAG_RD, -NULL, 0, sysctl_kern_boottime, "S,timeval", "System boottime"); +SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, +CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, +sysctl_kern_boottime, "S,timeval", +"System boottime"); -SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, ""); -static SYSCTL_NODE(_kern_timecounter, OID_AUTO, tc, CTLFLAG_RW, 0, ""); +SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, +""); +static SYSCTL_NODE(_kern_timecounter, OID_AUTO, tc, +CTLFLAG_RW | CTLFLAG_MPSAFE, 0, +""); static int timestepwarnings; SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW, @@ -1337,16 +1342,19 @@ tc_init(struct timecounter *tc) */ tc_root = SYSCTL_ADD_NODE_WITH_LABEL(NULL, SYSCTL_STATIC_CHILDREN(_kern_timecounter_tc), OID_AUTO, tc->tc_name, - CTLFLAG_RW, 0, "timecounter description", "timecounter"); + CTLFLAG_RW | CTLFLAG_MPSAFE, 0, + "timecounter description", "timecounter"); SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO, "mask", CTLFLAG_RD, &(tc->tc_counter_mask), 0, "mask for implemented bits"); SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO, - "counter", CTLTYPE_UINT | CTLFLAG_RD, tc, sizeof(*tc), - sysctl_kern_timecounter_get, "IU", "current timecounter value"); + "counter", CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_MPSAFE, tc, + sizeof(*tc), sysctl_kern_timecounter_get, "IU", + "current timecounter value"); SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO, - "frequency", CTLTYPE_U64 | CTLFLAG_RD, tc, sizeof(*tc), -sysctl_kern_timecounter_freq, "QU", "timecounter frequency"); + "frequency", CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_MPSAFE, tc, + sizeof(*tc), sysctl_kern_timecounter_freq, "QU", + "timecounter frequency"); SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(tc_root), OID_AUTO, "quality", CTLFLAG_RD, &(tc->tc_quality), 0, "goodness of time counter"); @@ -1701,8 +1709,9 @@ sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS) return (EINVAL); } -SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW, -0, 0, sysctl_kern_timecounter_hardware, "A", +SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, +CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_NOFETCH | CTLFLAG_MPSAFE, 0, 0, +sysctl_kern_timecounter_hardware, "A", "Timecounter hardware selected"); /* Report the available timecounter hardware. */ @@ -1724,8 +1733,10 @@ sysctl_kern_timecounter_choice(SYSCTL_HANDLER_ARGS) return (error); } -SYSCTL_PROC(_kern_timecounter, OID_AUTO, choice, CTLTYPE_STRING | CTLFLAG_RD, -0, 0, sysctl_kern_timecounter_choice, "A", "Timecounter hardware detected"); +SYSCTL_PROC(_kern_timecounter, OID_AUTO, choice, +CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 0, +sysctl_kern_timecounter_choice, "A", +"Timecounter hardware detected"); #endif /* __rtems__ */ #ifndef __rtems__ -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 10/27] Initialize timehands linkage much earlier.
From: Konstantin Belousov Reported and tested by: trasz Sponsored by: The FreeBSD Foundation MFC after: 1 week --- cpukit/score/src/kern_tc.c | 34 ++ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 3aa68f7595..0051d49330 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -245,7 +245,8 @@ SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW, , 0, "Log time steps"); static int timehands_count = 2; -SYSCTL_INT(_kern_timecounter, OID_AUTO, timehands_count, CTLFLAG_RDTUN, +SYSCTL_INT(_kern_timecounter, OID_AUTO, timehands_count, +CTLFLAG_RDTUN | CTLFLAG_NOFETCH, _count, 0, "Count of timehands in rotation"); struct bintime bt_timethreshold; @@ -2242,12 +2243,30 @@ done: return (0); } +/* Set up the requested number of timehands. */ static void -inittimecounter(void *dummy) +inittimehands(void *dummy) { struct timehands *thp; + int i; + + TUNABLE_INT_FETCH("kern.timecounter.timehands_count", + _count); + if (timehands_count < 1) + timehands_count = 1; + if (timehands_count > nitems(ths)) + timehands_count = nitems(ths); + for (i = 1, thp = [0]; i < timehands_count; thp = [i++]) + thp->th_next = [i]; + thp->th_next = [0]; +} +SYSINIT(timehands, SI_SUB_TUNABLES, SI_ORDER_ANY, inittimehands, NULL); + +static void +inittimecounter(void *dummy) +{ u_int p; - int i, tick_rate; + int tick_rate; /* * Set the initial timeout to @@ -2274,15 +2293,6 @@ inittimecounter(void *dummy) ffclock_init(); #endif - /* Set up the requested number of timehands. */ - if (timehands_count < 1) - timehands_count = 1; - if (timehands_count > nitems(ths)) - timehands_count = nitems(ths); - for (i = 1, thp = [0]; i < timehands_count; thp = [i++]) - thp->th_next = [i]; - thp->th_next = [0]; - /* warm up new timecounter (again) and get rolling. */ (void)timecounter->tc_get_timecount(timecounter); (void)timecounter->tc_get_timecount(timecounter); -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 11/27] Remove duplicated empty lines from kern/*.c
From: Mateusz Guzik No functional changes. --- cpukit/score/src/kern_tc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 0051d49330..a72abaca35 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -1763,7 +1763,6 @@ SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW, 0, 0, sysctl_kern_timecounter_hardware, "A", "Timecounter hardware selected"); - /* Report the available timecounter hardware. */ static int sysctl_kern_timecounter_choice(SYSCTL_HANDLER_ARGS) -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 06/27] tc: bcopy -> memcpy
From: Mateusz Guzik --- cpukit/score/src/kern_tc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 6e517f9f17..28994d82b4 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -80,7 +80,6 @@ ISR_LOCK_DEFINE(, _Timecounter_Lock, "Timecounter") _ISR_lock_Release_and_ISR_enable(&_Timecounter_Lock, lock_context) #define hz rtems_clock_get_ticks_per_second() #define printf(...) -#define bcopy(x, y, z) memcpy(y, x, z); #define log(...) /* FIXME: https://devel.rtems.org/ticket/2348 */ #define ntp_update_second(a, b) do { (void) a; (void) b; } while (0) @@ -1533,7 +1532,7 @@ _Timecounter_Windup(struct bintime *new_boottimebin, th->th_generation = 0; atomic_thread_fence_rel(); #if defined(RTEMS_SMP) - bcopy(tho, th, offsetof(struct timehands, th_generation)); + memcpy(th, tho, offsetof(struct timehands, th_generation)); #endif if (new_boottimebin != NULL) th->th_boottime = *new_boottimebin; -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 09/27] Make timehands count selectable at boottime.
From: Konstantin Belousov Tested by: O'Connor, Daniel Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D21563 This patch was modified by Sebastian Huber to adjust it for RTEMS. See comment in the patch. --- cpukit/score/src/kern_tc.c | 50 ++ 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 21d018a671..3aa68f7595 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -167,6 +167,35 @@ struct timehands { struct timehands*th_next; }; +#ifndef __rtems__ +static struct timehands ths[16] = { +[0] = { + .th_counter = _timecounter, + .th_scale = (uint64_t)-1 / 100, + .th_offset = { .sec = 1 }, + .th_generation = 1, +}, +}; + +static struct timehands *volatile timehands = [0]; +struct timecounter *timecounter = _timecounter; +static struct timecounter *timecounters = _timecounter; + +int tc_min_ticktock_freq = 1; +#else /* __rtems__ */ +/* + * In FreeBSD, the timehands count is a tuning option from two to 16. The + * tuning option was added since it is inexpensive and some FreeBSD users asked + * for it to play around. The default value is two. One system which did not + * work with two timehands was a system with one processor and a specific PPS + * device. + * + * For RTEMS, in uniprocessor configurations, just use one timehand since the + * update is done with interrupt disabled. + * + * In SMP configurations, use a fixed set of two timehands until someone + * reports an issue. + */ #if defined(RTEMS_SMP) static struct timehands th0; static struct timehands th1 = { @@ -193,10 +222,6 @@ static struct timehands th0 = { static struct timehands *volatile timehands = struct timecounter *timecounter = _timecounter; -#ifndef __rtems__ -static struct timecounter *timecounters = _timecounter; - -int tc_min_ticktock_freq = 1; #endif /* __rtems__ */ #ifndef __rtems__ @@ -219,6 +244,10 @@ static int timestepwarnings; SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW, , 0, "Log time steps"); +static int timehands_count = 2; +SYSCTL_INT(_kern_timecounter, OID_AUTO, timehands_count, CTLFLAG_RDTUN, +_count, 0, "Count of timehands in rotation"); + struct bintime bt_timethreshold; struct bintime bt_tickthreshold; sbintime_t sbt_timethreshold; @@ -2216,8 +2245,9 @@ done: static void inittimecounter(void *dummy) { + struct timehands *thp; u_int p; - int tick_rate; + int i, tick_rate; /* * Set the initial timeout to @@ -2243,6 +2273,16 @@ inittimecounter(void *dummy) #ifdef FFCLOCK ffclock_init(); #endif + + /* Set up the requested number of timehands. */ + if (timehands_count < 1) + timehands_count = 1; + if (timehands_count > nitems(ths)) + timehands_count = nitems(ths); + for (i = 1, thp = [0]; i < timehands_count; thp = [i++]) + thp->th_next = [i]; + thp->th_next = [0]; + /* warm up new timecounter (again) and get rolling. */ (void)timecounter->tc_get_timecount(timecounter); (void)timecounter->tc_get_timecount(timecounter); -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 04/27] score: Remove FreeBSD identifier
From: Sebastian Huber --- cpukit/score/src/kern_tc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 9e6602e478..f63e48d16b 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -46,7 +46,7 @@ #include #endif /* __rtems__ */ #include -__FBSDID("$FreeBSD: head/sys/kern/kern_tc.c 324528 2017-10-11 11:03:11Z kib $"); +__FBSDID("$FreeBSD$"); #include "opt_compat.h" #include "opt_ntp.h" -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 07/27] Create a new macro for static DPCPU data.
From: Andrew Turner On arm64 (and possible other architectures) we are unable to use static DPCPU data in kernel modules. This is because the compiler will generate PC-relative accesses, however the runtime-linker expects to be able to relocate these. In preparation to fix this create two macros depending on if the data is global or static. Reviewed by:bz, emaste, markj Sponsored by: ABT Systems Ltd Differential Revision: https://reviews.freebsd.org/D16140 --- cpukit/score/src/kern_tc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 28994d82b4..747ce7edb3 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -2257,8 +2257,8 @@ SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_SECOND, inittimecounter, NULL); static int cpu_tick_variable; static uint64_tcpu_tick_frequency; -static DPCPU_DEFINE(uint64_t, tc_cpu_ticks_base); -static DPCPU_DEFINE(unsigned, tc_cpu_ticks_last); +DPCPU_DEFINE_STATIC(uint64_t, tc_cpu_ticks_base); +DPCPU_DEFINE_STATIC(unsigned, tc_cpu_ticks_last); static uint64_t tc_cpu_ticks(void) -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 05/27] Move most of the contents of opt_compat.h
From: Brooks Davis to opt_global.h. opt_compat.h is mentioned in nearly 180 files. In-progress network driver compabibility improvements may add over 100 more so this is closer to "just about everywhere" than "only some files" per the guidance in sys/conf/options. Keep COMPAT_LINUX32 in opt_compat.h as it is confined to a subset of sys/compat/linux/*.c. A fake _COMPAT_LINUX option ensure opt_compat.h is created on all architectures. Move COMPAT_LINUXKPI to opt_dontuse.h as it is only used to control the set of compiled files. Reviewed by:kib, cem, jhb, jtl Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D14941 --- cpukit/score/src/kern_tc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index f63e48d16b..6e517f9f17 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -48,7 +48,6 @@ #include __FBSDID("$FreeBSD$"); -#include "opt_compat.h" #include "opt_ntp.h" #include "opt_ffclock.h" -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 02/27] SPDX: use the Beerware identifier.
From: "Pedro F. Giffuni" --- cpukit/score/src/kern_tc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index f004c9bf97..b17327a2f8 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -1,4 +1,6 @@ /*- + * SPDX-License-Identifier: Beerware + * * * "THE BEER-WARE LICENSE" (Revision 42): * wrote this file. As long as you retain this notice you -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 03/27] Use atomic_load(9) to read ppsinfo sequence numbers.
From: Konstantin Belousov In this case volatile qualifiers enusre that a compiler does not optimize the accesses out. Reviewed by:alc, jhb Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D13534 --- cpukit/score/src/kern_tc.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index b17327a2f8..9e6602e478 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -1799,10 +1799,10 @@ pps_fetch(struct pps_fetch_args *fapi, struct pps_state *pps) tv.tv_usec = fapi->timeout.tv_nsec / 1000; timo = tvtohz(); } - aseq = pps->ppsinfo.assert_sequence; - cseq = pps->ppsinfo.clear_sequence; - while (aseq == pps->ppsinfo.assert_sequence && - cseq == pps->ppsinfo.clear_sequence) { + aseq = atomic_load_int(>ppsinfo.assert_sequence); + cseq = atomic_load_int(>ppsinfo.clear_sequence); + while (aseq == atomic_load_int(>ppsinfo.assert_sequence) && + cseq == atomic_load_int(>ppsinfo.clear_sequence)) { if (abi_aware(pps, 1) && pps->driver_mtx != NULL) { if (pps->flags & PPSFLAG_MTX_SPIN) { err = msleep_spin(pps, pps->driver_mtx, -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 01/27] kern_tc.c: Remove unused code
From: Sebastian Huber This fix relates to a Coverity issue (PW.DECLARED_BUT_NOT_REFERENCED). --- cpukit/score/src/kern_tc.c | 6 -- 1 file changed, 6 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 1b65cf41ee..f004c9bf97 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -81,12 +81,6 @@ ISR_LOCK_DEFINE(, _Timecounter_Lock, "Timecounter") #define printf(...) #define bcopy(x, y, z) memcpy(y, x, z); #define log(...) -static inline int -builtin_fls(int x) -{ -return x ? sizeof(x) * 8 - __builtin_clz(x) : 0; -} -#define fls(x) builtin_fls(x) /* FIXME: https://devel.rtems.org/ticket/2348 */ #define ntp_update_second(a, b) do { (void) a; (void) b; } while (0) -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH 00/27] Update kern_tc in rtems 5 for ntp support
These commits port to rtems 5 the last changes in kern_tc and timecounter pushed by Sebastian Huber. Additionally the last commit closes the ticket 4549, which is a clone of 2348(NTP support) for rtems 5. Andrew Turner (1): Create a new macro for static DPCPU data. Brooks Davis (1): Move most of the contents of opt_compat.h Ed Maste (1): Remove "All Rights Reserved" from Konstantin Belousov (7): Use atomic_load(9) to read ppsinfo sequence numbers. Make timehands count selectable at boottime. Initialize timehands linkage much earlier. Consolidate read code for timecounters Remove double-calls to tc_get_timecount() Add ddb 'show timecounter' command. Make kern.timecounter.hardware tunable Mark Johnston (3): timecounter: Let kern.timecounter.stepwarnings be set as a tunable timecounter: Lock the timecounter list timecounter: Load the currently selected tc once in tc_windup() Mateusz Guzik (2): tc: bcopy -> memcpy Remove duplicated empty lines from kern/*.c Olivier Houchard (1): Instead of using an incomplete list of platforms Pawel Biernacki (1): Mark more nodes as CTLFLAG_MPSAFE Pedro F. Giffuni (1): SPDX: use the Beerware identifier. Robert Watson (1): Changes that improve DTrace FBT reliability Sebastian Huber (7): kern_tc.c: Remove unused code score: Remove FreeBSD identifier kern_tc.c: Scaling/large delta recalculation score: Initialize timehand generation to UINT_MAX score: Port large time delta support to RTEMS score: Optimize timehand updates for non-SMP score: Add _Timecounter_Set_NTP_update_second() Warner Losh (1): kern: clarify boot time cpukit/include/rtems/score/timecounter.h | 24 +- cpukit/score/src/kern_tc.c| 676 ++ testsuites/sptests/sptimecounter01/init.c | 4 +- 3 files changed, 445 insertions(+), 259 deletions(-) -- 2.17.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH v2] c-user: Document new clock manager directives
On 16/11/21 4:27 am, Sebastian Huber wrote: > On 11/11/2021 08:02, Sebastian Huber wrote:> On 09/11/2021 13:06, Sebastian > Huber wrote: >>> On 09/11/2021 08:50, Sebastian Huber wrote: On 09/11/2021 08:41, Chris Johns wrote: >> We could also use something like this: >> >> static inline struct timespec rtems_clock_get_realtime(void) >> { >> struct timespec time_snapshot; >> >> _Timecounter_Nanotime( _snapshot ); >> >> return time_snapshot; >> } >> >> Unfortunately GCC is not able to optimize this. >> > Ah OK. This can be fixed and the performance improved but once the API is > set it > cannot change or do you think we can add a check later and not break the > API? I filed a GCC bug for this: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103150 It seems I was not the only one noticing issues related to structure returns: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101926 However, if we want a foolproof API, then I would prefer the structure return over the return status and pointer argument. Compilers may get better in the future. clang has similar issues, so this is not only a GCC problem. >>> >>> We have at least three options for the API: >>> >>> 1. Use the existing FreeBSD implementation as is: >>> >>> void rtems_clock_get_realtime(struct timespec *); >>> >>> This is the easiest and most efficient approach. >>> >>> 2. Check for NULL and return a status: >>> >>> rtems_status_code rtems_clock_get_realtime(struct timespec *); >>> >>> This requires a wrapper function which is a bit less efficient and needs >>> more >>> code/testing: >>> >>> rtems_status_code >>> rtems_clock_get_realtime(struct timespec *time_snapshot) >>> { >>> if ( time_snapshot == NULL ) { >>> return RTEMS_INVALID_ADDRESS; >>> } >>> >>> _Timecounter_Nanotime( time_snapshot ); >>> return RTEMS_SUCCESSFUL; >>> } >>> >>> 3. Return the structure and use the existing implementation: >>> >>> static inline struct timespec rtems_clock_get_realtime(void) >>> { >>> struct timespec time_snapshot; >>> >>> _Timecounter_Nanotime( _snapshot ); >>> >>> return time_snapshot; >>> } >>> >>> This is currently not well supported by existing compilers: >>> >>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103150 >>> >>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101926 >>> >> >> 4. Do nothing for a NULL pointer: >> >> void rtems_clock_get_realtime(struct timespec *); >> >> This requires a wrapper function which can use a tail call optimization: >> >> void >> rtems_clock_get_realtime(struct timespec *time_snapshot) >> { >> if ( time_snapshot == NULL ) { >> return; >> } >> >> _Timecounter_Nanotime( time_snapshot ); >> } > > How do we want to proceed with this? We ship the high performance and very > useful clock routines from FreeBSD since 2015. I just would like to add an > RTEMS > signature for them and document them in the Clock Manager. Currently, these > routines are the most efficient way to get clock values in RTEMS. Developers > afraid of unchecked NULL pointers may use existing RTEMS directives or > clock_get(). It would be nice if we can decide on a way forward. I will leave this for Joel to decide. Chris ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH] config: CONFIGURE_DISABLE_BSP_SETTINGS
OK Chris On 16/11/21 5:18 am, Sebastian Huber wrote: > Evaluate CONFIGURE_DISABLE_BSP_SETTINGS for each affected application > configuration option. This makes the code easier to review since the > influence > of CONFIGURE_DISABLE_BSP_SETTINGS is locally visible in the code. > --- > cpukit/include/rtems/confdefs/bsp.h| 15 ++- > cpukit/include/rtems/confdefs/extensions.h | 3 ++- > cpukit/include/rtems/confdefs/iodrivers.h | 3 ++- > cpukit/include/rtems/confdefs/malloc.h | 10 +++--- > cpukit/include/rtems/confdefs/percpu.h | 9 ++--- > 5 files changed, 19 insertions(+), 21 deletions(-) > > diff --git a/cpukit/include/rtems/confdefs/bsp.h > b/cpukit/include/rtems/confdefs/bsp.h > index 03ad9bf55f..bc96713765 100644 > --- a/cpukit/include/rtems/confdefs/bsp.h > +++ b/cpukit/include/rtems/confdefs/bsp.h > @@ -41,19 +41,8 @@ > #error "Do not include this file directly, use instead" > #endif > > -#ifdef CONFIGURE_INIT > - > -#ifdef CONFIGURE_DISABLE_BSP_SETTINGS > - #undef BSP_IDLE_TASK_BODY > - #undef BSP_IDLE_TASK_STACK_SIZE > - #undef BSP_INITIAL_EXTENSION > - #undef BSP_INTERRUPT_STACK_SIZE > - #undef CONFIGURE_BSP_PREREQUISITE_DRIVERS > - #undef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK > -#else > - #include > +#if defined(CONFIGURE_INIT) && !defined(CONFIGURE_DISABLE_BSP_SETTINGS) > +#include > #endif > > -#endif /* CONFIGURE_INIT */ > - > #endif /* _RTEMS_CONFDEFS_BSP_H */ > diff --git a/cpukit/include/rtems/confdefs/extensions.h > b/cpukit/include/rtems/confdefs/extensions.h > index 6492407934..118ad29484 100644 > --- a/cpukit/include/rtems/confdefs/extensions.h > +++ b/cpukit/include/rtems/confdefs/extensions.h > @@ -146,7 +146,8 @@ extern "C" { > #ifdef CONFIGURE_INITIAL_EXTENSIONS >CONFIGURE_INITIAL_EXTENSIONS, > #endif > -#ifdef BSP_INITIAL_EXTENSION > +#if !defined(CONFIGURE_DISABLE_BSP_SETTINGS) && \ > + defined(BSP_INITIAL_EXTENSION) >BSP_INITIAL_EXTENSION > #endif >}; > diff --git a/cpukit/include/rtems/confdefs/iodrivers.h > b/cpukit/include/rtems/confdefs/iodrivers.h > index a7de77a8c3..8c102197eb 100644 > --- a/cpukit/include/rtems/confdefs/iodrivers.h > +++ b/cpukit/include/rtems/confdefs/iodrivers.h > @@ -110,7 +110,8 @@ extern "C" { > > rtems_driver_address_table > _IO_Driver_address_table[ CONFIGURE_MAXIMUM_DRIVERS ] = { > - #ifdef CONFIGURE_BSP_PREREQUISITE_DRIVERS > + #if !defined(CONFIGURE_DISABLE_BSP_SETTINGS) && \ > +defined(CONFIGURE_BSP_PREREQUISITE_DRIVERS) > CONFIGURE_BSP_PREREQUISITE_DRIVERS, >#endif >#ifdef CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS > diff --git a/cpukit/include/rtems/confdefs/malloc.h > b/cpukit/include/rtems/confdefs/malloc.h > index d864a98270..a8dae6e739 100644 > --- a/cpukit/include/rtems/confdefs/malloc.h > +++ b/cpukit/include/rtems/confdefs/malloc.h > @@ -45,8 +45,12 @@ > > #include > > -#if defined(CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK) \ > - || defined(CONFIGURE_MALLOC_DIRTY) > +#if !defined(CONFIGURE_DISABLE_BSP_SETTINGS) && \ > + defined(CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK) > +#define _CONFIGURE_HEAP_EXTEND_VIA_SBRK > +#endif > + > +#if defined(_CONFIGURE_HEAP_EXTEND_VIA_SBRK) || > defined(CONFIGURE_MALLOC_DIRTY) > #include > #endif > > @@ -54,7 +58,7 @@ > extern "C" { > #endif > > -#ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK > +#ifdef _CONFIGURE_HEAP_EXTEND_VIA_SBRK > const rtems_heap_extend_handler rtems_malloc_extend_handler = >rtems_heap_extend_via_sbrk; > #endif > diff --git a/cpukit/include/rtems/confdefs/percpu.h > b/cpukit/include/rtems/confdefs/percpu.h > index 3bea8340cb..b91590bfd9 100644 > --- a/cpukit/include/rtems/confdefs/percpu.h > +++ b/cpukit/include/rtems/confdefs/percpu.h > @@ -78,7 +78,8 @@ extern "C" { > /* Interrupt stack configuration */ > > #ifndef CONFIGURE_INTERRUPT_STACK_SIZE > - #ifdef BSP_INTERRUPT_STACK_SIZE > + #if !defined(CONFIGURE_DISABLE_BSP_SETTINGS) && \ > +defined(BSP_INTERRUPT_STACK_SIZE) > #define CONFIGURE_INTERRUPT_STACK_SIZE BSP_INTERRUPT_STACK_SIZE >#else > #define CONFIGURE_INTERRUPT_STACK_SIZE CPU_STACK_MINIMUM_SIZE > @@ -121,7 +122,8 @@ RTEMS_DEFINE_GLOBAL_SYMBOL( > /* Idle thread configuration */ > > #ifndef CONFIGURE_IDLE_TASK_STACK_SIZE > - #ifdef BSP_IDLE_TASK_STACK_SIZE > + #if !defined(CONFIGURE_DISABLE_BSP_SETTINGS) && \ > +defined(BSP_IDLE_TASK_STACK_SIZE) > #define CONFIGURE_IDLE_TASK_STACK_SIZE BSP_IDLE_TASK_STACK_SIZE >#else > #define CONFIGURE_IDLE_TASK_STACK_SIZE CONFIGURE_MINIMUM_TASK_STACK_SIZE > @@ -153,7 +155,8 @@ const size_t _Thread_Idle_stack_size = > CONFIGURE_IDLE_TASK_STACK_SIZE; >#error "If you define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION, then > you must define CONFIGURE_IDLE_TASK_BODY as well" > #endif > > -#if !defined(CONFIGURE_IDLE_TASK_BODY) && defined(BSP_IDLE_TASK_BODY) > +#if !defined(CONFIGURE_IDLE_TASK_BODY) && \ > +
Re: [PATCH] c-user: Use rubric for configuration options
OK to push. This is a sensible change to make. Thanks Chris On 16/11/21 6:27 pm, Sebastian Huber wrote: > Use a rubric instead of a definition list for the application > configuration options similar to the directive documentation pages. For > direcives and application configuration options use the same rubric > order. > > Generalize value constraints to constraints. > > This patch does not change hand written content. > --- > > The generated PDF can be reviewed here: > > https://ftp.rtems.org/pub/rtems/people/sebh/c-user.pdf > > c-user/config/bdbuf.rst | 457 +-- > c-user/config/bsp-related.rst | 304 > c-user/config/classic-api.rst | 676 > c-user/config/classic-init-task.rst | 355 + > c-user/config/device-driver.rst | 792 ++- > c-user/config/event-record.rst | 160 ++-- > c-user/config/filesystem.rst| 844 ++-- > c-user/config/general.rst | 1103 +++ > c-user/config/idle-task.rst | 147 ++-- > c-user/config/mpci.rst | 315 > c-user/config/posix-api.rst | 539 +++-- > c-user/config/posix-init-thread.rst | 115 +-- > c-user/config/scheduler-general.rst | 669 > c-user/config/task-stack-alloc.rst | 244 +++--- > 14 files changed, 3691 insertions(+), 3029 deletions(-) > > diff --git a/c-user/config/bdbuf.rst b/c-user/config/bdbuf.rst > index c5381e1..d36c2bd 100644 > --- a/c-user/config/bdbuf.rst > +++ b/c-user/config/bdbuf.rst > @@ -35,24 +35,29 @@ This section describes configuration options related to > the Block Device Cache > CONFIGURE_APPLICATION_NEEDS_LIBBLOCK > > > -CONSTANT: > -``CONFIGURE_APPLICATION_NEEDS_LIBBLOCK`` > +.. rubric:: CONSTANT: > > -OPTION TYPE: > -This configuration option is a boolean feature define. > +``CONFIGURE_APPLICATION_NEEDS_LIBBLOCK`` > > -DEFAULT CONFIGURATION: > -If this configuration option is undefined, then the described feature is > not > -enabled. > +.. rubric:: OPTION TYPE: > > -DESCRIPTION: > -In case this configuration option is defined, then the Block Device > Cache is > -initialized during system initialization. > +This configuration option is a boolean feature define. > > -NOTES: > -Each option of the Block Device Cache (bdbuf) configuration can be > explicitly > -set by the user with the configuration options below. The Block Device > Cache > -is used for example by the RFS and DOSFS filesystems. > +.. rubric:: DEFAULT CONFIGURATION: > + > +If this configuration option is undefined, then the described feature is not > +enabled. > + > +.. rubric:: DESCRIPTION: > + > +In case this configuration option is defined, then the Block Device Cache is > +initialized during system initialization. > + > +.. rubric:: NOTES: > + > +Each option of the Block Device Cache (bdbuf) configuration can be explicitly > +set by the user with the configuration options below. The Block Device Cache > +is used for example by the RFS and DOSFS filesystems. > > .. Generated from spec:/acfg/if/bdbuf-buffer-max-size > > @@ -63,30 +68,31 @@ NOTES: > CONFIGURE_BDBUF_BUFFER_MAX_SIZE > --- > > -CONSTANT: > -``CONFIGURE_BDBUF_BUFFER_MAX_SIZE`` > +.. rubric:: CONSTANT: > + > +``CONFIGURE_BDBUF_BUFFER_MAX_SIZE`` > + > +.. rubric:: OPTION TYPE: > > -OPTION TYPE: > -This configuration option is an integer define. > +This configuration option is an integer define. > > -DEFAULT VALUE: > -The default value is 4096. > +.. rubric:: DEFAULT VALUE: > > -VALUE CONSTRAINTS: > -The value of this configuration option shall satisfy all of the following > -constraints: > +The default value is 4096. > > -* It shall be greater than or equal to zero. > +.. rubric:: DESCRIPTION: > > -* It shall be an integral multiple of > - :ref:`CONFIGURE_BDBUF_BUFFER_MIN_SIZE`. > +The value of this configuration option defines the maximum size of a buffer > +in bytes. > > -DESCRIPTION: > -The value of this configuration option defines the maximum size of a > buffer > -in bytes. > +.. rubric:: CONSTRAINTS: > > -NOTES: > -None. > +The following constraints apply to this configuration option: > + > +* The value of the configuration option shall be greater than or equal to > zero. > + > +* The value of the configuration option shall be an integral multiple of > + :ref:`CONFIGURE_BDBUF_BUFFER_MIN_SIZE`. > > .. Generated from spec:/acfg/if/bdbuf-buffer-min-size > > @@ -97,30 +103,31 @@ NOTES: > CONFIGURE_BDBUF_BUFFER_MIN_SIZE > --- > > -CONSTANT: > -``CONFIGURE_BDBUF_BUFFER_MIN_SIZE`` > +.. rubric:: CONSTANT: > + > +``CONFIGURE_BDBUF_BUFFER_MIN_SIZE`` > + > +.. rubric:: OPTION TYPE: > > -OPTION TYPE: > -This configuration option is an integer define. > +This
Re: [PATCH v2 1/4] Revert "optvermaj.yml: Allow __RTEMS_MAJOR__ to be overridden so RTEMS 7 tools can be tested"
OK and thank you Chris On 16/11/21 5:47 pm, Sebastian Huber wrote: > This reverts commit d1bbfbea5f60f552b2b3138bb1df35c3372f2461. > --- > spec/build/cpukit/optvermaj.yml | 8 +++- > 1 file changed, 3 insertions(+), 5 deletions(-) > > diff --git a/spec/build/cpukit/optvermaj.yml b/spec/build/cpukit/optvermaj.yml > index e1a5eae5b3..2596e6ef6a 100644 > --- a/spec/build/cpukit/optvermaj.yml > +++ b/spec/build/cpukit/optvermaj.yml > @@ -1,16 +1,14 @@ > SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause > actions: > -- get-string: null > +- set-value: '6' > - env-assign: null > build-type: option > copyrights: > - Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) > -default: 6 > +default: null > default-by-variant: [] > -description: | > - Major Component of the RTEMS Version Number > +description: '' > enabled-by: true > -format: '{}' > links: [] > name: __RTEMS_MAJOR__ > type: build > ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH] config: Fix IO driver table initialization
Check all IO driver table configuration options which are used to initialize _IO_Driver_address_table[]. Checks for the following settings were missing: * CONFIGURE_BSP_PREREQUISITE_DRIVERS * CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS * CONFIGURE_APPLICATION_NEEDS_WATCHDOG_DRIVER * CONFIGURE_APPLICATION_EXTRA_DRIVERS Update #3875. --- cpukit/include/rtems/confdefs/iodrivers.h | 63 +++ 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/cpukit/include/rtems/confdefs/iodrivers.h b/cpukit/include/rtems/confdefs/iodrivers.h index 8c102197eb..1f77948676 100644 --- a/cpukit/include/rtems/confdefs/iodrivers.h +++ b/cpukit/include/rtems/confdefs/iodrivers.h @@ -43,16 +43,30 @@ #ifdef CONFIGURE_INIT -#if defined(CONFIGURE_APPLICATION_EXTRA_DRIVERS) \ - || defined(CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER) \ - || defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) \ - || defined(CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVER) \ - || defined(CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER) \ - || defined(CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER) \ - || defined(CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER) \ - || defined(CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER) \ - || defined(CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER) \ - || CONFIGURE_MAXIMUM_DRIVERS > 0 +#include + +#if !defined(CONFIGURE_DISABLE_BSP_SETTINGS) && \ + defined(CONFIGURE_BSP_PREREQUISITE_DRIVERS) +#define _CONFIGURE_BSP_PREREQUISITE_DRIVERS CONFIGURE_BSP_PREREQUISITE_DRIVERS +#endif + +#if defined(_CONFIGURE_BSP_PREREQUISITE_DRIVERS) || \ + defined(CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS) || \ + defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) || \ + defined(CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER) || \ + defined(CONFIGURE_APPLICATION_NEEDS_WATCHDOG_DRIVER) || \ + defined(CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER) || \ + defined(CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER) || \ + defined(CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER) || \ + defined(CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER) || \ + defined(CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVER) || \ + defined(CONFIGURE_APPLICATION_EXTRA_DRIVERS) +#define _CONFIGURE_HAS_IO_DRIVERS +#endif + +#if defined(_CONFIGURE_HAS_IO_DRIVERS) || \ + defined(CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER) || \ + CONFIGURE_MAXIMUM_DRIVERS > 0 #include #include @@ -110,9 +124,8 @@ extern "C" { rtems_driver_address_table _IO_Driver_address_table[ CONFIGURE_MAXIMUM_DRIVERS ] = { - #if !defined(CONFIGURE_DISABLE_BSP_SETTINGS) && \ -defined(CONFIGURE_BSP_PREREQUISITE_DRIVERS) -CONFIGURE_BSP_PREREQUISITE_DRIVERS, + #ifdef _CONFIGURE_BSP_PREREQUISITE_DRIVERS +_CONFIGURE_BSP_PREREQUISITE_DRIVERS, #endif #ifdef CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS, @@ -144,15 +157,8 @@ _IO_Driver_address_table[ CONFIGURE_MAXIMUM_DRIVERS ] = { #ifdef CONFIGURE_APPLICATION_EXTRA_DRIVERS CONFIGURE_APPLICATION_EXTRA_DRIVERS, #endif - #if defined(CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER) \ -|| ( !defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) \ - && !defined(CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER) \ - && !defined(CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER) \ - && !defined(CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER) \ - && !defined(CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER) \ - && !defined(CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER) \ - && !defined(CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVER) \ - && !defined(CONFIGURE_APPLICATION_EXTRA_DRIVERS) ) + #if defined(CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER) || \ +!defined(_CONFIGURE_HAS_IO_DRIVERS) NULL_DRIVER_TABLE_ENTRY #endif }; @@ -179,16 +185,9 @@ RTEMS_SYSINIT_ITEM( } #endif -#endif /* CONFIGURE_APPLICATION_EXTRA_DRIVERS - || CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER - || CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER - || CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVER - || CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER - || CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER - || CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER - || CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER - || CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER - || CONFIGURE_MAXIMUM_DRIVERS */ +#endif /* _CONFIGURE_HAS_IO_DRIVERS) || + CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER || + CONFIGURE_MAXIMUM_DRIVERS */ /* -- 2.26.2 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
[PATCH] c-user: rtems_scheduler_remove_processor()
Update error status description. Close #4544. --- c-user/scheduling-concepts/directives.rst | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/c-user/scheduling-concepts/directives.rst b/c-user/scheduling-concepts/directives.rst index aa0300e..1827060 100644 --- a/c-user/scheduling-concepts/directives.rst +++ b/c-user/scheduling-concepts/directives.rst @@ -683,9 +683,12 @@ scheduler specified by ``scheduler_id``. The processor was not owned by the scheduler. :c:macro:`RTEMS_RESOURCE_IN_USE` -The set of processors owned by the scheduler would have been empty after -the processor removal and there was at least one non-idle task that used -this scheduler as its :term:`home scheduler`. +The processor was required by at least one non-idle task that used the +scheduler as its :term:`home scheduler`. + +:c:macro:`RTEMS_RESOURCE_IN_USE` +The processor was the last processor owned by the scheduler and there was +at least one task that used the scheduler as a :term:`helping scheduler`. .. rubric:: NOTES: -- 2.31.1 ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel