dpdk: add hugepage hint to lower the amount of reserved hugepages

If a user allocates too many hugepages and those are largely not used
then Suricata suggests that the user can lower the amount of hugepages
and therefore save memory for other purposes.

Ticket: #5966
pull/9637/head
Lukas Sismis 3 years ago committed by Victor Julien
parent cf8b630ed2
commit 1bcea5a992

@ -137,6 +137,7 @@
AC_CHECK_HEADERS([getopt.h])
AC_CHECK_HEADERS([limits.h netdb.h netinet/in.h poll.h sched.h signal.h])
AC_CHECK_HEADERS([stdarg.h stdint.h stdio.h stdlib.h stdbool.h string.h strings.h sys/ioctl.h])
AC_CHECK_HEADERS([math.h])
AC_CHECK_HEADERS([syslog.h sys/prctl.h sys/socket.h sys/stat.h sys/syscall.h])
AC_CHECK_HEADERS([sys/time.h time.h unistd.h sys/param.h])
AC_CHECK_HEADERS([sys/ioctl.h linux/if_ether.h linux/if_packet.h linux/filter.h])

@ -280,6 +280,10 @@ typedef unsigned char u_char;
#include <magic.h>
#endif
#ifdef HAVE_MATH_H
#include <math.h>
#endif
/* we need this to stringify the defines which are supplied at compiletime see:
http://gcc.gnu.org/onlinedocs/gcc-3.4.1/cpp/Stringification.html#Stringification */
#define xstr(s) str(s)

@ -3037,6 +3037,8 @@ int SuricataMain(int argc, char **argv)
PostRunStartedDetectSetup(&suricata);
DPDKEvaluateHugepages();
SCPledge();
SuricataMainLoop(&suricata);

@ -24,6 +24,7 @@
#include "suricata.h"
#include "util-dpdk.h"
#include "util-debug.h"
#include "util-byte.h"
void DPDKCleanupEAL(void)
{
@ -65,6 +66,104 @@ void DPDKFreeDevice(LiveDevice *ldev)
#endif
}
static FILE *HugepagesMeminfoOpen(void)
{
FILE *fp = fopen("/proc/meminfo", "r");
if (fp == NULL) {
SCLogInfo("Can't analyze hugepage usage: failed to open /proc/meminfo");
}
return fp;
}
static void HugepagesMeminfoClose(FILE *fp)
{
if (fp) {
fclose(fp);
}
}
/**
* Parsing values of meminfo
*
* \param fp Opened file pointer for reading of file /proc/meminfo at beginning
* \param keyword Entry to look for e.g. "HugePages_Free:"
* \return n Value of the entry
* \return -1 On error
*
*/
static int32_t MemInfoParseValue(FILE *fp, const char *keyword)
{
char path[256], value_str[64];
int32_t value = -1;
while (fscanf(fp, "%255s", path) != EOF) {
if (strcmp(path, keyword) == 0) {
if (fscanf(fp, "%63s", value_str) == EOF) {
SCLogDebug("%s: not followed by any number", keyword);
break;
}
if (StringParseInt32(&value, 10, 23, value_str) < 0) {
SCLogDebug("Failed to convert %s from /proc/meminfo", keyword);
value = -1;
}
break;
}
}
return value;
}
static void MemInfoEvaluateHugepages(FILE *fp)
{
int32_t free_hugepages = MemInfoParseValue(fp, "HugePages_Free:");
if (free_hugepages < 0) {
SCLogInfo("HugePages_Free information not found in /proc/meminfo");
return;
}
rewind(fp);
int32_t total_hugepages = MemInfoParseValue(fp, "HugePages_Total:");
if (total_hugepages < 0) {
SCLogInfo("HugePages_Total information not found in /proc/meminfo");
return;
} else if (total_hugepages == 0) {
SCLogInfo("HugePages_Total equals to zero");
return;
}
float free_hugepages_ratio = (float)free_hugepages / (float)total_hugepages;
if (free_hugepages_ratio > 0.5) {
SCLogInfo("%" PRIu32 " of %" PRIu32
" of hugepages are free - number of hugepages can be lowered to e.g. %.0lf",
free_hugepages, total_hugepages, ceil((total_hugepages - free_hugepages) * 1.15));
}
}
static void MemInfoWith(void (*callback)(FILE *))
{
FILE *fp = HugepagesMeminfoOpen();
if (fp) {
callback(fp);
HugepagesMeminfoClose(fp);
}
}
void DPDKEvaluateHugepages(void)
{
if (run_mode != RUNMODE_DPDK)
return;
#ifdef HAVE_DPDK
if (rte_eal_has_hugepages() == 0) { // hugepages disabled
SCLogPerf("Hugepages not enabled - enabling hugepages can improve performance");
return;
}
#endif
MemInfoWith(MemInfoEvaluateHugepages);
}
#ifdef HAVE_DPDK
/**

@ -121,6 +121,7 @@ void DPDKCleanupEAL(void);
void DPDKCloseDevice(LiveDevice *ldev);
void DPDKFreeDevice(LiveDevice *ldev);
void DPDKEvaluateHugepages(void);
#ifdef HAVE_DPDK
const char *DPDKGetPortNameByPortID(uint16_t pid);

Loading…
Cancel
Save