Browse Source

memory_pool: name field — идентификация пула в диагностике коррапшна

bbr
Evgeny 4 months ago
parent
commit
075c4f4583
  1. 11
      lib/memory_pool.c
  2. 3
      lib/memory_pool.h
  3. 4
      lib/tcp_io.c
  4. 2
      lib/u_async.c
  5. 2
      src/dummynet.c
  6. 4
      src/etcp.c
  7. 6
      src/lwip_tcp/lwip_tcp.c
  8. 2
      src/proxy/tcp_proxy_client.c
  9. 4
      src/tun_if.c
  10. 6
      src/utun_instance.c
  11. 6
      tests/bbr_integration/test_bbr_integration.c
  12. 6
      tests/test_etcp_congestion.c
  13. 6
      tests/test_etcp_dummynet.c
  14. 6
      tests/test_etcp_reinit_inflight.c
  15. 2
      tests/test_intensive_memory_pool.c
  16. 2
      tests/test_ll_queue.c
  17. 4
      tests/test_pkt_normalizer_standalone.c

11
lib/memory_pool.c

@ -29,8 +29,8 @@ static void pool_check_and_clear_tags(struct memory_pool* pool, void* obj, const
uint8_t* counter = (uint8_t*)obj + POOL_COUNTER_OFF; uint8_t* counter = (uint8_t*)obj + POOL_COUNTER_OFF;
if (*canary != POOL_CANARY_VAL) { if (*canary != POOL_CANARY_VAL) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "pool_free BUFFER OVERFLOW pool=%p sz=%zu allocs=%zu reuse=%zu free=%d", DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "pool_free BUFFER OVERFLOW pool=%p name=%s sz=%zu allocs=%zu reuse=%zu free=%d",
pool, pool->object_size, pool->allocations, pool->reuse_count, pool->free_count); pool, pool->name ? pool->name : "?", pool->object_size, pool->allocations, pool->reuse_count, pool->free_count);
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, " obj=%p alloc=%s free=%s canary=0x%08x expected=0x%08x", DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, " obj=%p alloc=%s free=%s canary=0x%08x expected=0x%08x",
obj, *loc ? *loc : "(null)", location, *canary, POOL_CANARY_VAL); obj, *loc ? *loc : "(null)", location, *canary, POOL_CANARY_VAL);
if (pool->object_size) if (pool->object_size)
@ -39,8 +39,8 @@ static void pool_check_and_clear_tags(struct memory_pool* pool, void* obj, const
while (_halt) {} while (_halt) {}
} }
if (*counter == 0) { if (*counter == 0) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "pool_free DOUBLE FREE pool=%p sz=%zu allocs=%zu reuse=%zu alloc=%s free=%s", DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "pool_free DOUBLE FREE pool=%p name=%s sz=%zu allocs=%zu reuse=%zu alloc=%s free=%s",
pool, pool->object_size, pool->allocations, pool->reuse_count, pool, pool->name ? pool->name : "?", pool->object_size, pool->allocations, pool->reuse_count,
*loc ? *loc : "(null)", location); *loc ? *loc : "(null)", location);
volatile int _halt = 1; volatile int _halt = 1;
while (_halt) {} while (_halt) {}
@ -55,7 +55,7 @@ size_t memory_pool_get_total_free_blocks(void) {
} }
// Инициализировать пул памяти // Инициализировать пул памяти
struct memory_pool* memory_pool_init(size_t object_size) { struct memory_pool* memory_pool_init(size_t object_size, const char* name) {
struct memory_pool* pool = u_calloc(1, sizeof(struct memory_pool)); struct memory_pool* pool = u_calloc(1, sizeof(struct memory_pool));
if (!pool) { if (!pool) {
return NULL; return NULL;
@ -66,6 +66,7 @@ struct memory_pool* memory_pool_init(size_t object_size) {
pool->allocations = 0; pool->allocations = 0;
pool->reuse_count = 0; pool->reuse_count = 0;
pool->alloc_tag_counter = 1; pool->alloc_tag_counter = 1;
pool->name = name;
return pool; return pool;
} }

3
lib/memory_pool.h

@ -18,11 +18,12 @@ struct memory_pool {
size_t allocations; // Общее количество аллокаций (включая новые malloc) size_t allocations; // Общее количество аллокаций (включая новые malloc)
size_t reuse_count; // Количество повторных использований из пула size_t reuse_count; // Количество повторных использований из пула
uint8_t alloc_tag_counter; // монотонный счётчик для детекции double-free (1 байт) uint8_t alloc_tag_counter; // монотонный счётчик для детекции double-free (1 байт)
const char* name; // Имя пула для диагностики (напр. "data_pool", "pkt_pool")
}; };
// сам пул: // сам пул:
// если используем с элементами ll_queue то не забываем что к object_size надо прибавить sizeof(struct ll_entry) // если используем с элементами ll_queue то не забываем что к object_size надо прибавить sizeof(struct ll_entry)
struct memory_pool* memory_pool_init(size_t object_size); struct memory_pool* memory_pool_init(size_t object_size, const char* name);
void memory_pool_destroy(struct memory_pool* pool); void memory_pool_destroy(struct memory_pool* pool);
// элементы пула: // элементы пула:

4
lib/tcp_io.c

@ -46,10 +46,10 @@ struct tcp_conn* tcp_conn_create(
tc->on_error = on_error; tc->on_error = on_error;
tc->arg = arg; tc->arg = arg;
tc->entry_pool = memory_pool_init(sizeof(struct ll_entry)); tc->entry_pool = memory_pool_init(sizeof(struct ll_entry), "entry_pool");
{ {
size_t ds = entry_data_size > write_chunk_size ? entry_data_size : write_chunk_size; size_t ds = entry_data_size > write_chunk_size ? entry_data_size : write_chunk_size;
tc->data_pool = memory_pool_init(ds); tc->data_pool = memory_pool_init(ds, "data_pool");
} }
if (!tc->entry_pool || !tc->data_pool) { if (!tc->entry_pool || !tc->data_pool) {
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "tcp_conn_create: memory_pool_init failed"); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "tcp_conn_create: memory_pool_init failed");

2
lib/u_async.c

@ -1347,7 +1347,7 @@ struct UASYNC* uasync_create(void) {
} }
// Initialize timeout pool // Initialize timeout pool
ua->timeout_pool = memory_pool_init(sizeof(struct timeout_node)); ua->timeout_pool = memory_pool_init(sizeof(struct timeout_node), "timeout_pool");
if (!ua->timeout_pool) { if (!ua->timeout_pool) {
timeout_heap_destroy(ua->timeout_heap); timeout_heap_destroy(ua->timeout_heap);
socket_array_destroy(ua->sockets); socket_array_destroy(ua->sockets);

2
src/dummynet.c

@ -355,7 +355,7 @@ struct dummynet* dummynet_create(struct UASYNC* ua, const char* bind_ip, uint16_
dn->listen_port = listen_port; dn->listen_port = listen_port;
/* Создаём пул для пакетов */ /* Создаём пул для пакетов */
dn->pkt_pool = memory_pool_init(sizeof(struct ll_entry) + sizeof(struct dummynet_pkt)); dn->pkt_pool = memory_pool_init(sizeof(struct ll_entry) + sizeof(struct dummynet_pkt), "pkt_pool");
if (!dn->pkt_pool) { if (!dn->pkt_pool) {
DEBUG_ERROR(DEBUG_CATEGORY_DUMMYNET, "Failed to create packet pool"); DEBUG_ERROR(DEBUG_CATEGORY_DUMMYNET, "Failed to create packet pool");
u_free(dn); u_free(dn);

4
src/etcp.c

@ -205,8 +205,8 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* n
etcp->input_wait_ack = queue_new(instance->ua, INFLIGHT_INITIAL_HASH_SIZE, 0, 4, "input_wait_ack"); // Hash for wait_ack etcp->input_wait_ack = queue_new(instance->ua, INFLIGHT_INITIAL_HASH_SIZE, 0, 4, "input_wait_ack"); // Hash for wait_ack
etcp->recv_q = queue_new(instance->ua, INFLIGHT_INITIAL_HASH_SIZE, 0, 4, "recv_q"); // Hash for recv_q etcp->recv_q = queue_new(instance->ua, INFLIGHT_INITIAL_HASH_SIZE, 0, 4, "recv_q"); // Hash for recv_q
etcp->ack_q = queue_new(instance->ua, INFLIGHT_INITIAL_HASH_SIZE, 0, 4, "ack_q"); etcp->ack_q = queue_new(instance->ua, INFLIGHT_INITIAL_HASH_SIZE, 0, 4, "ack_q");
etcp->inflight_pool = memory_pool_init(sizeof(struct INFLIGHT_PACKET)); etcp->inflight_pool = memory_pool_init(sizeof(struct INFLIGHT_PACKET), "inflight_pool");
etcp->io_pool = memory_pool_init(sizeof(struct ETCP_FRAGMENT)); etcp->io_pool = memory_pool_init(sizeof(struct ETCP_FRAGMENT), "io_pool");
etcp->optimal_inflight=100000; etcp->optimal_inflight=100000;
etcp->initialized=0; etcp->initialized=0;
etcp->links_up=0; etcp->links_up=0;

6
src/lwip_tcp/lwip_tcp.c

@ -95,9 +95,9 @@ struct lwip_tcp_ctx *lwip_tcp_init(struct UASYNC *ua, tcp_output_fn output, void
ctx->ua = ua; ctx->ua = ua;
ctx->output = output; ctx->output = output;
ctx->output_arg = output_arg; ctx->output_arg = output_arg;
ctx->pcb_pool = memory_pool_init(sizeof(struct tcp_pcb)); ctx->pcb_pool = memory_pool_init(sizeof(struct tcp_pcb), "pcb_pool");
ctx->pcb_listen_pool = memory_pool_init(sizeof(struct tcp_pcb_listen)); ctx->pcb_listen_pool = memory_pool_init(sizeof(struct tcp_pcb_listen), "pcb_listen_pool");
ctx->seg_pool = memory_pool_init(sizeof(struct tcp_seg)); ctx->seg_pool = memory_pool_init(sizeof(struct tcp_seg), "seg_pool");
if (!ctx->pcb_pool || !ctx->pcb_listen_pool || !ctx->seg_pool) { if (!ctx->pcb_pool || !ctx->pcb_listen_pool || !ctx->seg_pool) {
lwip_tcp_destroy(ctx); lwip_tcp_destroy(ctx);
return NULL; return NULL;

2
src/proxy/tcp_proxy_client.c

@ -564,7 +564,7 @@ struct tcp_proxy_client* tcp_proxy_client_create(struct UTUN_INSTANCE* inst, str
p->via_node_id = via_node_id; p->via_node_id = via_node_id;
p->mappings = mappings; p->mapping_count = mapping_count; p->mappings = mappings; p->mapping_count = mapping_count;
p->entry_pool = memory_pool_init(sizeof(struct ll_entry)); p->entry_pool = memory_pool_init(sizeof(struct ll_entry), "entry_pool");
if (!p->entry_pool) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "tcp_proxy_client_create: memory_pool_init failed"); u_free(p); return NULL; } if (!p->entry_pool) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "tcp_proxy_client_create: memory_pool_init failed"); u_free(p); return NULL; }
p->tun = tun_init_nat(ua, tun_name, tun_ip, mtu > 0 ? mtu : 1500, test_mode); p->tun = tun_init_nat(ua, tun_name, tun_ip, mtu > 0 ? mtu : 1500, test_mode);

4
src/tun_if.c

@ -161,7 +161,7 @@ struct tun_if* tun_init(struct UASYNC* ua, struct utun_config* config)
tun->test_fd = fds[1]; tun->test_fd = fds[1];
} }
tun->pool = memory_pool_init(sizeof(struct ll_entry)); tun->pool = memory_pool_init(sizeof(struct ll_entry), "tun_pool");
if (!tun->pool) goto fail; if (!tun->pool) goto fail;
tun->output_queue = queue_new(ua, 0, 0, 0, "TUN output"); tun->output_queue = queue_new(ua, 0, 0, 0, "TUN output");
@ -253,7 +253,7 @@ struct tun_if* tun_init_nat(struct UASYNC* ua, const char* ifname, const char* i
tun->test_fd = fds[1]; tun->test_fd = fds[1];
} }
tun->pool = memory_pool_init(sizeof(struct ll_entry)); tun->pool = memory_pool_init(sizeof(struct ll_entry), "tun_pool");
if (!tun->pool) goto fail2; if (!tun->pool) goto fail2;
tun->output_queue = queue_new(ua, 0, 0, 0, "NAT TUN output"); tun->output_queue = queue_new(ua, 0, 0, 0, "NAT TUN output");

6
src/utun_instance.c

@ -83,9 +83,9 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u
} }
// Create memory pools // Create memory pools
instance->ack_pool = memory_pool_init(sizeof(struct ACK_PACKET)); instance->ack_pool = memory_pool_init(sizeof(struct ACK_PACKET), "ack_pool");
instance->data_pool = memory_pool_init(PACKET_DATA_SIZE); instance->data_pool = memory_pool_init(PACKET_DATA_SIZE, "data_pool");
instance->pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM) + PACKET_DATA_SIZE); instance->pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM) + PACKET_DATA_SIZE, "pkt_pool");
// Create routing module // Create routing module
if (routing_create(instance) != 0) { if (routing_create(instance) != 0) {

6
tests/bbr_integration/test_bbr_integration.c

@ -111,9 +111,9 @@ static struct UTUN_INSTANCE* create_instance(struct UASYNC* u, uint64_t node_id,
inst->ua = u; inst->ua = u;
inst->node_id = node_id; inst->node_id = node_id;
if (sc_init_local_keys(&inst->my_keys, pub_hex, priv_hex) != SC_OK) { u_free(inst); return NULL; } if (sc_init_local_keys(&inst->my_keys, pub_hex, priv_hex) != SC_OK) { u_free(inst); return NULL; }
inst->ack_pool = memory_pool_init(sizeof(struct ACK_PACKET)); inst->ack_pool = memory_pool_init(sizeof(struct ACK_PACKET), "ack_pool");
inst->data_pool = memory_pool_init(PACKET_DATA_SIZE); inst->data_pool = memory_pool_init(PACKET_DATA_SIZE, "data_pool");
inst->pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM) + PACKET_DATA_SIZE); inst->pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM) + PACKET_DATA_SIZE, "pkt_pool");
if (!inst->ack_pool || !inst->data_pool || !inst->pkt_pool) { u_free(inst); return NULL; } if (!inst->ack_pool || !inst->data_pool || !inst->pkt_pool) { u_free(inst); return NULL; }
struct utun_config* cfg = u_calloc(1, sizeof(*cfg)); struct utun_config* cfg = u_calloc(1, sizeof(*cfg));
if (!cfg) { u_free(inst); return NULL; } if (!cfg) { u_free(inst); return NULL; }

