diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2011-01-17 18:08:11 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2011-01-17 18:08:11 +0300 |
commit | c783f297faa2453daca7189182a17f913e003ccc (patch) | |
tree | 0527171103dbe568658ea21262e1027b7023bf9a | |
parent | 56762d9574d05bff9709c856f9f466c51156f549 (diff) | |
download | accel-ppp-c783f297faa2453daca7189182a17f913e003ccc.tar.gz accel-ppp-c783f297faa2453daca7189182a17f913e003ccc.zip |
memory usage optimization
-rw-r--r-- | accel-pppd/CMakeLists.txt | 11 | ||||
-rw-r--r-- | accel-pppd/auth/auth_chap_md5.c | 4 | ||||
-rw-r--r-- | accel-pppd/auth/auth_mschap_v1.c | 4 | ||||
-rw-r--r-- | accel-pppd/auth/auth_mschap_v2.c | 4 | ||||
-rw-r--r-- | accel-pppd/auth/auth_pap.c | 4 | ||||
-rw-r--r-- | accel-pppd/cli/std_cmd.c | 13 | ||||
-rw-r--r-- | accel-pppd/extra/chap-secrets.c | 1 | ||||
-rw-r--r-- | accel-pppd/memdebug.c | 4 | ||||
-rw-r--r-- | accel-pppd/memdebug.h | 2 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp.c | 59 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp.h | 6 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp_ccp.c | 6 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp_ipcp.c | 6 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp_lcp.c | 10 | ||||
-rw-r--r-- | accel-pppd/radius/packet.c | 36 | ||||
-rw-r--r-- | accel-pppd/triton/mempool.c | 104 |
16 files changed, 162 insertions, 112 deletions
diff --git a/accel-pppd/CMakeLists.txt b/accel-pppd/CMakeLists.txt index 8f1e931..b3c8dad 100644 --- a/accel-pppd/CMakeLists.txt +++ b/accel-pppd/CMakeLists.txt @@ -12,7 +12,7 @@ IF (NOT HAVE_SSL) MESSAGE(FATAL_ERROR "openssl headers not found") ENDIF (NOT HAVE_SSL) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden -fno-strict-aliasing -D_GNU_SOURCE -DPTHREAD_SPINLOCK -DMEMDEBUG -fPIC") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden -fno-strict-aliasing -D_GNU_SOURCE -DPTHREAD_SPINLOCK -fPIC") IF (EXISTS ${CMAKE_HOME_DIRECTORY}/.git) EXECUTE_PROCESS( @@ -40,9 +40,12 @@ IF (RADIUS) ADD_SUBDIRECTORY(radius) ENDIF (RADIUS) -IF (VALGRIND) - ADD_DEFINITIONS(-DVALGRIND) -ENDIF (VALGRIND) +IF (MEMDEBUG) + ADD_DEFINITIONS(-DMEMDEBUG) + IF (VALGRIND) + ADD_DEFINITIONS(-DVALGRIND) + ENDIF (VALGRIND) +ENDIF (MEMDEBUG) ADD_SUBDIRECTORY(triton) ADD_SUBDIRECTORY(ctrl) diff --git a/accel-pppd/auth/auth_chap_md5.c b/accel-pppd/auth/auth_chap_md5.c index 647ba15..2ea60ba 100644 --- a/accel-pppd/auth/auth_chap_md5.c +++ b/accel-pppd/auth/auth_chap_md5.c @@ -384,9 +384,9 @@ static struct ppp_auth_handler_t chap= static void chap_recv(struct ppp_handler_t *h) { struct chap_auth_data_t *d = container_of(h, typeof(*d), h); - struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->chan_buf; + struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->buf; - if (d->ppp->chan_buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->chan_buf_size - 2) { + if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->buf_size - 2) { log_ppp_warn("chap-md5: short packet received\n"); return; } diff --git a/accel-pppd/auth/auth_mschap_v1.c b/accel-pppd/auth/auth_mschap_v1.c index 21d90a6..4308300 100644 --- a/accel-pppd/auth/auth_mschap_v1.c +++ b/accel-pppd/auth/auth_mschap_v1.c @@ -469,9 +469,9 @@ static struct ppp_auth_handler_t chap = { static void chap_recv(struct ppp_handler_t *h) { struct chap_auth_data_t *d = container_of(h, typeof(*d), h); - struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->chan_buf; + struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->buf; - if (d->ppp->chan_buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->chan_buf_size - 2) { + if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->buf_size - 2) { log_ppp_warn("mschap-v1: short packet received\n"); return; } diff --git a/accel-pppd/auth/auth_mschap_v2.c b/accel-pppd/auth/auth_mschap_v2.c index 61dd017..644f70b 100644 --- a/accel-pppd/auth/auth_mschap_v2.c +++ b/accel-pppd/auth/auth_mschap_v2.c @@ -609,9 +609,9 @@ static struct ppp_auth_handler_t chap= static void chap_recv(struct ppp_handler_t *h) { struct chap_auth_data_t *d = container_of(h, typeof(*d), h); - struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->chan_buf; + struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->buf; - if (d->ppp->chan_buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->chan_buf_size - 2) { + if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->buf_size - 2) { log_ppp_warn("mschap-v2: short packet received\n"); return; } diff --git a/accel-pppd/auth/auth_pap.c b/accel-pppd/auth/auth_pap.c index 6909046..70e8081 100644 --- a/accel-pppd/auth/auth_pap.c +++ b/accel-pppd/auth/auth_pap.c @@ -242,9 +242,9 @@ static int pap_recv_req(struct pap_auth_data_t *p, struct pap_hdr_t *hdr) static void pap_recv(struct ppp_handler_t *h) { struct pap_auth_data_t *d = container_of(h, typeof(*d), h); - struct pap_hdr_t *hdr = (struct pap_hdr_t *)d->ppp->chan_buf; + struct pap_hdr_t *hdr = (struct pap_hdr_t *)d->ppp->buf; - if (d->ppp->chan_buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->chan_buf_size - 2) { + if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->buf_size - 2) { log_ppp_warn("PAP: short packet received\n"); return; } diff --git a/accel-pppd/cli/std_cmd.c b/accel-pppd/cli/std_cmd.c index a49bbce..3adb926 100644 --- a/accel-pppd/cli/std_cmd.c +++ b/accel-pppd/cli/std_cmd.c @@ -3,6 +3,7 @@ #include <string.h> #include <unistd.h> #include <signal.h> +#include <malloc.h> #include <arpa/inet.h> #include "triton.h" @@ -21,6 +22,9 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, FILE *f; unsigned long vmsize = 0, vmrss = 0; unsigned long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; +#ifdef MEMDEBUG + struct mallinfo mi = mallinfo(); +#endif sprintf(statm_fname, "/proc/%i/statm", getpid()); f = fopen(statm_fname, "r"); @@ -38,7 +42,16 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, cli_sendv(client, "uptime: %i.%02i:%02i:%02i\r\n", day, hour, dt / 60, dt % 60); cli_sendv(client, "cpu: %i%%\r\n", triton_stat.cpu); +#ifdef MEMDEBUG + cli_send(client, "memory:\r\n"); + cli_sendv(client, " rss/virt: %lu/%lu kB\r\n", vmrss * page_size_kb, vmsize * page_size_kb); + cli_sendv(client, " arena: %lu kB\r\n", mi.arena / 1024); + cli_sendv(client, " mmaped: %lu kB\r\n", mi.hblkhd / 1024); + cli_sendv(client, " uordblks: %lu kB\r\n", mi.uordblks / 1024); + cli_sendv(client, " fordblks: %lu kB\r\n", mi.fordblks / 1024); +#else cli_sendv(client, "mem(rss/virt): %lu/%lu kB\r\n", vmrss * page_size_kb, vmsize * page_size_kb); +#endif cli_send(client, "core:\r\n"); cli_sendv(client, " mempool_allocated: %u\r\n", triton_stat.mempool_allocated); cli_sendv(client, " mempool_available: %u\r\n", triton_stat.mempool_available); diff --git a/accel-pppd/extra/chap-secrets.c b/accel-pppd/extra/chap-secrets.c index 3550347..a42ab23 100644 --- a/accel-pppd/extra/chap-secrets.c +++ b/accel-pppd/extra/chap-secrets.c @@ -1,4 +1,5 @@ #include <stdio.h> +#include <stdlib.h> #include <errno.h> #include <string.h> #include <netinet/in.h> diff --git a/accel-pppd/memdebug.c b/accel-pppd/memdebug.c index c33e34b..8e9dd4b 100644 --- a/accel-pppd/memdebug.c +++ b/accel-pppd/memdebug.c @@ -30,7 +30,7 @@ struct mem_t { struct list_head entry; - char fname[PATH_MAX]; + const char *fname; int line; size_t size; uint64_t magic2; @@ -48,7 +48,7 @@ struct mem_t *_md_malloc(size_t size, const char *fname, int line) if (size > 4096) line = 0; - strcpy(mem->fname, fname); + mem->fname = fname; mem->line = line; mem->size = size; mem->magic1 = MAGIC1; diff --git a/accel-pppd/memdebug.h b/accel-pppd/memdebug.h index dc6b9ad..98e87d0 100644 --- a/accel-pppd/memdebug.h +++ b/accel-pppd/memdebug.h @@ -22,6 +22,8 @@ void md_check(void *ptr); #define _malloc(size) malloc(size) #define _realloc(ptr, size) realloc(ptr, size) #define _free(ptr) free(ptr) +#define _strdup(str) strdup(str) +#define _strndup(str, size) strndup(str, size) #endif #endif diff --git a/accel-pppd/ppp/ppp.c b/accel-pppd/ppp/ppp.c index f578e8e..a044d9a 100644 --- a/accel-pppd/ppp/ppp.c +++ b/accel-pppd/ppp/ppp.c @@ -20,6 +20,7 @@ #include "ppp_fsm.h" #include "log.h" #include "spinlock.h" +#include "mempool.h" #include "memdebug.h" @@ -29,17 +30,19 @@ static int conf_sid_ucase; pthread_rwlock_t __export ppp_lock = PTHREAD_RWLOCK_INITIALIZER; __export LIST_HEAD(ppp_list); -static LIST_HEAD(layers); int __export sock_fd; int __export ppp_shutdown; +static mempool_t buf_pool; + +static LIST_HEAD(layers); + static unsigned long long seq; #if __WORDSIZE == 32 static spinlock_t seq_lock; #endif - struct ppp_stat_t ppp_stat; struct layer_node_t @@ -64,16 +67,6 @@ void __export ppp_init(struct ppp_t *ppp) INIT_LIST_HEAD(&ppp->pd_list); } -static void _free_ppp(struct ppp_t *ppp) -{ - if (ppp->chan_buf) - free(ppp->chan_buf); - if (ppp->unit_buf) - _free(ppp->unit_buf); - if (ppp->username) - _free(ppp->username); -} - static void generate_sessionid(struct ppp_t *ppp) { unsigned long long sid; @@ -151,8 +144,7 @@ int __export establish_ppp(struct ppp_t *ppp) goto exit_close_unit; } - ppp->chan_buf = _malloc(PPP_MRU); - ppp->unit_buf = _malloc(PPP_MRU); + ppp->buf = mempool_alloc(buf_pool); ppp->chan_hnd.fd = ppp->chan_fd; ppp->chan_hnd.read = ppp_chan_read; @@ -184,7 +176,8 @@ exit_close_unit: exit_close_chan: close(ppp->chan_fd); - _free_ppp(ppp); + if (ppp->buf) + mempool_free(ppp->buf); return -1; } @@ -218,9 +211,6 @@ static void destablish_ppp(struct ppp_t *ppp) ppp->chan_fd = -1; ppp->fd = -1; - _free(ppp->unit_buf); - _free(ppp->chan_buf); - _free_layers(ppp); ppp->terminated = 1; @@ -230,6 +220,8 @@ static void destablish_ppp(struct ppp_t *ppp) triton_event_fire(EV_PPP_FINISHED, ppp); ppp->ctrl->finished(ppp); + mempool_free(ppp->buf); + if (ppp->username) { _free(ppp->username); ppp->username = NULL; @@ -281,8 +273,8 @@ static int ppp_chan_read(struct triton_md_handler_t *h) while(1) { cont: - ppp->chan_buf_size = read(h->fd, ppp->chan_buf, PPP_MRU); - if (ppp->chan_buf_size < 0) { + ppp->buf_size = read(h->fd, ppp->buf, PPP_MRU); + if (ppp->buf_size < 0) { if (errno == EAGAIN) return 0; log_ppp_error("ppp_chan_read: %s\n", strerror(errno)); @@ -290,18 +282,18 @@ cont: } //printf("ppp_chan_read: "); - //print_buf(ppp->chan_buf,ppp->chan_buf_size); - if (ppp->chan_buf_size == 0) { + //print_buf(ppp->buf,ppp->buf_size); + if (ppp->buf_size == 0) { ppp_terminate(ppp, 1, TERM_NAS_ERROR); return 1; } - if (ppp->chan_buf_size < 2) { - log_ppp_error("ppp_chan_read: short read %i\n", ppp->chan_buf_size); + if (ppp->buf_size < 2) { + log_ppp_error("ppp_chan_read: short read %i\n", ppp->buf_size); continue; } - proto = ntohs(*(uint16_t*)ppp->chan_buf); + proto = ntohs(*(uint16_t*)ppp->buf); list_for_each_entry(ppp_h, &ppp->chan_handlers, entry) { if (ppp_h->proto == proto) { ppp_h->recv(ppp_h); @@ -326,29 +318,28 @@ static int ppp_unit_read(struct triton_md_handler_t *h) while (1) { cont: - ppp->unit_buf_size = read(h->fd, ppp->unit_buf, PPP_MRU); - if (ppp->unit_buf_size < 0) { + ppp->buf_size = read(h->fd, ppp->buf, PPP_MRU); + if (ppp->buf_size < 0) { if (errno == EAGAIN) return 0; log_ppp_error("ppp_unit_read: %s\n",strerror(errno)); return 0; } - md_check(ppp->unit_buf); //printf("ppp_unit_read: "); - //print_buf(ppp->unit_buf,ppp->unit_buf_size); + //print_buf(ppp->buf,ppp->buf_size); - if (ppp->unit_buf_size == 0) { + if (ppp->buf_size == 0) { ppp_terminate(ppp, 1, TERM_NAS_ERROR); return 1; } - if (ppp->unit_buf_size < 2) { - log_ppp_error("ppp_unit_read: short read %i\n", ppp->unit_buf_size); + if (ppp->buf_size < 2) { + log_ppp_error("ppp_unit_read: short read %i\n", ppp->buf_size); continue; } - proto=ntohs(*(uint16_t*)ppp->unit_buf); + proto=ntohs(*(uint16_t*)ppp->buf); list_for_each_entry(ppp_h, &ppp->unit_handlers, entry) { if (ppp_h->proto == proto) { ppp_h->recv(ppp_h); @@ -656,6 +647,8 @@ static void __init init(void) char *opt; FILE *f; + buf_pool = mempool_create(PPP_MRU); + sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if (sock_fd < 0) { perror("socket"); diff --git a/accel-pppd/ppp/ppp.h b/accel-pppd/ppp/ppp.h index c633135..5fee8a4 100644 --- a/accel-pppd/ppp/ppp.h +++ b/accel-pppd/ppp/ppp.h @@ -103,10 +103,8 @@ struct ppp_t int terminated:1; int terminate_cause; - void *chan_buf; - int chan_buf_size; - void *unit_buf; - int unit_buf_size; + void *buf; + int buf_size; struct list_head chan_handlers; struct list_head unit_handlers; diff --git a/accel-pppd/ppp/ppp_ccp.c b/accel-pppd/ppp/ppp_ccp.c index 721dd9b..d4732fa 100644 --- a/accel-pppd/ppp/ppp_ccp.c +++ b/accel-pppd/ppp/ppp_ccp.c @@ -271,7 +271,7 @@ static int send_conf_req(struct ppp_fsm_t *fsm) static void send_conf_ack(struct ppp_fsm_t *fsm) { struct ppp_ccp_t *ccp = container_of(fsm, typeof(*ccp), fsm); - struct ccp_hdr_t *hdr = (struct ccp_hdr_t*)ccp->ppp->unit_buf; + struct ccp_hdr_t *hdr = (struct ccp_hdr_t*)ccp->ppp->buf; hdr->code = CONFACK; @@ -619,12 +619,12 @@ static void ccp_recv(struct ppp_handler_t*h) return; } - if (ccp->ppp->unit_buf_size < PPP_HEADERLEN + 2) { + if (ccp->ppp->buf_size < PPP_HEADERLEN + 2) { log_ppp_warn("CCP: short packet received\n"); return; } - hdr = (struct ccp_hdr_t *)ccp->ppp->unit_buf; + hdr = (struct ccp_hdr_t *)ccp->ppp->buf; if (ntohs(hdr->len) < PPP_HEADERLEN) { log_ppp_warn("CCP: short packet received\n"); return; diff --git a/accel-pppd/ppp/ppp_ipcp.c b/accel-pppd/ppp/ppp_ipcp.c index 7cdcdbc..5d66c9d 100644 --- a/accel-pppd/ppp/ppp_ipcp.c +++ b/accel-pppd/ppp/ppp_ipcp.c @@ -219,7 +219,7 @@ static int send_conf_req(struct ppp_fsm_t *fsm) static void send_conf_ack(struct ppp_fsm_t *fsm) { struct ppp_ipcp_t *ipcp = container_of(fsm, typeof(*ipcp), fsm); - struct ipcp_hdr_t *hdr = (struct ipcp_hdr_t*)ipcp->ppp->unit_buf; + struct ipcp_hdr_t *hdr = (struct ipcp_hdr_t*)ipcp->ppp->buf; hdr->code = CONFACK; @@ -564,12 +564,12 @@ static void ipcp_recv(struct ppp_handler_t*h) return; } - if (ipcp->ppp->unit_buf_size < PPP_HEADERLEN + 2) { + if (ipcp->ppp->buf_size < PPP_HEADERLEN + 2) { log_ppp_warn("IPCP: short packet received\n"); return; } - hdr = (struct ipcp_hdr_t *)ipcp->ppp->unit_buf; + hdr = (struct ipcp_hdr_t *)ipcp->ppp->buf; if (ntohs(hdr->len) < PPP_HEADERLEN) { log_ppp_warn("IPCP: short packet received\n"); return; diff --git a/accel-pppd/ppp/ppp_lcp.c b/accel-pppd/ppp/ppp_lcp.c index e40e321..63fe8ff 100644 --- a/accel-pppd/ppp/ppp_lcp.c +++ b/accel-pppd/ppp/ppp_lcp.c @@ -252,7 +252,7 @@ static int send_conf_req(struct ppp_fsm_t *fsm) static void send_conf_ack(struct ppp_fsm_t *fsm) { struct ppp_lcp_t *lcp = container_of(fsm, typeof(*lcp), fsm); - struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->chan_buf; + struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->buf; hdr->code = CONFACK; @@ -265,7 +265,7 @@ static void send_conf_ack(struct ppp_fsm_t *fsm) static void send_code_rej(struct ppp_fsm_t *fsm) { struct ppp_lcp_t *lcp = container_of(fsm, typeof(*lcp), fsm); - struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->chan_buf; + struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->buf; hdr->code = CONFACK; @@ -586,7 +586,7 @@ static void lcp_recv_echo_repl(struct ppp_lcp_t *lcp, uint8_t *data, int size) static void send_echo_reply(struct ppp_lcp_t *lcp) { - struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->chan_buf; + struct lcp_hdr_t *hdr = (struct lcp_hdr_t*)lcp->ppp->buf; uint32_t magic = *(uint32_t *)(hdr + 1); hdr->code = ECHOREP; @@ -706,12 +706,12 @@ static void lcp_recv(struct ppp_handler_t*h) return; } - if (lcp->ppp->chan_buf_size < PPP_HEADERLEN + 2) { + if (lcp->ppp->buf_size < PPP_HEADERLEN + 2) { log_ppp_warn("LCP: short packet received\n"); return; } - hdr = (struct lcp_hdr_t *)lcp->ppp->chan_buf; + hdr = (struct lcp_hdr_t *)lcp->ppp->buf; if (ntohs(hdr->len) < PPP_HEADERLEN) { log_ppp_warn("LCP: short packet received\n"); return; diff --git a/accel-pppd/radius/packet.c b/accel-pppd/radius/packet.c index 4e24ded..a3ba9a2 100644 --- a/accel-pppd/radius/packet.c +++ b/accel-pppd/radius/packet.c @@ -5,6 +5,8 @@ #include <stdio.h> #include <unistd.h> #include <fcntl.h> +#include <sys/mman.h> +#include <linux/mman.h> #include "log.h" #include "mempool.h" @@ -48,17 +50,18 @@ int rad_packet_build(struct rad_packet_t *pack, uint8_t *RA) struct rad_attr_t *attr; uint8_t *ptr; - if (pack->buf) - ptr = _realloc(pack->buf, pack->len); - else - ptr = _malloc(pack->len); + if (!pack->buf) { + ptr = mmap(NULL, REQ_LENGTH_MAX, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + + if (ptr == MAP_FAILED) { + log_emerg("radius:packet: out of memory\n"); + return -1; + } + + pack->buf = ptr; + } else + ptr = pack->buf; - if (!ptr) { - log_emerg("radius:packet: out of memory\n"); - return -1; - } - - pack->buf = ptr; *ptr = pack->code; ptr++; *ptr = pack->id; ptr++; *(uint16_t*)ptr = htons(pack->len); ptr+= 2; @@ -113,11 +116,13 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr) if (!pack) return 0; - pack->buf = _malloc(REQ_LENGTH_MAX); - if (!pack->buf) { + ptr = mmap(NULL, REQ_LENGTH_MAX, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) { log_emerg("radius:packet: out of memory\n"); goto out_err; } + + pack->buf = ptr; while (1) { if (addr) @@ -141,8 +146,6 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr) goto out_err; } - ptr = (uint8_t *)pack->buf; - pack->code = *ptr; ptr++; pack->id = *ptr; ptr++; pack->len = ntohs(*(uint16_t*)ptr); ptr += 2; @@ -224,6 +227,9 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr) n -= 2 + len; } + munmap(pack->buf, REQ_LENGTH_MAX); + pack->buf = NULL; + *p = pack; return 0; @@ -238,7 +244,7 @@ void rad_packet_free(struct rad_packet_t *pack) struct rad_attr_t *attr; if (pack->buf) - _free(pack->buf); + munmap(pack->buf, REQ_LENGTH_MAX); while(!list_empty(&pack->attrs)) { attr = list_entry(pack->attrs.next, typeof(*attr), entry); diff --git a/accel-pppd/triton/mempool.c b/accel-pppd/triton/mempool.c index 855e22e..e3950dc 100644 --- a/accel-pppd/triton/mempool.c +++ b/accel-pppd/triton/mempool.c @@ -18,6 +18,7 @@ //#define MEMPOOL_DISABLE #define MAGIC1 0x2233445566778899llu +#define PAGE_ORDER 5 struct _mempool_t { @@ -50,6 +51,11 @@ struct _item_t static LIST_HEAD(pools); static spinlock_t pools_lock = SPINLOCK_INITIALIZER; +static spinlock_t mmap_lock = SPINLOCK_INITIALIZER; +static void *mmap_ptr; +static void *mmap_endptr; + +static int mmap_grow(void); mempool_t __export *mempool_create(int size) { @@ -63,6 +69,7 @@ mempool_t __export *mempool_create(int size) spinlock_init(&p->lock); p->size = size; p->magic = (uint64_t)random() * (uint64_t)random(); + p->mmap = 1; spin_lock(&pools_lock); list_add_tail(&p->entry, &pools); @@ -92,41 +99,51 @@ void __export *mempool_alloc(mempool_t *pool) it = list_entry(p->items.next, typeof(*it), entry); list_del(&it->entry); spin_unlock(&p->lock); - + __sync_sub_and_fetch(&triton_stat.mempool_available, size); it->magic1 = MAGIC1; return it->ptr; +#ifdef VALGRIND + } +#endif } spin_unlock(&p->lock); - if (p->mmap) - it = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_32BIT, -1, 0); - else + if (p->mmap) { + spin_lock(&mmap_lock); + if (mmap_ptr + size >= mmap_endptr) { + if (mmap_grow()) + return NULL; + } + it = (struct _item_t *)mmap_ptr; + mmap_ptr += size; + spin_unlock(&mmap_lock); + __sync_sub_and_fetch(&triton_stat.mempool_available, size); + } else { it = _malloc(size); + __sync_add_and_fetch(&triton_stat.mempool_allocated, size); + } if (!it) { triton_log_error("mempool: out of memory\n"); return NULL; } it->owner = p; - it->magic1 = MAGIC1; it->magic2 = p->magic; - *(uint64_t*)(it->data + p->size) = it->magic2; - - __sync_add_and_fetch(&triton_stat.mempool_allocated, size); + it->magic1 = MAGIC1; + *(uint64_t*)(it->ptr + p->size) = it->magic2; return it->ptr; } -#endif +#else void __export *mempool_alloc_md(mempool_t *pool, const char *fname, int line) { struct _mempool_t *p = (struct _mempool_t *)pool; struct _item_t *it; uint32_t size = sizeof(*it) + p->size + 8; - int i, n; spin_lock(&p->lock); if (!list_empty(&p->items)) { @@ -155,29 +172,17 @@ void __export *mempool_alloc_md(mempool_t *pool, const char *fname, int line) spin_unlock(&p->lock); if (p->mmap) { - n = (sysconf(_SC_PAGE_SIZE) - 1) / size + 1; - it = mmap(NULL, n * size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_32BIT, -1, 0); - __sync_add_and_fetch(&triton_stat.mempool_allocated, size * (n - 1)); - __sync_add_and_fetch(&triton_stat.mempool_available, size * (n - 1)); - spin_lock(&p->lock); - for (i = 0; i < n - 1; i++, it) { - it->owner = p; - it->magic2 = p->magic; - it->magic1 = MAGIC1; - *(uint64_t*)(it->ptr + p->size) = it->magic2; - list_add_tail(&it->entry,&p->items); -#ifdef VALGRIND - it->timestamp = 0; - VALGRIND_MAKE_MEM_NOACCESS(&it->owner, size - sizeof(it->entry) - sizeof(it->timestamp)); -#endif - it = (struct _item_t *)((char *)it + size); - } - spin_unlock(&p->lock); -#ifdef VALGRIND - VALGRIND_MAKE_MEM_UNDEFINED(it, size); -#endif - } else + spin_lock(&mmap_lock); + if (mmap_ptr + size >= mmap_endptr) + mmap_grow(); + it = (struct _item_t *)mmap_ptr; + mmap_ptr += size; + spin_unlock(&mmap_lock); + __sync_sub_and_fetch(&triton_stat.mempool_available, size); + } else { it = md_malloc(size, fname, line); + __sync_add_and_fetch(&triton_stat.mempool_allocated, size); + } if (!it) { triton_log_error("mempool: out of memory\n"); @@ -194,11 +199,9 @@ void __export *mempool_alloc_md(mempool_t *pool, const char *fname, int line) list_add(&it->entry, &p->ditems); spin_unlock(&p->lock); - __sync_add_and_fetch(&triton_stat.mempool_allocated, size); - return it->ptr; } - +#endif void __export mempool_free(void *ptr) { @@ -323,6 +326,35 @@ void sigclean(int num) spin_unlock(&pools_lock); } +static int mmap_grow(void) +{ + int size = sysconf(_SC_PAGE_SIZE) * (1 << PAGE_ORDER); + void *ptr; + + if (mmap_endptr) { + ptr = mmap(mmap_endptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) + goto oom; + if (ptr != mmap_endptr) + mmap_ptr = ptr; + } else { + ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) + goto oom; + mmap_ptr = ptr; + } + + mmap_endptr = ptr + size; + + __sync_add_and_fetch(&triton_stat.mempool_allocated, size); + __sync_add_and_fetch(&triton_stat.mempool_available, size); + + return 0; +oom: + triton_log_error("mempool: out of memory\n"); + return -1; +} + static void __init init(void) { sigset_t set; @@ -334,5 +366,7 @@ static void __init init(void) }; sigaction(35, &sa, NULL); + + mmap_grow(); } |