From 4157d9408d6e7f10c1d82e43d4360ce36ce032bf Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 22 Mar 2012 11:53:35 +0100 Subject: [PATCH] Various small flow and host table fixes. --- src/flow-hash.c | 2 +- src/flow-manager.c | 2 +- src/flow-util.c | 2 +- src/flow-util.h | 10 ++++++++++ src/flow.c | 20 ++++++++++++-------- src/host.c | 20 ++++++++++++-------- src/host.h | 10 ++++++++++ src/util-error.c | 2 ++ src/util-error.h | 2 ++ 9 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/flow-hash.c b/src/flow-hash.c index 0b6fcb2e7d..3c8604b46c 100644 --- a/src/flow-hash.c +++ b/src/flow-hash.c @@ -309,7 +309,7 @@ static Flow *FlowGetNew(Packet *p) { f = FlowDequeue(&flow_spare_q); if (f == NULL) { /* If we reached the max memcap, we get a used flow */ - if ((SC_ATOMIC_GET(flow_memuse) + sizeof(Flow)) > flow_config.memcap) { + if (!(FLOW_CHECK_MEMCAP(sizeof(Flow)))) { /* declare state of emergency */ if (!(SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)) { SC_ATOMIC_OR(flow_flags, FLOW_EMERGENCY); diff --git a/src/flow-manager.c b/src/flow-manager.c index c13bd67acd..e6dabceade 100644 --- a/src/flow-manager.c +++ b/src/flow-manager.c @@ -800,7 +800,7 @@ static int FlowMgrTest05 (void) { UTHBuildPacketOfFlows(ini, end, 0); /* And now let's try to reach the memcap val */ - while (SC_ATOMIC_GET(flow_memuse) + sizeof(Flow) < flow_config.memcap) { + while (FLOW_CHECK_MEMCAP(sizeof(Flow))) { ini = end + 1; end = end + 2; UTHBuildPacketOfFlows(ini, end, 0); diff --git a/src/flow-util.c b/src/flow-util.c index 71016c997a..bfa6ebcbe3 100644 --- a/src/flow-util.c +++ b/src/flow-util.c @@ -49,7 +49,7 @@ Flow *FlowAlloc(void) { Flow *f; - if ((SC_ATOMIC_GET(flow_memuse) + sizeof(Flow)) > flow_config.memcap) { + if (!(FLOW_CHECK_MEMCAP(sizeof(Flow)))) { return NULL; } diff --git a/src/flow-util.h b/src/flow-util.h index a8d4dd5820..b1315e714d 100644 --- a/src/flow-util.h +++ b/src/flow-util.h @@ -115,6 +115,16 @@ (f)->tag_list = NULL; \ } while(0) +/** \brief check if a memory alloc would fit in the memcap + * + * \param size memory allocation size to check + * + * \retval 1 it fits + * \retval 0 no fit + */ +#define FLOW_CHECK_MEMCAP(size) \ + ((((uint64_t)SC_ATOMIC_GET(flow_memuse) + (uint64_t)(size)) <= flow_config.memcap)) + Flow *FlowAlloc(void); Flow *FlowAllocDirect(void); void FlowFree(Flow *); diff --git a/src/flow.c b/src/flow.c index c11517b587..2bc884a329 100644 --- a/src/flow.c +++ b/src/flow.c @@ -413,16 +413,20 @@ void FlowInitConfig(char quiet) /* pre allocate flows */ for (i = 0; i < flow_config.prealloc; i++) { - if ((SC_ATOMIC_GET(flow_memuse) + sizeof(Flow)) > flow_config.memcap) { - printf("ERROR: FlowAlloc failed (max flow memcap reached): %s\n", strerror(errno)); - exit(1); + if (!(FLOW_CHECK_MEMCAP(sizeof(Flow)))) { + SCLogError(SC_ERR_FLOW_INIT, "preallocating flows failed: " + "max flow memcap reached. Memcap %"PRIu64", " + "Memuse %"PRIu64".", flow_config.memcap, + ((uint64_t)SC_ATOMIC_GET(flow_memuse) + (uint64_t)sizeof(Flow))); + exit(EXIT_FAILURE); } Flow *f = FlowAlloc(); if (f == NULL) { - printf("ERROR: FlowAlloc failed: %s\n", strerror(errno)); - exit(1); + SCLogError(SC_ERR_FLOW_INIT, "preallocating flow failed: %s", strerror(errno)); + exit(EXIT_FAILURE); } + FlowEnqueue(&flow_spare_q,f); } @@ -947,7 +951,7 @@ static int FlowTest07 (void) { UTHBuildPacketOfFlows(ini, end, 0); /* And now let's try to reach the memcap val */ - while (SC_ATOMIC_GET(flow_memuse) + sizeof(Flow) < flow_config.memcap) { + while (FLOW_CHECK_MEMCAP(sizeof(Flow))) { ini = end + 1; end = end + 2; UTHBuildPacketOfFlows(ini, end, 0); @@ -994,7 +998,7 @@ static int FlowTest08 (void) { UTHBuildPacketOfFlows(ini, end, 0); /* And now let's try to reach the memcap val */ - while (SC_ATOMIC_GET(flow_memuse) + sizeof(Flow) < flow_config.memcap) { + while (FLOW_CHECK_MEMCAP(sizeof(Flow))) { ini = end + 1; end = end + 2; UTHBuildPacketOfFlows(ini, end, 0); @@ -1041,7 +1045,7 @@ static int FlowTest09 (void) { UTHBuildPacketOfFlows(ini, end, 0); /* And now let's try to reach the memcap val */ - while (SC_ATOMIC_GET(flow_memuse) + sizeof(Flow) < flow_config.memcap) { + while (FLOW_CHECK_MEMCAP(sizeof(Flow))) { ini = end + 1; end = end + 2; UTHBuildPacketOfFlows(ini, end, 0); diff --git a/src/host.c b/src/host.c index 2e24c8a31a..5737d5a1fc 100644 --- a/src/host.c +++ b/src/host.c @@ -53,7 +53,7 @@ void HostMoveToSpare(Host *h) { } Host *HostAlloc(void) { - if ((SC_ATOMIC_GET(host_memuse) + sizeof(Host)) > host_config.memcap) { + if (!(HOST_CHECK_MEMCAP(sizeof(Host)))) { return NULL; } @@ -119,6 +119,7 @@ void HostInitConfig(char quiet) memset(&host_config, 0, sizeof(host_config)); //SC_ATOMIC_INIT(flow_flags); + SC_ATOMIC_INIT(host_counter); SC_ATOMIC_INIT(host_memuse); SC_ATOMIC_INIT(host_prune_idx); HostQueueInit(&host_spare_q); @@ -187,15 +188,18 @@ void HostInitConfig(char quiet) /* pre allocate hosts */ for (i = 0; i < host_config.prealloc; i++) { - if ((SC_ATOMIC_GET(host_memuse) + sizeof(Host)) > host_config.memcap) { - printf("ERROR: HostAlloc failed (max host memcap reached): %s\n", strerror(errno)); - exit(1); + if (!(HOST_CHECK_MEMCAP(sizeof(Host)))) { + SCLogError(SC_ERR_HOST_INIT, "preallocating hosts failed: " + "max host memcap reached. Memcap %"PRIu64", " + "Memuse %"PRIu64".", host_config.memcap, + ((uint64_t)SC_ATOMIC_GET(host_memuse) + (uint64_t)sizeof(Host))); + exit(EXIT_FAILURE); } Host *h = HostAlloc(); if (h == NULL) { - printf("ERROR: HostAlloc failed: %s\n", strerror(errno)); - exit(1); + SCLogError(SC_ERR_HOST_INIT, "preallocating host failed: %s", strerror(errno)); + exit(EXIT_FAILURE); } HostEnqueue(&host_spare_q,h); } @@ -257,6 +261,7 @@ void HostShutdown(void) SC_ATOMIC_DESTROY(host_prune_idx); SC_ATOMIC_DESTROY(host_memuse); + SC_ATOMIC_DESTROY(host_counter); //SC_ATOMIC_DESTROY(flow_flags); return; } @@ -306,7 +311,7 @@ static Host *HostGetNew(Address *a) { h = HostDequeue(&host_spare_q); if (h == NULL) { /* If we reached the max memcap, we get a used host */ - if ((SC_ATOMIC_GET(host_memuse) + sizeof(Host)) > host_config.memcap) { + if (!(HOST_CHECK_MEMCAP(sizeof(Host)))) { /* declare state of emergency */ //if (!(SC_ATOMIC_GET(host_flags) & HOST_EMERGENCY)) { // SC_ATOMIC_OR(host_flags, HOST_EMERGENCY); @@ -349,7 +354,6 @@ static Host *HostGetNew(Address *a) { (h)->use_cnt-- void HostInit(Host *h, Address *a) { -// SCMutexLock(&h->m); COPY_ADDRESS(a, &h->a); HostIncrUsecnt(h); } diff --git a/src/host.h b/src/host.h index a4603e5b2d..e3610b8129 100644 --- a/src/host.h +++ b/src/host.h @@ -96,6 +96,16 @@ typedef struct HostConfig_ { uint32_t prealloc; } HostConfig; +/** \brief check if a memory alloc would fit in the memcap + * + * \param size memory allocation size to check + * + * \retval 1 it fits + * \retval 0 no fit + */ +#define HOST_CHECK_MEMCAP(size) \ + ((((uint64_t)SC_ATOMIC_GET(host_memuse) + (uint64_t)(size)) <= host_config.memcap)) + HostConfig host_config; SC_ATOMIC_DECLARE(unsigned long long int,host_memuse); SC_ATOMIC_DECLARE(unsigned int,host_counter); diff --git a/src/util-error.c b/src/util-error.c index 450fbba0df..e39131cc04 100644 --- a/src/util-error.c +++ b/src/util-error.c @@ -223,6 +223,8 @@ const char * SCErrorToString(SCError err) CASE_CODE (SC_WARN_OUTDATED_LIBHTP); CASE_CODE (SC_WARN_DEPRECATED); CASE_CODE (SC_WARN_PROFILE); + CASE_CODE (SC_ERR_FLOW_INIT); + CASE_CODE (SC_ERR_HOST_INIT); default: return "UNKNOWN_ERROR"; diff --git a/src/util-error.h b/src/util-error.h index ee0063a869..1bd80a7096 100644 --- a/src/util-error.h +++ b/src/util-error.h @@ -238,6 +238,8 @@ typedef enum { SC_WARN_OUTDATED_LIBHTP, SC_WARN_DEPRECATED, SC_WARN_PROFILE, + SC_ERR_FLOW_INIT, + SC_ERR_HOST_INIT, } SCError; const char *SCErrorToString(SCError); -- 2.47.2