6
tests/test_etcp_congestion.c

@ -102,9 +102,9 @@ static struct UTUN_INSTANCE* create_instance(struct UASYNC* u, uint64_t node_id,
inst->ua = u; inst->ua = u;
inst->node_id = node_id; inst->node_id = node_id;
if (sc_init_local_keys(&inst->my_keys, pub_hex, priv_hex) != SC_OK) { u_free(inst); return NULL; } if (sc_init_local_keys(&inst->my_keys, pub_hex, priv_hex) != SC_OK) { u_free(inst); return NULL; }
inst->ack_pool = memory_pool_init(sizeof(struct ACK_PACKET)); inst->ack_pool = memory_pool_init(sizeof(struct ACK_PACKET), "ack_pool");
inst->data_pool = memory_pool_init(PACKET_DATA_SIZE); inst->data_pool = memory_pool_init(PACKET_DATA_SIZE, "data_pool");
inst->pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM) + PACKET_DATA_SIZE); inst->pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM) + PACKET_DATA_SIZE, "pkt_pool");
if (!inst->ack_pool || !inst->data_pool || !inst->pkt_pool) { u_free(inst); return NULL; } if (!inst->ack_pool || !inst->data_pool || !inst->pkt_pool) { u_free(inst); return NULL; }
struct utun_config* cfg = u_calloc(1, sizeof(*cfg)); struct utun_config* cfg = u_calloc(1, sizeof(*cfg));
if (!cfg) { u_free(inst); return NULL; } if (!cfg) { u_free(inst); return NULL; }

