@@ -530,20 +530,53 @@ static int ConfigSetTxQueues(
530530 SCReturnInt (0 );
531531}
532532
533- static uint32_t MempoolSizeCalculate (
533+ static uint32_t MempoolSizeCalculateAutosize (
534534 const DPDKIfaceConfig * iconf , const struct rte_eth_dev_info * dev_info )
535535{
536- uint32_t sz = iconf -> nb_rx_queues * iconf -> nb_rx_desc + iconf -> nb_tx_queues * iconf -> nb_tx_desc ;
537- if (! iconf -> nb_tx_queues || ! iconf -> nb_tx_desc )
538- sz *= 2 ; // double to have enough space for RX descriptors
536+ uint32_t next_p2 =
537+ rte_align32pow2 ( iconf -> nb_rx_desc + iconf -> nb_tx_desc +
538+ 1 ) ; // + 1 in case number of descriptors is already a power of 2
539539
540+ uint32_t mp_size = next_p2 ;
540541 if (dev_info != NULL ) {
541542 if (strcmp (dev_info -> driver_name , "net_bonding" ) == 0 ) {
542- sz = BondingMempoolSizeCalculate (iconf -> port_id , dev_info , sz );
543+ mp_size = BondingMempoolSizeCalculate (iconf -> port_id , dev_info , mp_size );
543544 }
544545 }
545546
546- return sz ;
547+ return mp_size -
548+ 1 ; // mempool size should be n = (2^q - 1) to have all descriptors available for use
549+ }
550+
551+ static uint32_t MempoolSizeDistributeToQueues (uint32_t global_mp_size , uint16_t nic_queues )
552+ {
553+ if (nic_queues == 0 ) {
554+ return 0 ;
555+ }
556+
557+ uint32_t mp_size_per_queue = global_mp_size / nic_queues ;
558+ if (mp_size_per_queue == 0 ) {
559+ return 0 ;
560+ }
561+
562+ uint32_t next_p2 = rte_align32pow2 (mp_size_per_queue );
563+ return (mp_size_per_queue == next_p2 || mp_size_per_queue == next_p2 - 1 )
564+ ? next_p2 - 1
565+ : (next_p2 >> 1 ) - 1 ; // we must fit in the globally specified mempool size
566+ }
567+
568+ static uint32_t MempoolSizeCalculateMinimal (
569+ const DPDKIfaceConfig * iconf , const struct rte_eth_dev_info * dev_info )
570+ {
571+ uint32_t mp_size =
572+ rte_align32pow2 (iconf -> nb_rx_desc + iconf -> nb_tx_desc +
573+ 1 ); // + 1 in case number of descriptors is already a power of 2
574+ if (dev_info != NULL ) {
575+ if (strcmp (dev_info -> driver_name , "net_bonding" ) == 0 ) {
576+ mp_size = BondingMempoolSizeCalculate (iconf -> port_id , dev_info , mp_size );
577+ }
578+ }
579+ return mp_size - 1 ;
547580}
548581
549582static int ConfigSetMempoolSize (
@@ -571,27 +604,30 @@ static int ConfigSetMempoolSize(
571604 SCReturnInt (- EINVAL );
572605 }
573606
574- iconf -> mempool_size = MempoolSizeCalculate (iconf , dev_info );
607+ iconf -> queue_mempool_size = MempoolSizeCalculateAutosize (iconf , dev_info );
575608 SCReturnInt (0 );
576609 }
577610
578- if (StringParseUint32 (& iconf -> mempool_size , 10 , 0 , entry_str ) < 0 ) {
611+ uint32_t global_mempool_size ;
612+ if (StringParseUint32 (& global_mempool_size , 10 , 0 , entry_str ) < 0 ) {
579613 SCLogError ("%s: mempool size entry contain non-numerical characters - \"%s\"" , iconf -> iface ,
580614 entry_str );
581615 SCReturnInt (- EINVAL );
582616 }
583617
584- uint32_t required_mp_size = MempoolSizeCalculate (iconf , dev_info );
585- if (required_mp_size >
586- iconf -> mempool_size + 1 ) { // +1 to mask mempool size advice given in Suricata 7.0.x -
587- // mp_size should be n = (2^q - 1)
618+ iconf -> queue_mempool_size =
619+ MempoolSizeDistributeToQueues (global_mempool_size , iconf -> nb_rx_queues );
620+ uint32_t required_mp_size = MempoolSizeCalculateMinimal (iconf , dev_info );
621+ if (required_mp_size > iconf -> queue_mempool_size ) {
622+ uint32_t required_global_mp_size =
623+ required_mp_size * iconf -> nb_rx_queues + iconf -> nb_rx_queues - 1 ;
588624 SCLogError ("%s: mempool size is likely too small for the number of descriptors and queues, "
589625 "set to \"auto\" or adjust to the value of \"%" PRIu32 "\"" ,
590- iconf -> iface , required_mp_size );
626+ iconf -> iface , required_global_mp_size );
591627 SCReturnInt (- ERANGE );
592628 }
593629
594- if (iconf -> mempool_size == 0 ) {
630+ if (iconf -> queue_mempool_size == 0 ) {
595631 SCLogError ("%s: mempool size requires a positive integer" , iconf -> iface );
596632 SCReturnInt (- ERANGE );
597633 }
@@ -613,9 +649,9 @@ static int ConfigSetMempoolCacheSize(DPDKIfaceConfig *iconf, const char *entry_s
613649 SCEnter ();
614650 if (entry_str == NULL || entry_str [0 ] == '\0' || strcmp (entry_str , "auto" ) == 0 ) {
615651 // calculate the mempool size based on the mempool size (it needs to be already filled in)
616- if (iconf -> mempool_size == 0 ) {
617- SCLogError ("%s: cannot calculate mempool cache size of a mempool with size %d" ,
618- iconf -> iface , iconf -> mempool_size );
652+ if (iconf -> queue_mempool_size == 0 ) {
653+ SCLogError ("%s: cannot calculate mempool cache size of a mempool with size %" PRIu32 ,
654+ iconf -> iface , iconf -> queue_mempool_size );
619655 SCReturnInt (- EINVAL );
620656 }
621657
@@ -1459,20 +1495,16 @@ static int DeviceConfigureQueues(DPDKIfaceConfig *iconf, const struct rte_eth_de
14591495 // +4 for VLAN header
14601496 uint16_t mtu_size = iconf -> mtu + RTE_ETHER_CRC_LEN + RTE_ETHER_HDR_LEN + 4 ;
14611497 uint16_t mbuf_size = ROUNDUP (mtu_size , 1024 ) + RTE_PKTMBUF_HEADROOM ;
1462- // Follows DPDK recommendation of having a mempool size that is a power of 2 minus one.
1463- // So e.g. mp_size of 262144 and 262143 both lead to 65535 on 4 rx queues
1464- uint32_t raw = iconf -> mempool_size / iconf -> nb_rx_queues ;
1465- uint32_t next_p2 = rte_align32pow2 (raw + 1 );
1466- uint32_t q_mp_sz = (next_p2 == raw + 1 ) ? raw : (next_p2 >> 1 ) - 1 ;
1467- uint32_t q_mp_cache_sz = iconf -> mempool_cache_size_auto ? MempoolCacheSizeCalculate (q_mp_sz )
1468- : iconf -> mempool_cache_size ;
1498+ uint32_t q_mp_cache_sz = iconf -> mempool_cache_size_auto
1499+ ? MempoolCacheSizeCalculate (iconf -> queue_mempool_size )
1500+ : iconf -> mempool_cache_size ;
14691501 SCLogInfo ("%s: creating %u packet mempools of size %u, cache size %u, mbuf size %u" ,
1470- iconf -> iface , iconf -> nb_rx_queues , q_mp_sz , q_mp_cache_sz , mbuf_size );
1502+ iconf -> iface , iconf -> nb_rx_queues , iconf -> queue_mempool_size , q_mp_cache_sz , mbuf_size );
14711503 for (int i = 0 ; i < iconf -> nb_rx_queues ; i ++ ) {
14721504 char mempool_name [64 ];
14731505 snprintf (mempool_name , sizeof (mempool_name ), "mp_%d_%.20s" , i , iconf -> iface );
1474- iconf -> pkt_mempools -> pkt_mp [i ] = rte_pktmbuf_pool_create (
1475- mempool_name , q_mp_sz , q_mp_cache_sz , 0 , mbuf_size , (int )iconf -> socket_id );
1506+ iconf -> pkt_mempools -> pkt_mp [i ] = rte_pktmbuf_pool_create (mempool_name ,
1507+ iconf -> queue_mempool_size , q_mp_cache_sz , 0 , mbuf_size , (int )iconf -> socket_id );
14761508 if (iconf -> pkt_mempools -> pkt_mp [i ] == NULL ) {
14771509 retval = - rte_errno ;
14781510 SCLogError ("%s: rte_pktmbuf_pool_create failed with code %d (mempool: %s) - %s" ,
0 commit comments