Replace session queue with kernel list

This commit is contained in:
luwenpeng
2024-03-29 17:45:41 +08:00
parent 6e422ecb8d
commit 8e527a0f4c
12 changed files with 60 additions and 241 deletions

View File

@@ -3,7 +3,6 @@ add_library(session_manager
session_pool.cpp session_pool.cpp
session_table.cpp session_table.cpp
session_timer.cpp session_timer.cpp
session_queue.cpp
session_manager.cpp session_manager.cpp
session_transition.cpp session_transition.cpp
) )

View File

@@ -8,7 +8,6 @@
#include "session_pool.h" #include "session_pool.h"
#include "session_table.h" #include "session_table.h"
#include "session_timer.h" #include "session_timer.h"
#include "session_queue.h"
#include "session_manager.h" #include "session_manager.h"
#include "session_private.h" #include "session_private.h"
#include "session_transition.h" #include "session_transition.h"
@@ -40,7 +39,7 @@ struct session_manager
struct session_table *tcp_sess_table; struct session_table *tcp_sess_table;
struct session_table *udp_sess_table; struct session_table *udp_sess_table;
struct session_timer *sess_timer; struct session_timer *sess_timer;
struct session_queue *sess_evicte_queue; struct list_head evicte_queue;
struct duplicated_packet_filter *dup_pkt_filter; struct duplicated_packet_filter *dup_pkt_filter;
struct evicted_session_filter *evicte_sess_filter; struct evicted_session_filter *evicte_sess_filter;
@@ -467,7 +466,7 @@ static void session_manager_evicte_session(struct session_manager *mgr, struct s
session_timer_del(mgr->sess_timer, sess); session_timer_del(mgr->sess_timer, sess);
session_set_closing_reason(sess, CLOSING_BY_EVICTED); session_set_closing_reason(sess, CLOSING_BY_EVICTED);
session_queue_push(mgr->sess_evicte_queue, sess); list_add_tail(&sess->evicte, &mgr->evicte_queue);
switch (session_get_type(sess)) switch (session_get_type(sess))
{ {
@@ -725,14 +724,14 @@ struct session_manager *session_manager_new(struct session_manager_options *opts
mgr->tcp_sess_table = session_table_new(); mgr->tcp_sess_table = session_table_new();
mgr->udp_sess_table = session_table_new(); mgr->udp_sess_table = session_table_new();
mgr->sess_timer = session_timer_new(); mgr->sess_timer = session_timer_new();
mgr->sess_evicte_queue = session_queue_new();
mgr->dup_pkt_filter = duplicated_packet_filter_new(&duplicated_packet_filter_opts, now); mgr->dup_pkt_filter = duplicated_packet_filter_new(&duplicated_packet_filter_opts, now);
mgr->evicte_sess_filter = evicted_session_filter_new(&evicted_session_filter_opts, now); mgr->evicte_sess_filter = evicted_session_filter_new(&evicted_session_filter_opts, now);
if (mgr->sess_pool == NULL || mgr->tcp_sess_table == NULL || mgr->udp_sess_table == NULL || mgr->sess_timer == NULL || mgr->sess_evicte_queue == NULL || mgr->dup_pkt_filter == NULL || mgr->evicte_sess_filter == NULL) if (mgr->sess_pool == NULL || mgr->tcp_sess_table == NULL || mgr->udp_sess_table == NULL || mgr->sess_timer == NULL || mgr->dup_pkt_filter == NULL || mgr->evicte_sess_filter == NULL)
{ {
goto error; goto error;
} }
INIT_LIST_HEAD(&mgr->evicte_queue);
session_filter_init(); session_filter_init();
session_transition_init(); session_transition_init();
tcp_flags_idx = session_get_ex_new_index("tcp_flags", NULL, NULL); tcp_flags_idx = session_get_ex_new_index("tcp_flags", NULL, NULL);
@@ -750,8 +749,10 @@ void session_manager_free(struct session_manager *mgr)
if (mgr) if (mgr)
{ {
// free all evicted session // free all evicted session
while (mgr->sess_evicte_queue && (sess = session_manager_get_evicted_session(mgr))) while (!list_empty(&mgr->evicte_queue))
{ {
sess = list_first_entry(&mgr->evicte_queue, struct session, evicte);
list_del(&sess->evicte);
session_manager_free_session(mgr, sess); session_manager_free_session(mgr, sess);
} }
// free all udp session // free all udp session
@@ -766,7 +767,6 @@ void session_manager_free(struct session_manager *mgr)
} }
evicted_session_filter_free(mgr->evicte_sess_filter); evicted_session_filter_free(mgr->evicte_sess_filter);
duplicated_packet_filter_free(mgr->dup_pkt_filter); duplicated_packet_filter_free(mgr->dup_pkt_filter);
session_queue_free(mgr->sess_evicte_queue);
session_timer_free(mgr->sess_timer); session_timer_free(mgr->sess_timer);
session_table_free(mgr->udp_sess_table); session_table_free(mgr->udp_sess_table);
session_table_free(mgr->tcp_sess_table); session_table_free(mgr->tcp_sess_table);
@@ -919,7 +919,17 @@ struct session *session_manager_get_expired_session(struct session_manager *mgr,
struct session *session_manager_get_evicted_session(struct session_manager *mgr) struct session *session_manager_get_evicted_session(struct session_manager *mgr)
{ {
return session_queue_pop(mgr->sess_evicte_queue); struct session *sess = NULL;
if (list_empty(&mgr->evicte_queue))
{
return sess;
}
else
{
sess = list_first_entry(&mgr->evicte_queue, struct session, evicte);
list_del(&sess->evicte);
return sess;
}
} }
uint64_t session_manager_get_expire_interval(struct session_manager *mgr) uint64_t session_manager_get_expire_interval(struct session_manager *mgr)

View File

@@ -4,7 +4,7 @@
struct session_pool struct session_pool
{ {
uint64_t count; uint64_t count;
struct session *sess; struct list_head free_queue;
}; };
struct session_pool *session_pool_new(uint64_t count) struct session_pool *session_pool_new(uint64_t count)
@@ -14,15 +14,15 @@ struct session_pool *session_pool_new(uint64_t count)
{ {
return NULL; return NULL;
} }
INIT_LIST_HEAD(&pool->free_queue);
pool->count = count; struct session *array = (struct session *)(pool + 1);
pool->sess = (struct session *)(pool + 1);
for (uint64_t i = 0; i < count; i++) for (uint64_t i = 0; i < count; i++)
{ {
pool->sess[i].next_free_ptr = &pool->sess[i + 1]; struct session *sess = &array[i];
list_add_tail(&sess->free, &pool->free_queue);
pool->count++;
} }
pool->sess[count - 1].next_free_ptr = NULL;
return pool; return pool;
} }
@@ -31,6 +31,13 @@ void session_pool_free(struct session_pool *pool)
{ {
if (pool) if (pool)
{ {
while (!list_empty(&pool->free_queue))
{
struct session *sess = list_first_entry(&pool->free_queue, struct session, free);
list_del(&sess->free);
pool->count--;
}
free(pool); free(pool);
pool = NULL; pool = NULL;
} }
@@ -43,14 +50,13 @@ struct session *session_pool_pop(struct session_pool *pool)
return NULL; return NULL;
} }
struct session *sess = pool->sess; if (list_empty(&pool->free_queue))
if (sess == NULL)
{ {
return NULL; return NULL;
} }
pool->sess = sess->next_free_ptr; struct session *sess = list_first_entry(&pool->free_queue, struct session, free);
sess->next_free_ptr = NULL; list_del(&sess->free);
pool->count--; pool->count--;
return sess; return sess;
@@ -63,8 +69,7 @@ void session_pool_push(struct session_pool *pool, struct session *sess)
return; return;
} }
sess->next_free_ptr = pool->sess; list_add_tail(&sess->free, &pool->free_queue);
pool->sess = sess;
pool->count++; pool->count++;
} }

