Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance issue caused by invoking 'rte_malloc' frequently. #595

Draft
wants to merge 3 commits into
base: devel
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/inetaddr.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,11 @@ static uint32_t ifa_msg_seq(void)
static inline struct inet_device *dev_get_idev(const struct netif_port *dev)
{
assert(dev && dev->in_ptr);
rte_atomic32_inc(&dev->in_ptr->refcnt);
return dev->in_ptr;
}

static inline void idev_put(struct inet_device *idev)
{
rte_atomic32_dec(&idev->refcnt);
}

static inline void imc_hash(struct inet_ifmcaddr *imc, struct inet_device *idev)
Expand Down
71 changes: 67 additions & 4 deletions src/ipvs/ip_vs_proto_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ struct conn_uoa {
uint8_t acked;
};

static struct rte_mempool *g_uoa_cache[DPVS_MAX_SOCKET];
#define this_uoa_cache (g_uoa_cache[rte_socket_id()])

static int g_uoa_max_trail = UOA_DEF_MAX_TRAIL; /* zero to disable UOA */
static int g_uoa_mode = UOA_M_OPP; /* by default */

Expand Down Expand Up @@ -148,6 +151,7 @@ static int udp_conn_sched(struct dp_vs_proto *proto,
struct dp_vs_conn **conn,
int *verdict)
{
int err;
struct udp_hdr *uh, _udph;
struct dp_vs_service *svc;
bool outwall = false;
Expand Down Expand Up @@ -177,8 +181,8 @@ static int udp_conn_sched(struct dp_vs_proto *proto,
if ((*conn)->dest->fwdmode == DPVS_FWD_MODE_FNAT && g_uoa_max_trail > 0) {
struct conn_uoa *uoa;

(*conn)->prot_data = rte_zmalloc(NULL, sizeof(struct conn_uoa), 0);
if (!(*conn)->prot_data) {
err = rte_mempool_get(this_uoa_cache, (void **)&((*conn)->prot_data));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now, struct conn_uoa has 6 bytes only, maybe use prot_data directly
uoa = (void*)&(*conn)->prot_data

if (err != 0) {
RTE_LOG(WARNING, IPVS, "%s: no memory for UOA\n", __func__);
} else {
uoa = (struct conn_uoa *)(*conn)->prot_data;
Expand Down Expand Up @@ -243,8 +247,9 @@ udp_conn_lookup(struct dp_vs_proto *proto,

static int udp_conn_expire(struct dp_vs_proto *proto, struct dp_vs_conn *conn)
{
if (conn->prot_data)
rte_free(conn->prot_data);
if (conn->prot_data) {
rte_mempool_put(this_uoa_cache, conn->prot_data);
}

return EDPVS_OK;
}
Expand Down Expand Up @@ -785,9 +790,67 @@ static int udp_snat_out_handler(struct dp_vs_proto *proto,
return udp_send_csum(af, iphdrlen, uh, conn, mbuf, NULL);
}

static int create_uoa_cache(void);
static void destroy_uoa_cache(void);

static int create_uoa_cache(void)
{
int i;
char pool_name[32];

for (i = 0; i < get_numa_nodes(); i++) {
snprintf(pool_name, sizeof(pool_name), "dp_vs_uoa_%d", i);

g_uoa_cache[i] = rte_mempool_create(pool_name,
dp_vs_conn_pool_size(),
sizeof(struct conn_uoa),
dp_vs_conn_pool_cache_size(),
0, NULL, NULL, NULL, NULL, i, 0);

if (unlikely(!g_uoa_cache[i])) {
destroy_uoa_cache();
return EDPVS_NOMEM;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

free previous uoa_cache memory before return

}
}

return EDPVS_OK;
}

static void destroy_uoa_cache(void)
{
int i;

for (i = 0; i < get_numa_nodes(); i++) {
if (g_uoa_cache[i]) {
rte_mempool_free(g_uoa_cache[i]);
g_uoa_cache[i] = NULL;
}
}
}

static int udp_init(struct dp_vs_proto *proto)
{
int err;

err = create_uoa_cache();
if (unlikely(err != EDPVS_OK)) {
return err;
}

return EDPVS_OK;
}

static int udp_exit(struct dp_vs_proto *proto)
{
destroy_uoa_cache();
return EDPVS_OK;
}

struct dp_vs_proto dp_vs_proto_udp = {
.name = "UDP",
.proto = IPPROTO_UDP,
.init = udp_init,
.exit = udp_exit,
.timeout_table = udp_timeouts,
.conn_sched = udp_conn_sched,
.conn_lookup = udp_conn_lookup,
Expand Down