6
tests/test_etcp_dummynet.c

@ -111,9 +111,9 @@ static struct UTUN_INSTANCE* create_instance(struct UASYNC* u, uint64_t node_id,
return NULL; return NULL;
} }
inst->ack_pool = memory_pool_init(sizeof(struct ACK_PACKET)); inst->ack_pool = memory_pool_init(sizeof(struct ACK_PACKET), "ack_pool");
inst->data_pool = memory_pool_init(PACKET_DATA_SIZE); inst->data_pool = memory_pool_init(PACKET_DATA_SIZE, "data_pool");
inst->pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM) + PACKET_DATA_SIZE); inst->pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM) + PACKET_DATA_SIZE, "pkt_pool");
if (!inst->ack_pool || !inst->data_pool || !inst->pkt_pool) { if (!inst->ack_pool || !inst->data_pool || !inst->pkt_pool) {
u_free(inst); u_free(inst);

6
tests/test_etcp_reinit_inflight.c

@ -53,9 +53,9 @@ static struct UTUN_INSTANCE* create_instance(struct UASYNC* u, uint64_t node_id,
inst->ua = u; inst->ua = u;
inst->node_id = node_id; inst->node_id = node_id;
if (sc_init_local_keys(&inst->my_keys, pub_hex, priv_hex) != SC_OK) { u_free(inst); return NULL; } if (sc_init_local_keys(&inst->my_keys, pub_hex, priv_hex) != SC_OK) { u_free(inst); return NULL; }
inst->ack_pool = memory_pool_init(sizeof(struct ACK_PACKET)); inst->ack_pool = memory_pool_init(sizeof(struct ACK_PACKET), "ack_pool");
inst->data_pool = memory_pool_init(PACKET_DATA_SIZE); inst->data_pool = memory_pool_init(PACKET_DATA_SIZE, "data_pool");
inst->pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM) + PACKET_DATA_SIZE); inst->pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM) + PACKET_DATA_SIZE, "pkt_pool");
if (!inst->ack_pool || !inst->data_pool || !inst->pkt_pool) { u_free(inst); return NULL; } if (!inst->ack_pool || !inst->data_pool || !inst->pkt_pool) { u_free(inst); return NULL; }
struct utun_config* cfg = u_calloc(1, sizeof(*cfg)); struct utun_config* cfg = u_calloc(1, sizeof(*cfg));
if (!cfg) { u_free(inst); return NULL; } if (!cfg) { u_free(inst); return NULL; }

