From b745132ebd14012dfdfefd6ceb14ef844755c4d7 Mon Sep 17 00:00:00 2001 From: "roberto@oneiric64" Date: Fri, 2 Dec 2011 13:31:17 +0100 Subject: [PATCH] improved ksm support --- utils.c | 119 +++++++++++++++++++++++++++----------------------------- uwsgi.h | 5 +++ 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/utils.c b/utils.c index 8dd53c24..01f48c4b 100644 --- a/utils.c +++ b/utils.c @@ -739,81 +739,76 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) { #ifdef __linux__ #ifdef MADV_MERGEABLE -unsigned long long *ksm_mappings_last = NULL; -int ksm_mappings_last_lines = 0; -unsigned long long *ksm_mappings_current = NULL; -int ksm_mappings_current_lines = 0; - void uwsgi_linux_ksm_map(void) { - char map_line_buf[1024]; - unsigned long long start, end; int dirty = 0; - int i; - int errors = 0; - unsigned long long *tmp_ptr; + size_t i; + unsigned long long start = 0, end = 0; + int errors = 0; int lines = 0; - ksm_mappings_current = NULL; - ksm_mappings_current_lines = 0; + int fd = open("/proc/self/maps", O_RDONLY); + if (fd < 0) { + uwsgi_error_open("[uwsgi-KSM] /proc/self/maps"); + return ; + } - FILE *process_maps = fopen("/proc/self/maps", "r"); + // allocate memory if not available; + if (uwsgi.ksm_mappings_current == NULL) { + if (!uwsgi.ksm_buffer_size) uwsgi.ksm_buffer_size = 32768; + uwsgi.ksm_mappings_current = uwsgi_malloc(uwsgi.ksm_buffer_size); + uwsgi.ksm_mappings_current_size = 0; + } + if (uwsgi.ksm_mappings_last == NULL) { + if (!uwsgi.ksm_buffer_size) uwsgi.ksm_buffer_size = 32768; + uwsgi.ksm_mappings_last = uwsgi_malloc(uwsgi.ksm_buffer_size); + uwsgi.ksm_mappings_last_size = 0; + } - if (process_maps) { - while( fgets(map_line_buf, 1024, process_maps)) { - if (fscanf(process_maps, "%llx-%llx %*s", &start, &end) == 2) { - ksm_mappings_current_lines+=2; - tmp_ptr = ksm_mappings_current; - ksm_mappings_current = realloc(ksm_mappings_current, sizeof(unsigned long long) * ksm_mappings_current_lines); - if (!ksm_mappings_current) { - uwsgi_error("[uwsgi-KSM] /proc/self/maps realloc()"); - fclose(process_maps); - if (tmp_ptr) { - free(tmp_ptr); - } - return; - } - ksm_mappings_current[ksm_mappings_current_lines-2] = start; - ksm_mappings_current[ksm_mappings_current_lines-1] = end; - } - } - fclose(process_maps); + uwsgi.ksm_mappings_current_size = read(fd, uwsgi.ksm_mappings_current, uwsgi.ksm_buffer_size); + close(fd); + if (uwsgi.ksm_mappings_current_size <= 0) { + uwsgi_log("[uwsgi-KSM] unable to read /proc/self/maps data\n"); + return; + } - if (ksm_mappings_last == NULL || ksm_mappings_last_lines == 0 || ksm_mappings_last_lines != ksm_mappings_current_lines) { + // we now have areas + if (uwsgi.ksm_mappings_last_size == 0 || uwsgi.ksm_mappings_current_size == 0 || uwsgi.ksm_mappings_current_size != uwsgi.ksm_mappings_last_size) { + dirty = 1; + } + else { + if (memcmp(uwsgi.ksm_mappings_current, uwsgi.ksm_mappings_last, uwsgi.ksm_mappings_current_size) != 0) { dirty = 1; } - else { - for(i=0;i= ksm_mappings_current_lines) { - uwsgi_error("[uwsgi-KSM] unable to share pages"); - } - } - // if not dirty, free ksm_mappings_current - else { - free(ksm_mappings_current); + if (errors >= lines) { + uwsgi_error("[uwsgi-KSM] unable to share pages"); } } } diff --git a/uwsgi.h b/uwsgi.h index f2f59ebe..70a307f5 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -1555,6 +1555,11 @@ struct uwsgi_server { #ifdef __linux__ #ifdef MADV_MERGEABLE int linux_ksm; + int ksm_buffer_size; + char *ksm_mappings_last; + char *ksm_mappings_current; + size_t ksm_mappings_last_size; + size_t ksm_mappings_current_size; #endif #endif