summaryrefslogtreecommitdiffstats
path: root/sys/netgraph/ng_ppp.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2008-01-26 22:39:05 +0000
committermav <mav@FreeBSD.org>2008-01-26 22:39:05 +0000
commit4b87cfa8f895a89a0108387b5ecae05f2bbd87ba (patch)
tree68c149acbc3a1dcb9cfa77b82fd9af848feeb80c /sys/netgraph/ng_ppp.c
parent13fcc58a15a2e25c54bd64d9ddc5047df408d1ab (diff)
downloadFreeBSD-src-4b87cfa8f895a89a0108387b5ecae05f2bbd87ba.zip
FreeBSD-src-4b87cfa8f895a89a0108387b5ecae05f2bbd87ba.tar.gz
Improve multilink receive performance with fragment headers preallocation.
Diffstat (limited to 'sys/netgraph/ng_ppp.c')
-rw-r--r--sys/netgraph/ng_ppp.c45
1 files changed, 23 insertions, 22 deletions
diff --git a/sys/netgraph/ng_ppp.c b/sys/netgraph/ng_ppp.c
index 408ba4b9..86fa186 100644
--- a/sys/netgraph/ng_ppp.c
+++ b/sys/netgraph/ng_ppp.c
@@ -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;
}
/*
OpenPOWER on IntegriCloud