diff --git a/lib/common.h b/lib/common.h index d5196a3cf..41c36d77c 100644 --- a/lib/common.h +++ b/lib/common.h @@ -20,13 +20,83 @@ #ifndef __LIB_COMMON_H__ #define __LIB_COMMON_H__ -/* Get current timestamp in secs. */ -static inline long -tfw_current_timestamp(void) +#include +#include +#include + +/* Per-CPU cached timestamp */ +static DEFINE_PER_CPU(long, tfw_ts_cache); + +/* Update timer */ +static struct timer_list tfw_ts_timer; + +/* Timer interval: 1 second */ +#define TFW_TS_UPDATE_INTERVAL (HZ) + +/** + * Timer callback to update the cached timestamp across all CPUs. + */ +static void +tfw_ts_update_timer(struct timer_list *t) { struct timespec64 ts; + int cpu; + + /* Get the current timestamp */ ktime_get_real_ts64(&ts); - return ts.tv_sec; + + /* Update the timestamp on all CPUs */ + for_each_online_cpu(cpu) { + per_cpu(tfw_ts_cache, cpu) = ts.tv_sec; + } + + /* Reschedule the timer */ + mod_timer(&tfw_ts_timer, jiffies + TFW_TS_UPDATE_INTERVAL); +} + +/** + * Initialize the timestamp caching system. + * Should be called during module initialization. + */ +static inline int +tfw_ts_cache_init(void) +{ + struct timespec64 ts; + int cpu; + + /* Initialize the initial timestamp value */ + ktime_get_real_ts64(&ts); + + /* Set the initial value for all CPUs */ + for_each_online_cpu(cpu) { + per_cpu(tfw_ts_cache, cpu) = ts.tv_sec; + } + + /* Setup the timer */ + timer_setup(&tfw_ts_timer, tfw_ts_update_timer, 0); + mod_timer(&tfw_ts_timer, jiffies + TFW_TS_UPDATE_INTERVAL); + + return 0; +} + +/** + * Clean up the timestamp caching system. + * Should be called during module cleanup. + */ +static inline void +tfw_ts_cache_exit(void) +{ + del_timer_sync(&tfw_ts_timer); +} + +/** + * Get current timestamp in seconds. + * Always returns the cached value, which is updated by the timer. + */ +static inline long +tfw_current_timestamp(void) +{ + return this_cpu_read(tfw_ts_cache); } #endif /* __LIB_COMMON_H__ */ diff --git a/lib/main.c b/lib/main.c index 59a44567d..932a68304 100644 --- a/lib/main.c +++ b/lib/main.c @@ -20,6 +20,8 @@ #include #include +#include "common.h" + MODULE_AUTHOR("Tempesta Technologies, INC"); MODULE_VERSION("0.1.1"); MODULE_LICENSE("GPL"); @@ -64,13 +66,18 @@ EXPORT_SYMBOL(bzero_fast); static int __init tempesta_lib_init(void) -{ - return 0; +{ + int ret = tfw_ts_cache_init(); + if (ret) + return 1; + + return ret; } static void __exit tempesta_lib_exit(void) { + tfw_ts_cache_exit(); } module_init(tempesta_lib_init);