Improve multilink receive performance with fragment headers preallocation.

This commit is contained in:
Alexander Motin 2008-01-26 22:39:05 +00:00
parent 650bd88c74
commit 93caf2e299

View File

@ -217,9 +217,11 @@ struct ng_ppp_private {
uint8_t vjCompHooked; /* VJ comp hooked up? */
uint8_t allLinksEqual; /* all xmit the same? */
hook_p hooks[HOOK_INDEX_MAX]; /* non-link hooks */
struct ng_ppp_frag fragsmem[MP_MAX_QUEUE_LEN]; /* fragments storage */
TAILQ_HEAD(ng_ppp_fraglist, ng_ppp_frag) /* fragment queue */
frags;
int qlen; /* fraq queue length */
TAILQ_HEAD(ng_ppp_fragfreelist, ng_ppp_frag) /* free fragment queue */
fragsfree;
struct callout fragTimer; /* fraq queue check */
struct mtx rmtx; /* recv mutex */
struct mtx xmtx; /* xmit mutex */
@ -496,6 +498,9 @@ ng_ppp_constructor(node_p node)
/* Initialize state */
TAILQ_INIT(&priv->frags);
TAILQ_INIT(&priv->fragsfree);
for (i = 0; i < MP_MAX_QUEUE_LEN; i++)
TAILQ_INSERT_TAIL(&priv->fragsfree, &priv->fragsmem[i], f_qent);
for (i = 0; i < NG_PPP_MAX_LINKS; i++)
priv->links[i].seq = MP_NOSEQ;
ng_callout_init(&priv->fragTimer);
@ -1489,7 +1494,7 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
{
const priv_p priv = NG_NODE_PRIVATE(node);
struct ng_ppp_link *const link = &priv->links[linkNum];
struct ng_ppp_frag frag0, *frag = &frag0;
struct ng_ppp_frag *frag;
struct ng_ppp_frag *qent;
int i, diff, inserted;
struct mbuf *m;
@ -1507,6 +1512,13 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
NGI_GET_M(item, m);
NG_FREE_ITEM(item);
/* Get a new frag struct from the free queue */
if ((frag = TAILQ_FIRST(&priv->fragsfree)) == NULL) {
printf("No free fragments headers in ng_ppp!\n");
NG_FREE_M(m);
goto process;
}
/* Extract fragment information from MP header */
if (priv->conf.recvShortSeq) {
uint16_t shdr;
@ -1564,13 +1576,8 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
priv->mseq = alink->seq;
}
/* Allocate a new frag struct for the queue */
MALLOC(frag, struct ng_ppp_frag *, sizeof(*frag), M_NETGRAPH_PPP, M_NOWAIT);
if (frag == NULL) {
NG_FREE_M(m);
goto process;
}
*frag = frag0;
/* Remove frag struct from free queue. */
TAILQ_REMOVE(&priv->fragsfree, frag, f_qent);
/* Add fragment to queue, which is sorted by sequence number */
inserted = 0;
@ -1583,13 +1590,12 @@ ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
} else if (diff == 0) { /* should never happen! */
link->stats.dupFragments++;
NG_FREE_M(frag->data);
FREE(frag, M_NETGRAPH_PPP);
TAILQ_INSERT_HEAD(&priv->fragsfree, frag, f_qent);
ERROUT(EINVAL);
}
}
if (!inserted)
TAILQ_INSERT_HEAD(&priv->frags, frag, f_qent);
priv->qlen++;
process:
/* Process the queue */
@ -1693,8 +1699,7 @@ ng_ppp_get_packet(node_p node, struct mbuf **mp)
/* Bump MSEQ if necessary */
ng_ppp_bump_mseq(node, qent->seq);
}
FREE(qent, M_NETGRAPH_PPP);
priv->qlen--;
TAILQ_INSERT_HEAD(&priv->fragsfree, qent, f_qent);
}
*mp = m;
}
@ -1742,8 +1747,7 @@ ng_ppp_frag_trim(node_p node)
priv->bundleStats.dropFragments++;
TAILQ_REMOVE(&priv->frags, qent, f_qent);
NG_FREE_M(qent->data);
FREE(qent, M_NETGRAPH_PPP);
priv->qlen--;
TAILQ_INSERT_HEAD(&priv->fragsfree, qent, f_qent);
removed = 1;
}
}
@ -1760,7 +1764,7 @@ ng_ppp_frag_drop(node_p node)
const priv_p priv = NG_NODE_PRIVATE(node);
/* Check queue length */
if (priv->qlen > MP_MAX_QUEUE_LEN) {
if (TAILQ_EMPTY(&priv->fragsfree)) {
struct ng_ppp_frag *qent;
/* Get oldest fragment */
@ -1775,8 +1779,7 @@ ng_ppp_frag_drop(node_p node)
priv->bundleStats.dropFragments++;
TAILQ_REMOVE(&priv->frags, qent, f_qent);
NG_FREE_M(qent->data);
FREE(qent, M_NETGRAPH_PPP);
priv->qlen--;
TAILQ_INSERT_HEAD(&priv->fragsfree, qent, f_qent);
return (1);
}
@ -1894,8 +1897,7 @@ ng_ppp_frag_checkstale(node_p node)
priv->bundleStats.dropFragments++;
TAILQ_REMOVE(&priv->frags, qent, f_qent);
NG_FREE_M(qent->data);
FREE(qent, M_NETGRAPH_PPP);
priv->qlen--;
TAILQ_INSERT_HEAD(&priv->fragsfree, qent, f_qent);
}
/* Extract completed packet */
@ -2548,10 +2550,9 @@ ng_ppp_frag_reset(node_p node)
for (qent = TAILQ_FIRST(&priv->frags); qent; qent = qnext) {
qnext = TAILQ_NEXT(qent, f_qent);
NG_FREE_M(qent->data);
FREE(qent, M_NETGRAPH_PPP);
TAILQ_INSERT_HEAD(&priv->fragsfree, qent, f_qent);
}
TAILQ_INIT(&priv->frags);
priv->qlen = 0;
}
/*