@ -168,37 +168,42 @@ void PacketPoolWait(void)
*
*
* This function only returns when at least N packets are in our pool .
* This function only returns when at least N packets are in our pool .
*
*
* If counting in our pool ' s main stack didn ' t give us the number we
* are seeking , we check if the return stack is filled and add those
* to our main stack . Then we retry .
*
* \ param n number of packets needed
* \ param n number of packets needed
*/
*/
void PacketPoolWaitForN ( int n )
void PacketPoolWaitForN ( int n )
{
{
PktPool * my_pool = GetThreadPacketPool ( ) ;
PktPool * my_pool = GetThreadPacketPool ( ) ;
Packet * p = NULL ;
Packet * p , * pp ;
while ( 1 ) {
while ( 1 ) {
int i = 0 ;
PacketPoolWait ( ) ;
PacketPoolWait ( ) ;
/* count packets in our stack */
/* count packets in our stack */
p = my_pool - > head ;
int i = 0 ;
pp = p = my_pool - > head ;
while ( p ! = NULL ) {
while ( p ! = NULL ) {
if ( + + i = = n )
if ( + + i = = n )
return ;
return ;
pp = p ;
p = p - > next ;
p = p - > next ;
}
}
/* c ontinue counting in the return stack */
/* c heck return stack, return to our pool and retry counting */
if ( my_pool - > return_stack . head ! = NULL ) {
if ( my_pool - > return_stack . head ! = NULL ) {
SCMutexLock ( & my_pool - > return_stack . mutex ) ;
SCMutexLock ( & my_pool - > return_stack . mutex ) ;
p = my_pool - > return_stack . head ;
/* Move all the packets from the locked return stack to the local stack. */
while ( p ! = NULL ) {
if ( pp ) {
if ( + + i = = n ) {
pp - > next = my_pool - > return_stack . head ;
SCMutexUnlock ( & my_pool - > return_stack . mutex ) ;
} else {
return ;
my_pool - > head = my_pool - > return_stack . head ;
}
p = p - > next ;
}
}
my_pool - > return_stack . head = NULL ;
SC_ATOMIC_RESET ( my_pool - > return_stack . sync_now ) ;
SCMutexUnlock ( & my_pool - > return_stack . mutex ) ;
SCMutexUnlock ( & my_pool - > return_stack . mutex ) ;
/* or signal that we need packets and wait */
/* or signal that we need packets and wait */
@ -559,6 +564,12 @@ void TmqhReleasePacketsToPacketPool(PacketQueue *pq)
return ;
return ;
}
}
/** number of packets to keep reserved when calculating the the pending
* return packets count . This assumes we need at max 10 packets in one
* PacketPoolWaitForN call . The actual number is 9 now , so this has a
* bit of margin . */
# define RESERVED_PACKETS 10
/**
/**
* \ brief Set the max_pending_return_packets value
* \ brief Set the max_pending_return_packets value
*
*
@ -575,17 +586,23 @@ void TmqhReleasePacketsToPacketPool(PacketQueue *pq)
void PacketPoolPostRunmodes ( void )
void PacketPoolPostRunmodes ( void )
{
{
extern intmax_t max_pending_packets ;
extern intmax_t max_pending_packets ;
intmax_t pending_packets = max_pending_packets ;
if ( pending_packets < RESERVED_PACKETS ) {
FatalError ( SC_ERR_INVALID_ARGUMENT , " 'max-pending-packets' setting "
" must be at least %d " , RESERVED_PACKETS ) ;
}
uint32_t threads = TmThreadCountThreadsByTmmFlags ( TM_FLAG_DETECT_TM ) ;
uint32_t threads = TmThreadCountThreadsByTmmFlags ( TM_FLAG_DETECT_TM ) ;
if ( threads = = 0 )
if ( threads = = 0 )
return ;
return ;
if ( threads > max_pending_packets )
return ;
uint32_t packets = ( max_ pending_packets / threads ) - 1 ;
uint32_t packets = ( pending_packets / threads ) - 1 ;
if ( packets < max_pending_return_packets )
if ( packets < max_pending_return_packets )
max_pending_return_packets = packets ;
max_pending_return_packets = packets ;
/* make sure to have a margin in the return logic */
if ( max_pending_return_packets > = RESERVED_PACKETS )
max_pending_return_packets - = RESERVED_PACKETS ;
SCLogDebug ( " detect threads %u, max packets %u, max_pending_return_packets %u " ,
SCLogDebug ( " detect threads %u, max packets %u, max_pending_return_packets %u " ,
threads , threads , max_pending_return_packets ) ;
threads , packet s, max_pending_return_packets ) ;
}
}