View File

@@ -10,6 +10,7 @@ extern "C"
{ {
#endif #endif
#include "list.h"
#include "timeout.h" #include "timeout.h"
#include "uthash.h" #include "uthash.h"
#include "session.h" #include "session.h"
@@ -87,13 +88,6 @@ struct session
void *expire_arg; void *expire_arg;
uint64_t expire_abs_ts; uint64_t expire_abs_ts;
/******************************
* Session Pool Zone
******************************/
// session pool recycle handle
struct session *next_free_ptr;
/****************************** /******************************
* Session Table Zone * Session Table Zone
******************************/ ******************************/
@@ -102,17 +96,16 @@ struct session
struct tuple6 tuple; struct tuple6 tuple;
enum session_dir tuple_dir; enum session_dir tuple_dir;
struct session *next_ptr;
struct session *prev_ptr;
// session table handle // session table handle
UT_hash_handle hh; UT_hash_handle hh;
/****************************** /******************************
* Session Queue Zone * Session Queue Node
******************************/ ******************************/
struct session *next_ready_ptr; struct list_head evicte; // used for evicte queue
struct list_head lru; // used for lru queue
struct list_head free; // used for free queue
}; };
#ifdef __cpluscplus #ifdef __cpluscplus

View File

@@ -1,77 +0,0 @@
#include "session_queue.h"
#include "session_private.h"
struct session_queue
{
struct session *head;
struct session *tail;
int count;
};
struct session_queue *session_queue_new()
{
struct session_queue *queue = (struct session_queue *)calloc(1, sizeof(struct session_queue));
if (queue == NULL)
{
return NULL;
}
return queue;
}
void session_queue_free(struct session_queue *queue)
{
if (queue)
{
free(queue);
queue = NULL;
}
}
void session_queue_push(struct session_queue *queue, struct session *sess)
{
if (queue == NULL || sess == NULL)
{
return;
}
if (queue->head == NULL)
{
queue->head = sess;
queue->tail = sess;
}
else
{
queue->tail->next_ready_ptr = sess;
queue->tail = sess;
}
sess->next_ready_ptr = NULL;
queue->count++;
}
struct session *session_queue_pop(struct session_queue *queue)
{
if (queue == NULL)
{
return NULL;
}
struct session *sess = queue->head;
if (sess == NULL)
{
return NULL;
}
if (queue->head == queue->tail)
{
queue->head = NULL;
queue->tail = NULL;
}
else
{
queue->head = sess->next_ready_ptr;
}
sess->next_ready_ptr = NULL;
queue->count--;
return sess;
}

