THP detection / reporting functions added.

This commit is contained in:
antirez 2014-11-12 10:43:32 +01:00
parent bb7fea0d5c
commit 3ef0876b95
3 changed files with 45 additions and 6 deletions

View File

@ -56,6 +56,32 @@ dictType latencyTimeSeriesDictType = {
dictVanillaFree /* val destructor */ dictVanillaFree /* val destructor */
}; };
/* ------------------------- Utility functions ------------------------------ */
#ifdef __linux__
/* Returns 1 if Transparent Huge Pages support is enabled in the kernel.
* Otherwise (or if we are unable to check) 0 is returned. */
int THPIsEnabled(void) {
char buf[1024];
FILE *fp = fopen("/sys/kernel/mm/transparent_hugepage/enabled","r");
if (!fp) return 0;
if (fgets(buf,sizeof(buf),fp) == NULL) {
fclose(fp);
return 0;
}
fclose(fp);
return (strstr(buf,"[never]") == NULL) ? 1 : 0;
}
/* Report the amount of AnonHugePages in smap, in bytes. If the return
* value of the function is non-zero, the process is being targeted by
* THP support, and is likely to have memory usage / latency issues. */
int THPGetAnonHugePagesSize(void) {
return zmalloc_get_smap_bytes_by_field("AnonHugePages:");
}
#endif
/* ---------------------------- Latency API --------------------------------- */ /* ---------------------------- Latency API --------------------------------- */
/* Latency monitor initialization. We just need to create the dictionary /* Latency monitor initialization. We just need to create the dictionary

View File

@ -328,27 +328,39 @@ float zmalloc_get_fragmentation_ratio(size_t rss) {
return (float)rss/zmalloc_used_memory(); return (float)rss/zmalloc_used_memory();
} }
/* Get the sum of the specified field (converted form kb to bytes) in
* /proc/self/smaps. The field must be specified with trailing ":" as it
* apperas in the smaps output.
*
* Example: zmalloc_get_smap_bytes_by_field("Rss:");
*/
#if defined(HAVE_PROC_SMAPS) #if defined(HAVE_PROC_SMAPS)
size_t zmalloc_get_private_dirty(void) { size_t zmalloc_get_smap_bytes_by_field(char *field) {
char line[1024]; char line[1024];
size_t pd = 0; size_t bytes = 0;
FILE *fp = fopen("/proc/self/smaps","r"); FILE *fp = fopen("/proc/self/smaps","r");
int flen = strlen(field);
if (!fp) return 0; if (!fp) return 0;
while(fgets(line,sizeof(line),fp) != NULL) { while(fgets(line,sizeof(line),fp) != NULL) {
if (strncmp(line,"Private_Dirty:",14) == 0) { if (strncmp(line,field,flen) == 0) {
char *p = strchr(line,'k'); char *p = strchr(line,'k');
if (p) { if (p) {
*p = '\0'; *p = '\0';
pd += strtol(line+14,NULL,10) * 1024; bytes += strtol(line+flen,NULL,10) * 1024;
} }
} }
} }
fclose(fp); fclose(fp);
return pd; return bytes;
} }
#else #else
size_t zmalloc_get_private_dirty(void) { size_t zmalloc_get_smap_bytes_by_field(char *field) {
REDIS_NOTUSED(field);
return 0; return 0;
} }
#endif #endif
size_t zmalloc_get_private_dirty(void) {
return zmalloc_get_smap_bytes_by_field("Private_Dirty:");
}

View File

@ -76,6 +76,7 @@ void zmalloc_set_oom_handler(void (*oom_handler)(size_t));
float zmalloc_get_fragmentation_ratio(size_t rss); float zmalloc_get_fragmentation_ratio(size_t rss);
size_t zmalloc_get_rss(void); size_t zmalloc_get_rss(void);
size_t zmalloc_get_private_dirty(void); size_t zmalloc_get_private_dirty(void);
size_t zmalloc_get_smap_bytes_by_field(char *field);
void zlibc_free(void *ptr); void zlibc_free(void *ptr);
#ifndef HAVE_MALLOC_SIZE #ifndef HAVE_MALLOC_SIZE