Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Miscellaneous mbuf changes:



details:   https://anonhg.NetBSD.org/src/rev/4be797bd90a6
branches:  trunk
changeset: 768102:4be797bd90a6
user:      dyoung <dyoung%NetBSD.org@localhost>
date:      Mon Aug 08 19:10:33 2011 +0000

description:
Miscellaneous mbuf changes:

1 Add some protection against double-freeing mbufs in DIAGNOSTIC kernels.

2 Add a m_defrag() that's derived from
  sys/dev/pci/if_vge.c:vge_m_defrag().  This one copies the packet
  header.

3 Constify m_tag_find().

diffstat:

 sys/kern/uipc_mbuf.c  |  62 +++++++++++++++++++++++++++++++++++++++++++++++++-
 sys/kern/uipc_mbuf2.c |   6 ++--
 sys/sys/mbuf.h        |   8 ++++-
 3 files changed, 69 insertions(+), 7 deletions(-)

diffs (160 lines):

diff -r 5692a809f666 -r 4be797bd90a6 sys/kern/uipc_mbuf.c
--- a/sys/kern/uipc_mbuf.c      Mon Aug 08 18:57:58 2011 +0000
+++ b/sys/kern/uipc_mbuf.c      Mon Aug 08 19:10:33 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uipc_mbuf.c,v 1.141 2011/07/27 14:35:34 uebayasi Exp $ */
+/*     $NetBSD: uipc_mbuf.c,v 1.142 2011/08/08 19:10:33 dyoung Exp $   */
 
 /*-
  * Copyright (c) 1999, 2001 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.141 2011/07/27 14:35:34 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.142 2011/08/08 19:10:33 dyoung Exp $");
 
 #include "opt_mbuftrace.h"
 #include "opt_nmbclusters.h"
@@ -494,6 +494,8 @@
 {
        struct mbuf *m;
 
+       KASSERT(type != MT_FREE);
+
        m = pool_cache_get(mb_cache,
            nowait == M_WAIT ? PR_WAITOK|PR_LIMITFAIL : 0);
        if (m == NULL)
@@ -1249,6 +1251,62 @@
        return error;
 }
 
+/*
+ * Copy the mbuf chain to a new mbuf chain that is as short as possible.
+ * Return the new mbuf chain on success, NULL on failure.  On success,
+ * free the old mbuf chain.
+ */
+struct mbuf *
+m_defrag(struct mbuf *mold, int flags)
+{
+       struct mbuf *m0, *mn, *n;
+       size_t sz = mold->m_pkthdr.len;
+
+#ifdef DIAGNOSTIC
+       if ((mold->m_flags & M_PKTHDR) == 0)
+               panic("m_defrag: not a mbuf chain header");
+#endif
+
+       MGETHDR(m0, flags, MT_DATA);
+       if (m0 == NULL)
+               return NULL;
+       M_COPY_PKTHDR(m0, mold);
+       mn = m0;
+
+       do {
+               if (sz > MHLEN) {
+                       MCLGET(mn, M_DONTWAIT);
+                       if ((mn->m_flags & M_EXT) == 0) {
+                               m_freem(m0);
+                               return NULL;
+                       }
+               }
+
+               mn->m_len = MIN(sz, MCLBYTES);
+
+               m_copydata(mold, mold->m_pkthdr.len - sz, mn->m_len,
+                    mtod(mn, void *));
+
+               sz -= mn->m_len;
+
+               if (sz > 0) {
+                       /* need more mbufs */
+                       MGET(n, M_NOWAIT, MT_DATA);
+                       if (n == NULL) {
+                               m_freem(m0);
+                               return NULL;
+                       }
+
+                       mn->m_next = n;
+                       mn = n;
+               }
+       } while (sz > 0);
+
+       m_freem(mold);
+
+       return m0;
+}
+
 int
 m_copyback0(struct mbuf **mp0, int off, int len, const void *vp, int flags,
     int how)
diff -r 5692a809f666 -r 4be797bd90a6 sys/kern/uipc_mbuf2.c
--- a/sys/kern/uipc_mbuf2.c     Mon Aug 08 18:57:58 2011 +0000
+++ b/sys/kern/uipc_mbuf2.c     Mon Aug 08 19:10:33 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uipc_mbuf2.c,v 1.28 2009/04/18 14:58:04 tsutsui Exp $  */
+/*     $NetBSD: uipc_mbuf2.c,v 1.29 2011/08/08 19:10:33 dyoung Exp $   */
 /*     $KAME: uipc_mbuf2.c,v 1.29 2001/02/14 13:42:10 itojun Exp $     */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf2.c,v 1.28 2009/04/18 14:58:04 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf2.c,v 1.29 2011/08/08 19:10:33 dyoung Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -335,7 +335,7 @@
 
 /* Find a tag, starting from a given position. */
 struct m_tag *
-m_tag_find(struct mbuf *m, int type, struct m_tag *t)
+m_tag_find(const struct mbuf *m, int type, struct m_tag *t)
 {
        struct m_tag *p;
 
diff -r 5692a809f666 -r 4be797bd90a6 sys/sys/mbuf.h
--- a/sys/sys/mbuf.h    Mon Aug 08 18:57:58 2011 +0000
+++ b/sys/sys/mbuf.h    Mon Aug 08 19:10:33 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mbuf.h,v 1.144 2008/10/24 22:31:40 dyoung Exp $        */
+/*     $NetBSD: mbuf.h,v 1.145 2011/08/08 19:10:33 dyoung Exp $        */
 
 /*-
  * Copyright (c) 1996, 1997, 1999, 2001, 2007 The NetBSD Foundation, Inc.
@@ -551,6 +551,8 @@
        if ((m)->m_flags & M_EXT) {                                     \
                m_ext_free(m);                                          \
        } else {                                                        \
+               KASSERT(m->m_type != MT_FREE);                          \
+               m->m_type = MT_FREE;                                    \
                pool_cache_put(mb_cache, (m));                          \
        }                                                               \
 
@@ -667,6 +669,7 @@
 /* change mbuf to new type */
 #define MCHTYPE(m, t)                                                  \
 do {                                                                   \
+       KASSERT((t) != MT_FREE);                                        \
        mbstat_type_add((m)->m_type, -1);                               \
        mbstat_type_add(t, 1);                                          \
        (m)->m_type = t;                                                \
@@ -823,6 +826,7 @@
 struct mbuf *m_split(struct mbuf *,int, int);
 struct mbuf *m_getptr(struct mbuf *, int, int *);
 void   m_adj(struct mbuf *, int);
+struct mbuf *m_defrag(struct mbuf *, int);
 int    m_apply(struct mbuf *, int, int,
                int (*)(void *, void *, unsigned int), void *);
 void   m_cat(struct mbuf *,struct mbuf *);
@@ -854,7 +858,7 @@
 void   m_tag_delete(struct mbuf *, struct m_tag *);
 void   m_tag_delete_chain(struct mbuf *, struct m_tag *);
 void   m_tag_delete_nonpersistent(struct mbuf *);
-struct m_tag *m_tag_find(struct mbuf *, int, struct m_tag *);
+struct m_tag *m_tag_find(const struct mbuf *, int, struct m_tag *);
 struct m_tag *m_tag_copy(struct m_tag *);
 int    m_tag_copy_chain(struct mbuf *, struct mbuf *);
 void   m_tag_init(struct mbuf *);



Home | Main Index | Thread Index | Old Index