diff options
author | Alexander Motin <mav@FreeBSD.org> | 2008-01-26 22:39:05 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2008-01-26 22:39:05 +0000 |
commit | 93caf2e299834a56d6ece6bc6bd637a3fd0f2331 (patch) | |
tree | 68c149acbc3a1dcb9cfa77b82fd9af848feeb80c /sys/netgraph/ng_ppp.c | |
parent | 650bd88c746e3b9ceef88529681db34537829e50 (diff) | |
download | src-93caf2e299834a56d6ece6bc6bd637a3fd0f2331.tar.gz src-93caf2e299834a56d6ece6bc6bd637a3fd0f2331.zip |
Improve multilink receive performance with fragment headers preallocation.
Notes
Notes:
svn path=/head/; revision=175696
Diffstat (limited to 'sys/netgraph/ng_ppp.c')
-rw-r--r-- | sys/netgraph/ng_ppp.c | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/sys/netgraph/ng_ppp.c b/sys/netgraph/ng_ppp.c index 408ba4b905a6..86fa18687451 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; } /* |