Skip to content

Commit a72e107

Browse files
authored
Merge pull request #2457 from tempesta-tech/MorganaFuture/optimize_tfw_current_timestamp
Optimize tfw_current_timestamp() with per-CPU caching
2 parents e68015c + 2f17512 commit a72e107

File tree

8 files changed

+93
-35
lines changed

8 files changed

+93
-35
lines changed

fw/access_log.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,8 @@ do_access_log_req_mmap(TfwHttpReq *req, u16 resp_status,
298298
room_size -= sizeof(val); \
299299
} while (0)
300300

301-
ktime_get_real_ts64(&ts);
302-
303-
event->timestamp = ts.tv_sec * 1000 + ts.tv_nsec/1000000;
301+
tfw_current_timestamp_ts64(&ts);
302+
event->timestamp = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
304303
event->type = TFW_MMAP_LOG_TYPE_ACCESS;
305304
event->fields = TFW_MMAP_LOG_ALL_FIELDS_MASK; /* Enable all the fields */
306305

lib/common.h

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* Tempesta kernel library
33
*
4-
* Copyright (C) 2019 Tempesta Technologies, Inc.
4+
* Copyright (C) 2019-2025 Tempesta Technologies, Inc.
55
*
66
* This program is free software; you can redistribute it and/or modify it
77
* under the terms of the GNU General Public License as published by
@@ -20,13 +20,64 @@
2020
#ifndef __LIB_COMMON_H__
2121
#define __LIB_COMMON_H__
2222

23-
/* Get current timestamp in secs. */
23+
#include <linux/percpu.h>
24+
#include <linux/time.h>
25+
26+
#define TFW_TS_REFRESH_INTERVAL (HZ)
27+
28+
/**
29+
* Get current timestamp with ktime_get_real_ts64 interface.
30+
* Uses per-CPU cached timestamps in softirq context.
31+
* WARNING: Must be called from softirq context only.
32+
*/
33+
static inline void
34+
tfw_current_timestamp_ts64(struct timespec64 *ts)
35+
{
36+
static DEFINE_PER_CPU(struct timespec64, tfw_cached_ts);
37+
static DEFINE_PER_CPU(unsigned long, tfw_ts_last_update);
38+
struct timespec64 *cached_ts;
39+
unsigned long *last_update;
40+
unsigned long now;
41+
42+
WARN_ON_ONCE(!in_softirq());
43+
44+
cached_ts = this_cpu_ptr(&tfw_cached_ts);
45+
last_update = this_cpu_ptr(&tfw_ts_last_update);
46+
now = jiffies;
47+
48+
if (unlikely(time_after(now,
49+
*last_update + TFW_TS_REFRESH_INTERVAL)))
50+
{
51+
ktime_get_real_ts64(cached_ts);
52+
*last_update = now;
53+
}
54+
55+
*ts = *cached_ts;
56+
}
57+
58+
/**
59+
* Get current timestamp in seconds.
60+
* Uses per-CPU cached timestamps in softirq context.
61+
* WARNING: Must be called from softirq context only.
62+
*/
2463
static inline long
2564
tfw_current_timestamp(void)
2665
{
2766
struct timespec64 ts;
28-
ktime_get_real_ts64(&ts);
67+
68+
tfw_current_timestamp_ts64(&ts);
2969
return ts.tv_sec;
3070
}
3171

72+
/**
73+
* Get current timestamp - real-time version.
74+
* For use when precise real-time is needed without caching.
75+
*/
76+
static inline void
77+
tfw_current_timestamp_real(struct timespec64 *ts)
78+
{
79+
WARN_ON_ONCE(!in_task());
80+
ktime_get_real_ts64(ts);
81+
}
82+
3283
#endif /* __LIB_COMMON_H__ */

tls/tls_cli.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Based on mbed TLS, https://tls.mbed.org.
77
*
88
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
9-
* Copyright (C) 2015-2018 Tempesta Technologies, Inc.
9+
* Copyright (C) 2015-2025 Tempesta Technologies, Inc.
1010
*
1111
* This program is free software; you can redistribute it and/or modify
1212
* it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
2525
#if 0 /* TODO #769 Full TLS proxying */
2626

2727
#include "debug.h"
28+
#include "lib/common.h"
2829
#include "ttls.h"
2930
#include "tls_internal.h"
3031

@@ -418,7 +419,7 @@ static int ssl_generate_random(TlsCtx *ssl)
418419
unsigned char *p = ssl->handshake->randbytes;
419420
long t;
420421

