From 28ccea51d36a38bec124cc44b0e011621619d05d Mon Sep 17 00:00:00 2001 From: Ken Steele Date: Wed, 2 Jul 2014 10:42:05 -0400 Subject: [PATCH] Add error checking for pthread_setspecific() and pthread_key_create(). --- src/counters.c | 3 +- src/flow-manager.c | 1 + src/source-af-packet.c | 2 -- src/source-erf-dag.c | 2 -- src/source-erf-file.c | 2 -- src/source-ipfw.c | 2 -- src/source-mpipe.c | 2 -- src/source-napatech.c | 2 -- src/source-nfq.c | 2 -- src/source-pcap-file.c | 2 -- src/source-pcap.c | 2 -- src/source-pfring.c | 2 -- src/tm-threads.c | 10 +++++++ src/tmqh-packetpool.c | 65 ++++++++++++++++++++++++++---------------- 14 files changed, 53 insertions(+), 46 deletions(-) diff --git a/src/counters.c b/src/counters.c index fce1069080..9aae1fe52d 100644 --- a/src/counters.c +++ b/src/counters.c @@ -340,7 +340,7 @@ static void *SCPerfMgmtThread(void *arg) tv_local->cap_flags = 0; SCDropCaps(tv_local); - + PacketPoolInit(); if (sc_perf_op_ctx == NULL) { SCLogError(SC_ERR_PERF_STATS_NOT_INIT, "Perf Counter API not init" @@ -409,6 +409,7 @@ static void *SCPerfWakeupThread(void *arg) tv_local->cap_flags = 0; SCDropCaps(tv_local); + PacketPoolInit(); if (sc_perf_op_ctx == NULL) { SCLogError(SC_ERR_PERF_STATS_NOT_INIT, "Perf Counter API not init" diff --git a/src/flow-manager.c b/src/flow-manager.c index 9038888219..71bf2e0a49 100644 --- a/src/flow-manager.c +++ b/src/flow-manager.c @@ -441,6 +441,7 @@ void *FlowManagerThread(void *td) /* Set the threads capability */ th_v->cap_flags = 0; SCDropCaps(th_v); + PacketPoolInit(); FlowHashDebugInit(); diff --git a/src/source-af-packet.c b/src/source-af-packet.c index 99acb86801..dd817468ae 100644 --- a/src/source-af-packet.c +++ b/src/source-af-packet.c @@ -1781,8 +1781,6 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) { ptv->vlan_disabled = 1; } - PacketPoolInit(); - SCReturnInt(TM_ECODE_OK); } diff --git a/src/source-erf-dag.c b/src/source-erf-dag.c index 8eef943d43..e4202b41e0 100644 --- a/src/source-erf-dag.c +++ b/src/source-erf-dag.c @@ -316,8 +316,6 @@ ReceiveErfDagThreadInit(ThreadVars *tv, void *initdata, void **data) SCLogInfo("Starting processing packets from stream: %d on DAG: %s", ewtn->dagstream, ewtn->dagname); - PacketPoolInit(); - SCReturnInt(TM_ECODE_OK); } diff --git a/src/source-erf-file.c b/src/source-erf-file.c index 81305b8a0a..1a35f4d650 100644 --- a/src/source-erf-file.c +++ b/src/source-erf-file.c @@ -234,8 +234,6 @@ ReceiveErfFileThreadInit(ThreadVars *tv, void *initdata, void **data) etv->tv = tv; *data = (void *)etv; - PacketPoolInit(); - SCLogInfo("Processing ERF file %s", (char *)initdata); SCReturnInt(TM_ECODE_OK); diff --git a/src/source-ipfw.c b/src/source-ipfw.c index 60192361b5..f3b64bd35f 100644 --- a/src/source-ipfw.c +++ b/src/source-ipfw.c @@ -374,8 +374,6 @@ TmEcode ReceiveIPFWThreadInit(ThreadVars *tv, void *initdata, void **data) *data = (void *)ntv; - PacketPoolInit(); - SCReturnInt(TM_ECODE_OK); } diff --git a/src/source-mpipe.c b/src/source-mpipe.c index 382ed63f99..061cb1e1ff 100644 --- a/src/source-mpipe.c +++ b/src/source-mpipe.c @@ -898,8 +898,6 @@ TmEcode ReceiveMpipeThreadInit(ThreadVars *tv, void *initdata, void **data) *data = (void *)ptv; - PacketPoolInit(); - /* Only rank 0 does initialization of mpipe */ if (rank != 0) SCReturnInt(TM_ECODE_OK); diff --git a/src/source-napatech.c b/src/source-napatech.c index 60f9f246ce..1e4a4068e5 100644 --- a/src/source-napatech.c +++ b/src/source-napatech.c @@ -171,8 +171,6 @@ TmEcode NapatechStreamThreadInit(ThreadVars *tv, void *initdata, void **data) *data = (void *)ntv; - PacketPoolInit(); - SCReturnInt(TM_ECODE_OK); } diff --git a/src/source-nfq.c b/src/source-nfq.c index 7c6359a31e..8a6c9f5b2d 100644 --- a/src/source-nfq.c +++ b/src/source-nfq.c @@ -718,8 +718,6 @@ TmEcode ReceiveNFQThreadInit(ThreadVars *tv, void *initdata, void **data) { *data = (void *)ntv; - PacketPoolInit(); - SCMutexUnlock(&nfq_init_lock); return TM_ECODE_OK; } diff --git a/src/source-pcap-file.c b/src/source-pcap-file.c index ee7418d1c6..0d6f9a74ed 100644 --- a/src/source-pcap-file.c +++ b/src/source-pcap-file.c @@ -341,8 +341,6 @@ TmEcode ReceivePcapFileThreadInit(ThreadVars *tv, void *initdata, void **data) { ptv->tv = tv; *data = (void *)ptv; - PacketPoolInit(); - SCReturnInt(TM_ECODE_OK); } diff --git a/src/source-pcap.c b/src/source-pcap.c index 2b13d21dd3..f116da3fbe 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -638,8 +638,6 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { *data = (void *)ptv; - PacketPoolInit(); - /* Dereference config */ pcapconfig->DerefFunc(pcapconfig); SCReturnInt(TM_ECODE_OK); diff --git a/src/source-pfring.c b/src/source-pfring.c index 5735d3ec3a..4a17a92ca7 100644 --- a/src/source-pfring.c +++ b/src/source-pfring.c @@ -540,8 +540,6 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) { *data = (void *)ptv; pfconf->DerefFunc(pfconf); - PacketPoolInit(); - return TM_ECODE_OK; } diff --git a/src/tm-threads.c b/src/tm-threads.c index 18ec35e578..ec51ba21d7 100644 --- a/src/tm-threads.c +++ b/src/tm-threads.c @@ -142,6 +142,8 @@ void *TmThreadsSlot1NoIn(void *td) /* Drop the capabilities for this thread */ SCDropCaps(tv); + PacketPoolInit(); + if (s->SlotThreadInit != NULL) { void *slot_data = NULL; r = s->SlotThreadInit(tv, s->slot_initdata, &slot_data); @@ -252,6 +254,8 @@ void *TmThreadsSlot1NoOut(void *td) /* Drop the capabilities for this thread */ SCDropCaps(tv); + PacketPoolInit(); + if (s->SlotThreadInit != NULL) { void *slot_data = NULL; r = s->SlotThreadInit(tv, s->slot_initdata, &slot_data); @@ -343,6 +347,8 @@ void *TmThreadsSlot1NoInOut(void *td) /* Drop the capabilities for this thread */ SCDropCaps(tv); + PacketPoolInit(); + SCLogDebug("%s starting", tv->name); if (s->SlotThreadInit != NULL) { @@ -431,6 +437,8 @@ void *TmThreadsSlot1(void *td) /* Drop the capabilities for this thread */ SCDropCaps(tv); + PacketPoolInit(); + SCLogDebug("%s starting", tv->name); if (s->SlotThreadInit != NULL) { @@ -650,6 +658,8 @@ void *TmThreadsSlotPktAcqLoop(void *td) { /* Drop the capabilities for this thread */ SCDropCaps(tv); + PacketPoolInit(); + /* check if we are setup properly */ if (s == NULL || s->PktAcqLoop == NULL || tv->tmqh_in == NULL || tv->tmqh_out == NULL) { SCLogError(SC_ERR_FATAL, "TmSlot or ThreadVars badly setup: s=%p," diff --git a/src/tmqh-packetpool.c b/src/tmqh-packetpool.c index 9acd490dd2..b816f4a974 100644 --- a/src/tmqh-packetpool.c +++ b/src/tmqh-packetpool.c @@ -48,6 +48,9 @@ #include "util-profiling.h" #include "util-device.h" +/* Number of freed packet to save for one pool before freeing them. */ +#define MAX_PENDING_RETURN_PACKETS 32 + #ifdef TLS __thread PktPool thread_pkt_pool; @@ -58,22 +61,51 @@ static inline PktPool *GetThreadPacketPool(void) static inline PktPool *ThreadPacketPoolCreate(void) { - /* Nothing to do since __thread allocates the memory. */ + /* Nothing to do since __thread statically allocates the memory. */ return GetThreadPacketPool(); } - - #else /* __thread not supported. */ static pthread_key_t pkt_pool_thread_key; +static SCMutex pkt_pool_thread_key_mutex = SCMUTEX_INITIALIZER; +static int pkt_pool_thread_key_initialized = 0; static inline PktPool *GetThreadPacketPool(void) { return (PktPool*)pthread_getspecific(pkt_pool_thread_key); } +static void PktPoolThreadDestroy(void * buf) +{ + free(buf); +} + +static void TmqhPacketpoolInit(void) +{ + SCMutexLock(&pkt_pool_thread_key_mutex); + if (pkt_pool_thread_key_initialized) { + /* Key has already been created. */ + SCMutexUnlock(&pkt_pool_thread_key_mutex); + return; + } + + /* Create the pthread Key that is used to look up thread specific + * data buffer. Needs to be created only once. + */ + int r = pthread_key_create(&pkt_pool_thread_key, PktPoolThreadDestroy); + if (r != 0) { + SCLogError(SC_ERR_MEM_ALLOC, "pthread_key_create failed with %d", r); + exit(EXIT_FAILURE); + } + + pkt_pool_thread_key_initialized = 1; + SCMutexUnlock(&pkt_pool_thread_key_mutex); +} + static inline PktPool *ThreadPacketPoolCreate(void) { + TmqhPacketpoolInit(); + /* Check that the pool is not already created */ PktPool *pool = GetThreadPacketPool(); if (pool) @@ -85,30 +117,15 @@ static inline PktPool *ThreadPacketPoolCreate(void) SCLogError(SC_ERR_MEM_ALLOC, "malloc failed"); exit(EXIT_FAILURE); } - pthread_setspecific(pkt_pool_thread_key, pool); + int r = pthread_setspecific(pkt_pool_thread_key, pool); + if (r != 0) { + SCLogError(SC_ERR_MEM_ALLOC, "pthread_setspecific failed with %d", r); + exit(EXIT_FAILURE); + } return pool; } - -static void PktPoolThreadDestroy(void * buf) -{ - free(buf); -} - -#endif - -/* Number of freed packet to save for one pool before freeing them. */ -#define MAX_PENDING_RETURN_PACKETS 32 - -void TmqhPacketpoolInit(void) -{ -#ifndef TLS - /* Create the pthread Key that is used to look up thread specific - * data buffer. Needs to be created only once. - */ - pthread_key_create(&pkt_pool_thread_key, PktPoolThreadDestroy); #endif -} /** * \brief TmqhPacketpoolRegister @@ -118,8 +135,6 @@ void TmqhPacketpoolRegister (void) { tmqh_table[TMQH_PACKETPOOL].name = "packetpool"; tmqh_table[TMQH_PACKETPOOL].InHandler = TmqhInputPacketpool; tmqh_table[TMQH_PACKETPOOL].OutHandler = TmqhOutputPacketpool; - - TmqhPacketpoolInit(); } static int PacketPoolIsEmpty(PktPool *pool)