2
tests/test_intensive_memory_pool.c

@ -65,7 +65,7 @@ static double test_with_pools(int iterations) {
struct ll_queue* queue = queue_new(ua, 0, 0, 0,"q2"); // С пулами struct ll_queue* queue = queue_new(ua, 0, 0, 0,"q2"); // С пулами
// Создать пул памяти для данных // Создать пул памяти для данных
struct memory_pool* pool = memory_pool_init(sizeof(struct ll_entry) + 64); struct memory_pool* pool = memory_pool_init(sizeof(struct ll_entry) + 64, "test_pool");
if (!pool) { if (!pool) {
queue_free(queue); queue_free(queue);
uasync_destroy(ua, 0); uasync_destroy(ua, 0);

2
tests/test_ll_queue.c

@ -354,7 +354,7 @@ static void test_limits_hash(void) {
static void test_pool(void) { static void test_pool(void) {
TEST("memory_pool integration + reuse"); TEST("memory_pool integration + reuse");
struct UASYNC *ua = uasync_create(); struct UASYNC *ua = uasync_create();
struct memory_pool *pool = memory_pool_init(sizeof(test_data_t)); struct memory_pool *pool = memory_pool_init(sizeof(test_data_t), "test_data_pool");
struct ll_queue *q = queue_new(ua, 0, 0, 0, "q8"); struct ll_queue *q = queue_new(ua, 0, 0, 0, "q8");
size_t alloc1 = 0, reuse1 = 0; size_t alloc1 = 0, reuse1 = 0;

4
tests/test_pkt_normalizer_standalone.c

@ -185,7 +185,7 @@ static int init_mock_etcp(void) {
mock_etcp.instance = (struct UTUN_INSTANCE*)&mock_instance; mock_etcp.instance = (struct UTUN_INSTANCE*)&mock_instance;
// Create io_pool for ETCP_FRAGMENT allocation // Create io_pool for ETCP_FRAGMENT allocation
mock_etcp.io_pool = memory_pool_init(sizeof(struct ETCP_FRAGMENT)); mock_etcp.io_pool = memory_pool_init(sizeof(struct ETCP_FRAGMENT), "io_pool");
if (!mock_etcp.io_pool) { if (!mock_etcp.io_pool) {
printf("Failed to create io_pool\n"); printf("Failed to create io_pool\n");
return -1; return -1;
@ -271,7 +271,7 @@ int main() {
} }
// Initialize memory pool // Initialize memory pool
mock_instance.data_pool = memory_pool_init(MTU_SIZE); mock_instance.data_pool = memory_pool_init(MTU_SIZE, "data_pool");
if (!mock_instance.data_pool) { if (!mock_instance.data_pool) {
printf("Failed to create memory pool\n"); printf("Failed to create memory pool\n");

Loading…
Cancel
Save