421-
t = ttls_time();
422+
t = tfw_current_timestamp();
422423
*p++ = (unsigned char)(t >> 24);
423424
*p++ = (unsigned char)(t >> 16);
424425
*p++ = (unsigned char)(t >> 8);
@@ -965,7 +966,7 @@ static int ssl_parse_server_hello(TlsCtx *ssl)
965966
{
966967
ssl->state++;
967968
ssl->handshake->resume = 0;
968-
ssl->session_negotiate->start = ttls_time();
969+
ssl->session_negotiate->start = tfw_current_timestamp();
969970
ssl->session_negotiate->ciphersuite = i;
970971
ssl->session_negotiate->compression = comp;
971972
ssl->session_negotiate->id_len = n;

tls/tls_internal.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Based on mbed TLS, https://tls.mbed.org.
77
*
88
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
9-
* Copyright (C) 2015-2024 Tempesta Technologies, Inc.
9+
* Copyright (C) 2015-2025 Tempesta Technologies, Inc.
1010
*
1111
* This program is free software; you can redistribute it and/or modify
1212
* it under the terms of the GNU General Public License as published by
@@ -397,12 +397,8 @@ ttls_rnd(void *buf, size_t len)
397397
memset(buf, 0x55, len);
398398
}
399399

400-
unsigned long ttls_time_debug(void);
401-
402-
#define ttls_time() ttls_time_debug()
403400

404401
#else
405-
#define ttls_time() get_seconds()
406402
/*
407403
* CPUs since Intel Ice Lake are safe against SRBDS attack, so we're good
408404
* with the hardware random generator.

tls/tls_srv.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525
#include "debug.h"
2626
#include "lib/str.h"
27+
#include "lib/common.h"
2728
#include "ecp.h"
2829
#include "mpool.h"
2930
#include "tls_internal.h"
@@ -1311,7 +1312,7 @@ ttls_write_server_hello(TlsCtx *tls, struct sg_table *sgt,
13111312
T_DBG("server hello, chosen version %d:%d, buf=%pK\n",
13121313
buf[4], buf[5], buf);
13131314

1314-
*(unsigned int *)p = htonl(ttls_time());
1315+
*(unsigned int *)p = htonl(tfw_current_timestamp());
13151316
p += 4;
13161317
ttls_rnd(p, 28);
13171318
p += 28;
@@ -1325,7 +1326,7 @@ ttls_write_server_hello(TlsCtx *tls, struct sg_table *sgt,
13251326
*/
13261327
tls->state = TTLS_SERVER_CERTIFICATE;
13271328

1328-
tls->sess.start = ttls_time();
1329+
tls->sess.start = tfw_current_timestamp();
13291330

13301331
if (tls->hs->new_session_ticket) {
13311332
tls->sess.id_len = n = 0;

tls/tls_ticket.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Based on mbed TLS, https://tls.mbed.org.
77
*
88
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
9-
* Copyright (C) 2015-2024 Tempesta Technologies, Inc.
9+
* Copyright (C) 2015-2025 Tempesta Technologies, Inc.
1010
*
1111
* This program is free software; you can redistribute it and/or modify
1212
* it under the terms of the GNU General Public License as published by
@@ -71,11 +71,23 @@ const char *ticket_key_name_iv =
7171
static inline unsigned long
7272
ttls_ticket_get_time(unsigned long lifetime)
7373
{
74-
unsigned long ts = tfw_current_timestamp();
74+
struct timespec64 ts;
75+
unsigned long ts_sec;
7576

76-
ts -= ts % lifetime;
77+
/*
78+
* This function is called from both process context
79+
* (ttls_tickets_configure) and softirq context
80+
* (ttls_ticket_rotate_keys timer callback).
81+
*/
82+
if (in_softirq()) {
83+
tfw_current_timestamp_ts64(&ts);
84+
} else {
85+
tfw_current_timestamp_real(&ts);
86+
}
87+
ts_sec = ts.tv_sec;
88+
ts_sec -= ts_sec % lifetime;
7789

78-
return ts;
90+
return ts_sec;
7991
}
8092

8193
/**
@@ -177,6 +189,7 @@ static void
177189
ttls_ticket_rotate_keys(struct timer_list *t)
178190
{
179191
TlsTicketPeerCfg *tcfg = from_timer(tcfg, t, timer);
192+
struct timespec64 ts;
180193
unsigned long secs;
181194

182195
T_DBG("TLS: Rotate keys for ticket configuration [%pK]\n", tcfg);
@@ -192,7 +205,8 @@ ttls_ticket_rotate_keys(struct timer_list *t)
192205
* and callback will fire at different time on different Tempesta
193206
* nodes. To avoid it need to recalculate timer every time.
194207
*/
195-
secs = tcfg->lifetime - (tfw_current_timestamp() % tcfg->lifetime);
208+
tfw_current_timestamp_ts64(&ts);
209+
secs = tcfg->lifetime - (ts.tv_sec % tcfg->lifetime);
196210
mod_timer(&tcfg->timer, jiffies + msecs_to_jiffies(secs * 1000));
197211
}
198212