View File

@@ -1,22 +0,0 @@
#ifndef _SESSION_QUEUE_H
#define _SESSION_QUEUE_H
#ifdef __cpluscplus
extern "C"
{
#endif
#include "session.h"
struct session_queue;
struct session_queue *session_queue_new();
void session_queue_free(struct session_queue *queue);
void session_queue_push(struct session_queue *queue, struct session *sess);
struct session *session_queue_pop(struct session_queue *queue);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -4,6 +4,7 @@
#define HASH_KEYCMP(a, b, len) HASH_KEYCMP_OVERWRITE(a, b, len) #define HASH_KEYCMP(a, b, len) HASH_KEYCMP_OVERWRITE(a, b, len)
#include "session_table.h" #include "session_table.h"
#include "session_private.h" #include "session_private.h"
#include "list.h"
struct session_table struct session_table
{ {
@@ -12,8 +13,7 @@ struct session_table
void *arg; void *arg;
uint64_t count; uint64_t count;
struct session *head; // Least recently used struct list_head lru_queue;
struct session *tail; // Most recently used
}; };
/****************************************************************************** /******************************************************************************
@@ -45,56 +45,6 @@ static int HASH_KEYCMP_OVERWRITE(const void *key_a, const void *key_b, size_t le
return -1; return -1;
} }
// add session to the tail of the list
static void add_session_to_list(struct session_table *table, struct session *sess)
{
if (table == NULL || sess == NULL)
{
return;
}
sess->next_ptr = NULL;
sess->prev_ptr = NULL;
if (table->head == NULL && table->tail == NULL)
{
table->head = sess;
table->tail = sess;
}
else
{
table->tail->next_ptr = sess;
sess->prev_ptr = table->tail;
table->tail = sess;
}
}
static void del_session_from_list(struct session_table *table, struct session *sess)
{
if (table == NULL || sess == NULL)
{
return;
}
if (sess->prev_ptr)
{
sess->prev_ptr->next_ptr = sess->next_ptr;
}
else
{
table->head = sess->next_ptr;
}
if (sess->next_ptr)
{
sess->next_ptr->prev_ptr = sess->prev_ptr;
}
else
{
table->tail = sess->prev_ptr;
}
}
/****************************************************************************** /******************************************************************************
* Public API * Public API
******************************************************************************/ ******************************************************************************/
@@ -102,9 +52,13 @@ static void del_session_from_list(struct session_table *table, struct session *s
struct session_table *session_table_new() struct session_table *session_table_new()
{ {
struct session_table *table = (struct session_table *)calloc(1, sizeof(struct session_table)); struct session_table *table = (struct session_table *)calloc(1, sizeof(struct session_table));
if (table == NULL)
{
return NULL;
}
table->count = 0; table->count = 0;
table->head = NULL; INIT_LIST_HEAD(&table->lru_queue);
table->tail = NULL;
return table; return table;
} }
@@ -117,6 +71,7 @@ void session_table_free(struct session_table *table)
struct session *tmp = NULL; struct session *tmp = NULL;
HASH_ITER(hh, table->root, node, tmp) HASH_ITER(hh, table->root, node, tmp)
{ {
list_del(&node->lru);
HASH_DELETE(hh, table->root, node); HASH_DELETE(hh, table->root, node);
if (table->free_cb && node) if (table->free_cb && node)
{ {
@@ -161,8 +116,8 @@ int session_table_add(struct session_table *table, const struct tuple6 *tuple, s
return -1; return -1;
} }
list_add_tail(&sess->lru, &table->lru_queue);
HASH_ADD(hh, table->root, tuple, sizeof(sess->tuple), sess); HASH_ADD(hh, table->root, tuple, sizeof(sess->tuple), sess);
add_session_to_list(table, sess);
table->count++; table->count++;
return 0; return 0;
@@ -181,12 +136,12 @@ void session_table_del(struct session_table *table, const struct tuple6 *tuple)
return; return;
} }
list_del(&sess->lru);
HASH_DELETE(hh, table->root, sess); HASH_DELETE(hh, table->root, sess);
if (table->free_cb && sess) if (table->free_cb && sess)
{ {
table->free_cb(sess, table->arg); table->free_cb(sess, table->arg);
} }
del_session_from_list(table, sess);
table->count--; table->count--;
} }
@@ -209,8 +164,8 @@ struct session *session_table_find_tuple(struct session_table *table, const stru
if (sess) if (sess)
{ {
del_session_from_list(table, sess); list_del(&sess->lru);
add_session_to_list(table, sess); list_add_tail(&sess->lru, &table->lru_queue);
} }
return sess; return sess;
@@ -223,15 +178,12 @@ struct session *session_table_find_lru(struct session_table *table)
return NULL; return NULL;
} }
return table->head; if (list_empty(&table->lru_queue))
}
struct session *session_table_find_mru(struct session_table *table)
{
if (table == NULL)
{ {
return NULL; return NULL;
} }
else
return table->tail; {
return list_first_entry(&table->lru_queue, struct session, lru);
}
} }

