summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2011-01-17 18:08:11 +0300
committerDmitry Kozlov <xeb@mail.ru>2011-01-17 18:08:11 +0300
commitc783f297faa2453daca7189182a17f913e003ccc (patch)
tree0527171103dbe568658ea21262e1027b7023bf9a
parent56762d9574d05bff9709c856f9f466c51156f549 (diff)
downloadaccel-ppp-c783f297faa2453daca7189182a17f913e003ccc.tar.gz
accel-ppp-c783f297faa2453daca7189182a17f913e003ccc.zip
memory usage optimization
-rw-r--r--accel-pppd/CMakeLists.txt11
-rw-r--r--accel-pppd/auth/auth_chap_md5.c4
-rw-r--r--accel-pppd/auth/auth_mschap_v1.c4
-rw-r--r--accel-pppd/auth/auth_mschap_v2.c4
-rw-r--r--accel-pppd/auth/auth_pap.c4
-rw-r--r--accel-pppd/cli/std_cmd.c13
-rw-r--r--accel-pppd/extra/chap-secrets.c1
-rw-r--r--accel-pppd/memdebug.c4
-rw-r--r--accel-pppd/memdebug.h2
-rw-r--r--accel-pppd/ppp/ppp.c59
-rw-r--r--accel-pppd/ppp/ppp.h6
-rw-r--r--accel-pppd/ppp/ppp_ccp.c6
-rw-r--r--accel-pppd/ppp/ppp_ipcp.c6
-rw-r--r--accel-pppd/ppp/ppp_lcp.c10
-rw-r--r--accel-pppd/radius/packet.c36
-rw-r--r--accel-pppd/triton/mempool.c104
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();
}