summaryrefslogtreecommitdiff
path: root/sys/kern/uipc_mbuf2.c
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2009-08-09 12:50:10 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2009-08-09 12:50:10 +0000
commit0e8942341818ecca77a176152f29e70c7319aadd (patch)
tree3ee749c17dcb17fd0ecd3bb368d6f047b5d69874 /sys/kern/uipc_mbuf2.c
parent472e8d44c683b7b141f1c15d16ea056ae642c8f3 (diff)
make mbuf tags suck a bit less, performance wise.
the most common operation is checking for a particular tag to be there. in the majority of the cases it is not. introduce a "tagsset" in the mbuf packet header which has a bit for each mbuf tag type that is in the chain set, checking for its existance is now as easy and cheap as (tagsset & type) != 0. theo ok
Diffstat (limited to 'sys/kern/uipc_mbuf2.c')
-rw-r--r--sys/kern/uipc_mbuf2.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/sys/kern/uipc_mbuf2.c b/sys/kern/uipc_mbuf2.c
index 60d3182fc7c..11b45a64d20 100644
--- a/sys/kern/uipc_mbuf2.c
+++ b/sys/kern/uipc_mbuf2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_mbuf2.c,v 1.29 2008/11/30 18:22:15 deraadt Exp $ */
+/* $OpenBSD: uipc_mbuf2.c,v 1.30 2009/08/09 12:50:09 henning Exp $ */
/* $KAME: uipc_mbuf2.c,v 1.29 2001/02/14 13:42:10 itojun Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.40 1999/04/01 00:23:25 thorpej Exp $ */
@@ -276,14 +276,23 @@ void
m_tag_prepend(struct mbuf *m, struct m_tag *t)
{
SLIST_INSERT_HEAD(&m->m_pkthdr.tags, t, m_tag_link);
+ m->m_pkthdr.tagsset |= t->m_tag_id;
}
/* Unlink and free a packet tag. */
void
m_tag_delete(struct mbuf *m, struct m_tag *t)
{
+ u_int32_t tagsset = 0;
+ struct m_tag *p;
+
SLIST_REMOVE(&m->m_pkthdr.tags, t, m_tag, m_tag_link);
free(t, M_PACKET_TAGS);
+
+ SLIST_FOREACH(p, &m->m_pkthdr.tags, m_tag_link)
+ tagsset |= p->m_tag_id;
+ m->m_pkthdr.tagsset = tagsset;
+
}
/* Unlink and free a packet tag chain. */
@@ -296,6 +305,7 @@ m_tag_delete_chain(struct mbuf *m)
SLIST_REMOVE_HEAD(&m->m_pkthdr.tags, m_tag_link);
free(p, M_PACKET_TAGS);
}
+ m->m_pkthdr.tagsset = 0;
}
/* Find a tag, starting from a given position. */
@@ -304,6 +314,9 @@ m_tag_find(struct mbuf *m, int type, struct m_tag *t)
{
struct m_tag *p;
+ if (!(m->m_pkthdr.tagsset & type))
+ return (NULL);
+
if (t == NULL)
p = SLIST_FIRST(&m->m_pkthdr.tags);
else
@@ -352,6 +365,7 @@ m_tag_copy_chain(struct mbuf *to, struct mbuf *from)
else
SLIST_INSERT_AFTER(tprev, t, m_tag_link);
tprev = t;
+ to->m_pkthdr.tagsset |= t->m_tag_id;
}
return (1);
}