added Linux KSM support

This commit is contained in:
roberto@debian32
2011-11-17 11:16:48 +01:00
parent 715d26beed
commit 049ea3fbed
4 changed files with 137 additions and 0 deletions
+8
View File
@@ -1432,6 +1432,14 @@ healthy:
}
#endif
#ifdef __linux__
#ifdef MADV_MERGEABLE
if (uwsgi.linux_ksm > 0 && (uwsgi.master_cycles % uwsgi.linux_ksm) == 0) {
uwsgi_linux_ksm_map();
}
#endif
#endif
#ifdef UWSGI_UDP
// check for cluster nodes
master_check_cluster_nodes();
+88
View File
@@ -717,8 +717,96 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
uwsgi.loyal = 1;
}
#ifdef __linux__
#ifdef MADV_MERGEABLE
// run the ksm mapper
if (uwsgi.linux_ksm > 0 && (uwsgi.workers[uwsgi.mywid].requests % uwsgi.linux_ksm) == 0) {
uwsgi_linux_ksm_map();
}
#endif
#endif
}
#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;
ksm_mappings_current = NULL;
ksm_mappings_current_lines = 0;
FILE *process_maps = fopen("/proc/self/maps", "r");
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);
if (ksm_mappings_last == NULL || ksm_mappings_last_lines == 0 || ksm_mappings_last_lines != ksm_mappings_current_lines) {
dirty = 1;
}
else {
for(i=0;i<ksm_mappings_current_lines;i+=2) {
if (ksm_mappings_current[i] != ksm_mappings_last[i]) {
dirty = 1;
break;
}
if (ksm_mappings_current[i+1] != ksm_mappings_last[i+1]) {
dirty = 1;
break;
}
}
}
if (dirty) {
for(i=0;i<ksm_mappings_current_lines;i+=2) {
if (madvise((void *) (long) ksm_mappings_current[i], (size_t) (ksm_mappings_current[i+1]-ksm_mappings_current[i]), MADV_MERGEABLE)) {
errors += 2;
}
}
free(ksm_mappings_last);
ksm_mappings_last = ksm_mappings_current;
ksm_mappings_last_lines = ksm_mappings_current_lines;
if (errors >= ksm_mappings_current_lines) {
uwsgi_error("[uwsgi-KSM] unable to share pages");
}
}
}
}
#endif
#endif
void wsgi_req_setup(struct wsgi_request *wsgi_req, int async_id, struct uwsgi_socket *uwsgi_sock) {
wsgi_req->poll.events = POLLIN;
+28
View File
@@ -176,6 +176,11 @@ static struct option long_base_options[] = {
{"reload-on-rss", required_argument, 0, LONG_ARGS_RELOAD_ON_RSS},
{"evil-reload-on-as", required_argument, 0, LONG_ARGS_EVIL_RELOAD_ON_AS},
{"evil-reload-on-rss", required_argument, 0, LONG_ARGS_EVIL_RELOAD_ON_RSS},
#ifdef __linux__
#ifdef MADV_MERGEABLE
{"ksm", optional_argument, 0, LONG_ARGS_KSM},
#endif
#endif
{"touch-reload", required_argument, 0, LONG_ARGS_TOUCH_RELOAD},
{"propagate-touch", no_argument, &uwsgi.propagate_touch, 1},
{"limit-post", required_argument, 0, LONG_ARGS_LIMIT_POST},
@@ -2442,6 +2447,7 @@ skipzero:
}
if (!uwsgi.master_process && uwsgi.numproc == 0) {
exit(0);
}
@@ -2449,6 +2455,16 @@ skipzero:
uwsgi_log("*** uWSGI is running in multiple interpreter mode ***\n");
}
#ifdef __linux__
#ifdef MADV_MERGEABLE
if (uwsgi.linux_ksm > 0) {
uwsgi_log("[uwsgi-KSM] enabled with frequency: %d\n", uwsgi.linux_ksm);
}
#endif
#endif
if (uwsgi.master_process) {
if (uwsgi.is_a_reload) {
uwsgi_log("gracefully (RE)spawned uWSGI master process (pid: %d)\n", uwsgi.mypid);
@@ -2541,6 +2557,8 @@ skipzero:
}
}
if (getpid() == masterpid && uwsgi.master_process == 1) {
#ifdef UWSGI_AS_SHARED_LIBRARY
int ml_ret = master_loop(uwsgi.argv, uwsgi.environ);
@@ -3415,6 +3433,16 @@ static int manage_base_opt(int i, char *optarg) {
case LONG_ARGS_LIMIT_POST:
uwsgi.limit_post = (int) strtol(optarg, NULL, 10);
return 1;
#ifdef __linux__
#ifdef MADV_MERGEABLE
case LONG_ARGS_KSM:
uwsgi.linux_ksm = 1;
if (optarg) {
uwsgi.linux_ksm = atoi(optarg);
}
return 1;
#endif
#endif
case LONG_ARGS_RELOAD_ON_AS:
uwsgi.force_get_memusage = 1;
uwsgi.reload_on_as = (strtoul(optarg, NULL, 10)) * 1024 * 1024;
+13
View File
@@ -540,6 +540,7 @@ struct uwsgi_opt {
#define LONG_ARGS_PAUSE 17161
#define LONG_ARGS_SIGNAL_BUFSIZE 17162
#define LONG_ARGS_SIGNAL 17163
#define LONG_ARGS_KSM 17164
#define UWSGI_OK 0
@@ -1525,6 +1526,12 @@ struct uwsgi_server {
// subscription client
struct uwsgi_string_list *subscriptions;
#ifdef __linux__
#ifdef MADV_MERGEABLE
int linux_ksm;
#endif
#endif
};
struct uwsgi_rpc {
@@ -2459,6 +2466,12 @@ void uwsgi_add_app(int, uint8_t, char *, int);
int uwsgi_signal_send(int, uint8_t);
int uwsgi_remote_signal_send(char *, uint8_t);
#ifdef __linux__
#ifdef MADV_MERGEABLE
void uwsgi_linux_ksm_map(void);
#endif
#endif
#ifdef UWSGI_CAP
void uwsgi_build_cap(char *);
#endif