@@ -280,6 +294,7 @@ ttls_tickets_configure(TlsPeerCfg *cfg, unsigned long lifetime,
280294
const char *md_ctx_key = secret_str;
281295
size_t md_ctx_key_len = len;
282296
TlsMdCtx md_ctx;
297+
struct timespec64 ts;
283298
unsigned long secs;
284299

285300
tcfg->active_key = 0;
@@ -351,7 +366,8 @@ ttls_tickets_configure(TlsPeerCfg *cfg, unsigned long lifetime,
351366
}
352367

353368
timer_setup(&tcfg->timer, ttls_ticket_rotate_keys, 0);
354-
secs = tcfg->lifetime - (tfw_current_timestamp() % tcfg->lifetime);
369+
tfw_current_timestamp_real(&ts);
370+
secs = tcfg->lifetime - (ts.tv_sec % tcfg->lifetime);
355371
mod_timer(&tcfg->timer, jiffies + msecs_to_jiffies(secs * 1000));
356372

357373
err:
@@ -479,7 +495,7 @@ ttls_ticket_sess_save(const TlsSess *sess, TlsState *state, size_t buf_len)
479495
static int
480496
ttls_ticket_sess_load(TlsState *state, size_t len, unsigned long lifetime)
481497
{
482-
long time_pass = ttls_time() - state->sess.start;
498+
long time_pass = tfw_current_timestamp() - state->sess.start;
483499

484500
if ((time_pass < 0) || (unsigned long)time_pass > lifetime)
485501
return TTLS_ERR_SESSION_TICKET_EXPIRED;

tls/ttls.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Based on mbed TLS, https://tls.mbed.org.
99
*
1010
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
11-
* Copyright (C) 2015-2024 Tempesta Technologies, Inc.
11+
* Copyright (C) 2015-2025 Tempesta Technologies, Inc.
1212
*
1313
* This program is free software; you can redistribute it and/or modify
1414
* it under the terms of the GNU General Public License as published by
@@ -2849,15 +2849,6 @@ ttls_alpn_ext_eq(const ttls_alpn_proto *proto, const unsigned char *buf,
28492849
return !memcmp_fast(proto->name, buf, len);
28502850
}
28512851

2852-
#if DBG_TLS >= 3
2853-
unsigned long
2854-
ttls_time_debug(void)
2855-
{
2856-
static atomic64_t curr_time = ATOMIC_INIT(0);
2857-
2858-
return atomic64_inc_return(&curr_time);
2859-
}
2860-
#endif
28612852

28622853
static void
28632854
ttls_exit(void)

tls/x509.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Based on mbed TLS, https://tls.mbed.org.
1616
*
1717
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
18-
* Copyright (C) 2015-2024 Tempesta Technologies, Inc.
18+
* Copyright (C) 2015-2025 Tempesta Technologies, Inc.
1919
*
2020
* This program is free software; you can redistribute it and/or modify
2121
* it under the terms of the GNU General Public License as published by
@@ -32,6 +32,7 @@
3232
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3333
*/
3434
#include "debug.h"
35+
#include "lib/common.h"
3536
#include "ttls.h"
3637
#include "asn1.h"
3738
#include "oid.h"
@@ -708,8 +709,10 @@ static void
708709
x509_get_current_time(ttls_x509_time *now)
709710
{
710711
struct tm t;
712+
struct timespec64 ts;
711713

712-
time64_to_tm(ttls_time(), 0, &t);
714+
tfw_current_timestamp_real(&ts);
715+
time64_to_tm(ts.tv_sec, 0, &t);
713716

714717
now->year = t.tm_year + 1900;
715718
now->mon = t.tm_mon + 1;

0 commit comments

Comments
 (0)