View File

@@ -21,7 +21,6 @@ int session_table_add(struct session_table *table, const struct tuple6 *tuple, s
void session_table_del(struct session_table *table, const struct tuple6 *tuple); void session_table_del(struct session_table *table, const struct tuple6 *tuple);
struct session *session_table_find_tuple(struct session_table *table, const struct tuple6 *tuple); struct session *session_table_find_tuple(struct session_table *table, const struct tuple6 *tuple);
struct session *session_table_find_lru(struct session_table *table); struct session *session_table_find_lru(struct session_table *table);
struct session *session_table_find_mru(struct session_table *table);
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -14,9 +14,6 @@ target_link_libraries(gtest_session_table session_manager gtest)
add_executable(gtest_session_timer gtest_session_timer.cpp) add_executable(gtest_session_timer gtest_session_timer.cpp)
target_link_libraries(gtest_session_timer session_manager gtest) target_link_libraries(gtest_session_timer session_manager gtest)
add_executable(gtest_session_queue gtest_session_queue.cpp)
target_link_libraries(gtest_session_queue session_manager gtest)
############################################################################### ###############################################################################
# gtest state machine (TCP) # gtest state machine (TCP)
############################################################################### ###############################################################################
@@ -106,7 +103,6 @@ gtest_discover_tests(gtest_session)
gtest_discover_tests(gtest_session_pool) gtest_discover_tests(gtest_session_pool)
gtest_discover_tests(gtest_session_table) gtest_discover_tests(gtest_session_table)
gtest_discover_tests(gtest_session_timer) gtest_discover_tests(gtest_session_timer)
gtest_discover_tests(gtest_session_queue)
gtest_discover_tests(gtest_state_tcp_init_to_opening) gtest_discover_tests(gtest_state_tcp_init_to_opening)
gtest_discover_tests(gtest_state_tcp_opening_to_active) gtest_discover_tests(gtest_state_tcp_opening_to_active)

View File

@@ -57,7 +57,7 @@ static void packet_set_tcp_src_addr(struct packet *pkt, uint32_t addr)
} }
#if 1 #if 1
TEST(TCP_OVERLOAD, EVICT_TCP_OLD_SESS) TEST(TCP_OVERLOAD, EVICT_OLD_SESS)
{ {
struct packet pkt; struct packet pkt;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
@@ -97,7 +97,7 @@ TEST(TCP_OVERLOAD, EVICT_TCP_OLD_SESS)
#endif #endif
#if 1 #if 1
TEST(TCP_OVERLOAD, EVICT_TCP_NEW_SESS) TEST(TCP_OVERLOAD, EVICT_NEW_SESS)
{ {
struct packet pkt; struct packet pkt;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;

View File

@@ -1,29 +0,0 @@
#include <gtest/gtest.h>
#include "session_private.h"
#include "session_queue.h"
TEST(SESSION_QUEUE, POP_PUSH)
{
struct session sess1;
struct session sess2;
struct session_queue *queue = NULL;
queue = session_queue_new();
EXPECT_TRUE(queue != NULL);
EXPECT_TRUE(session_queue_pop(queue) == NULL);
session_queue_push(queue, &sess1);
session_queue_push(queue, &sess2);
EXPECT_TRUE(session_queue_pop(queue) == &sess1);
EXPECT_TRUE(session_queue_pop(queue) == &sess2);
EXPECT_TRUE(session_queue_pop(queue) == NULL);
session_queue_free(queue);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -148,7 +148,6 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
// Add Session // Add Session
EXPECT_TRUE(session_table_find_lru(sess_table) == NULL); EXPECT_TRUE(session_table_find_lru(sess_table) == NULL);
EXPECT_TRUE(session_table_find_mru(sess_table) == NULL);
sess1 = session_pool_pop(sess_pool); sess1 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess1 != NULL); EXPECT_TRUE(sess1 != NULL);
@@ -156,7 +155,6 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
session_set_key(sess1, &tuple_1); session_set_key(sess1, &tuple_1);
EXPECT_TRUE(session_table_add(sess_table, &tuple_1, sess1) == 0); EXPECT_TRUE(session_table_add(sess_table, &tuple_1, sess1) == 0);
EXPECT_TRUE(session_table_find_lru(sess_table) == sess1); EXPECT_TRUE(session_table_find_lru(sess_table) == sess1);
EXPECT_TRUE(session_table_find_mru(sess_table) == sess1);
sess2 = session_pool_pop(sess_pool); sess2 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess2 != NULL); EXPECT_TRUE(sess2 != NULL);
@@ -164,7 +162,6 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
session_set_key(sess2, &tuple_2); session_set_key(sess2, &tuple_2);
EXPECT_TRUE(session_table_add(sess_table, &tuple_2, sess2) == 0); EXPECT_TRUE(session_table_add(sess_table, &tuple_2, sess2) == 0);
EXPECT_TRUE(session_table_find_lru(sess_table) == sess1); EXPECT_TRUE(session_table_find_lru(sess_table) == sess1);
EXPECT_TRUE(session_table_find_mru(sess_table) == sess2);
sess3 = session_pool_pop(sess_pool); sess3 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess3 != NULL); EXPECT_TRUE(sess3 != NULL);
@@ -172,21 +169,17 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
session_set_key(sess3, &tuple_3); session_set_key(sess3, &tuple_3);
EXPECT_TRUE(session_table_add(sess_table, &tuple_3, sess3) == 0); EXPECT_TRUE(session_table_add(sess_table, &tuple_3, sess3) == 0);
EXPECT_TRUE(session_table_find_lru(sess_table) == sess1); EXPECT_TRUE(session_table_find_lru(sess_table) == sess1);
EXPECT_TRUE(session_table_find_mru(sess_table) == sess3);
// Delete Session // Delete Session
session_table_del(sess_table, &tuple_1); session_table_del(sess_table, &tuple_1);
EXPECT_TRUE(session_table_find_lru(sess_table) == sess2); EXPECT_TRUE(session_table_find_lru(sess_table) == sess2);
EXPECT_TRUE(session_table_find_mru(sess_table) == sess3);
session_table_del(sess_table, &tuple_2); session_table_del(sess_table, &tuple_2);
EXPECT_TRUE(session_table_find_lru(sess_table) == sess3); EXPECT_TRUE(session_table_find_lru(sess_table) == sess3);
EXPECT_TRUE(session_table_find_mru(sess_table) == sess3);
session_table_del(sess_table, &tuple_3); session_table_del(sess_table, &tuple_3);
EXPECT_TRUE(session_table_find_lru(sess_table) == NULL); EXPECT_TRUE(session_table_find_lru(sess_table) == NULL);
EXPECT_TRUE(session_table_find_mru(sess_table) == NULL);
// Destroy // Destroy
session_table_free(sess_table); session_table_free(sess_table);