From 4b87cfa8f895a89a0108387b5ecae05f2bbd87ba Mon Sep 17 00:00:00 2001 From: mav Date: Sat, 26 Jan 2008 22:39:05 +0000 Subject: Improve multilink receive performance with fragment headers preallocation. --- sys/netgraph/ng_ppp.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'sys/netgraph/ng_ppp.c') 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; } /* -- cgit v1.1