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_table.cpp
session_timer.cpp
session_queue.cpp
session_manager.cpp
session_transition.cpp
)

View File

@@ -8,7 +8,6 @@
#include "session_pool.h"
#include "session_table.h"
#include "session_timer.h"
#include "session_queue.h"
#include "session_manager.h"
#include "session_private.h"
#include "session_transition.h"
@@ -40,7 +39,7 @@ struct session_manager
struct session_table *tcp_sess_table;
struct session_table *udp_sess_table;
struct session_timer *sess_timer;
struct session_queue *sess_evicte_queue;
struct list_head evicte_queue;
struct duplicated_packet_filter *dup_pkt_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_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))
{
@@ -725,14 +724,14 @@ struct session_manager *session_manager_new(struct session_manager_options *opts
mgr->tcp_sess_table = session_table_new();
mgr->udp_sess_table = session_table_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->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;
}
INIT_LIST_HEAD(&mgr->evicte_queue);
session_filter_init();
session_transition_init();
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)
{
// 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);
}
// free all udp session
@@ -766,7 +767,6 @@ void session_manager_free(struct session_manager *mgr)
}
evicted_session_filter_free(mgr->evicte_sess_filter);
duplicated_packet_filter_free(mgr->dup_pkt_filter);
session_queue_free(mgr->sess_evicte_queue);
session_timer_free(mgr->sess_timer);
session_table_free(mgr->udp_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)
{
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)

View File

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

View File

@@ -10,6 +10,7 @@ extern "C"
{
#endif
#include "list.h"
#include "timeout.h"
#include "uthash.h"
#include "session.h"
@@ -87,13 +88,6 @@ struct session
void *expire_arg;
uint64_t expire_abs_ts;
/******************************
* Session Pool Zone
******************************/
// session pool recycle handle
struct session *next_free_ptr;
/******************************
* Session Table Zone
******************************/
@@ -102,17 +96,16 @@ struct session
struct tuple6 tuple;
enum session_dir tuple_dir;
struct session *next_ptr;
struct session *prev_ptr;
// session table handle
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

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)
#include "session_table.h"
#include "session_private.h"
#include "list.h"
struct session_table
{
@@ -12,8 +13,7 @@ struct session_table
void *arg;
uint64_t count;
struct session *head; // Least recently used
struct session *tail; // Most recently used
struct list_head lru_queue;
};
/******************************************************************************
@@ -45,56 +45,6 @@ static int HASH_KEYCMP_OVERWRITE(const void *key_a, const void *key_b, size_t le
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
******************************************************************************/
@@ -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 *table = (struct session_table *)calloc(1, sizeof(struct session_table));
if (table == NULL)
{
return NULL;
}
table->count = 0;
table->head = NULL;
table->tail = NULL;
INIT_LIST_HEAD(&table->lru_queue);
return table;
}
@@ -117,6 +71,7 @@ void session_table_free(struct session_table *table)
struct session *tmp = NULL;
HASH_ITER(hh, table->root, node, tmp)
{
list_del(&node->lru);
HASH_DELETE(hh, table->root, 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;
}
list_add_tail(&sess->lru, &table->lru_queue);
HASH_ADD(hh, table->root, tuple, sizeof(sess->tuple), sess);
add_session_to_list(table, sess);
table->count++;
return 0;
@@ -181,12 +136,12 @@ void session_table_del(struct session_table *table, const struct tuple6 *tuple)
return;
}
list_del(&sess->lru);
HASH_DELETE(hh, table->root, sess);
if (table->free_cb && sess)
{
table->free_cb(sess, table->arg);
}
del_session_from_list(table, sess);
table->count--;
}
@@ -209,8 +164,8 @@ struct session *session_table_find_tuple(struct session_table *table, const stru
if (sess)
{
del_session_from_list(table, sess);
add_session_to_list(table, sess);
list_del(&sess->lru);
list_add_tail(&sess->lru, &table->lru_queue);
}
return sess;
@@ -223,15 +178,12 @@ struct session *session_table_find_lru(struct session_table *table)
return NULL;
}
return table->head;
}
struct session *session_table_find_mru(struct session_table *table)
{
if (table == NULL)
if (list_empty(&table->lru_queue))
{
return NULL;
}
return table->tail;
else
{
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);
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_mru(struct session_table *table);
#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)
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)
###############################################################################
@@ -106,7 +103,6 @@ gtest_discover_tests(gtest_session)
gtest_discover_tests(gtest_session_pool)
gtest_discover_tests(gtest_session_table)
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_opening_to_active)

View File

@@ -57,7 +57,7 @@ static void packet_set_tcp_src_addr(struct packet *pkt, uint32_t addr)
}
#if 1
TEST(TCP_OVERLOAD, EVICT_TCP_OLD_SESS)
TEST(TCP_OVERLOAD, EVICT_OLD_SESS)
{
struct packet pkt;
struct session_manager *mgr = NULL;
@@ -97,7 +97,7 @@ TEST(TCP_OVERLOAD, EVICT_TCP_OLD_SESS)
#endif
#if 1
TEST(TCP_OVERLOAD, EVICT_TCP_NEW_SESS)
TEST(TCP_OVERLOAD, EVICT_NEW_SESS)
{
struct packet pkt;
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
EXPECT_TRUE(session_table_find_lru(sess_table) == NULL);
EXPECT_TRUE(session_table_find_mru(sess_table) == NULL);
sess1 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess1 != NULL);
@@ -156,7 +155,6 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
session_set_key(sess1, &tuple_1);
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_mru(sess_table) == sess1);
sess2 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess2 != NULL);
@@ -164,7 +162,6 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
session_set_key(sess2, &tuple_2);
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_mru(sess_table) == sess2);
sess3 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess3 != NULL);
@@ -172,21 +169,17 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
session_set_key(sess3, &tuple_3);
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_mru(sess_table) == sess3);
// Delete Session
session_table_del(sess_table, &tuple_1);
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);
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);
EXPECT_TRUE(session_table_find_lru(sess_table) == NULL);
EXPECT_TRUE(session_table_find_mru(sess_table) == NULL);
// Destroy
session_table_free(sess_table);