Here's a preview of what will happen to "struct pkthdr".  Do not store a
pointer since ifp might disappear.  That will allow us to stop garbage
collecting the various queues when an interface is destroy/detached and
since the per-ifp lists might also need some concurrent protection, we
can easily fold that around if_get().

But before talking about pkthdr, let's remove the related ifp pointer
in the "struct mbuf_ext", diff below, ok?

Index: share/man/man9/mbuf.9
===================================================================
RCS file: /home/ncvs/src/share/man/man9/mbuf.9,v
retrieving revision 1.69
diff -u -p -r1.69 mbuf.9
--- share/man/man9/mbuf.9       19 Mar 2014 10:09:19 -0000      1.69
+++ share/man/man9/mbuf.9       26 Mar 2014 15:26:36 -0000
@@ -140,7 +140,7 @@ struct mbuf_ext {
        void    *ext_arg;
        u_int   ext_size;
        int     ext_type;
-       struct ifnet* ext_ifp;
+       u_short ext_ifidx;
        int     ext_backend;
        struct mbuf *ext_nextref;
        struct mbuf *ext_prevref;
Index: sys/kern/uipc_mbuf.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.178
diff -u -p -r1.178 uipc_mbuf.c
--- sys/kern/uipc_mbuf.c        19 Jan 2014 03:04:54 -0000      1.178
+++ sys/kern/uipc_mbuf.c        26 Mar 2014 15:26:36 -0000
@@ -402,15 +402,18 @@ void
 m_cluncount(struct mbuf *m, int all)
 {
        struct mbuf_ext *me;
+       struct ifnet *ifp;
 
        do {
                me = &m->m_ext;
                if (((m->m_flags & (M_EXT|M_CLUSTER)) != (M_EXT|M_CLUSTER)) ||
-                   (me->ext_ifp == NULL))
+                   (me->ext_ifidx == 0))
                        continue;
 
-               me->ext_ifp->if_data.ifi_mclpool[me->ext_backend].mcl_alive--;
-               me->ext_ifp = NULL;
+               ifp = if_get(me->ext_ifidx);
+               if (ifp != NULL)
+                       ifp->if_data.ifi_mclpool[me->ext_backend].mcl_alive--;
+               me->ext_ifidx = 0;
        } while (all && (m = m->m_next));
 }
 
@@ -460,7 +463,10 @@ m_clget(struct mbuf *m, int how, struct 
        m->m_ext.ext_free = NULL;
        m->m_ext.ext_arg = NULL;
        m->m_ext.ext_backend = pi;
-       m->m_ext.ext_ifp = ifp;
+       if (ifp != NULL)
+               m->m_ext.ext_ifidx = ifp->if_index;
+       else
+               m->m_ext.ext_ifidx = 0;
        MCLINITREFERENCE(m);
        return (m);
 }
@@ -1375,7 +1381,7 @@ m_print(void *v,
                    m->m_ext.ext_buf, m->m_ext.ext_size);
                (*pr)("m_ext.ext_type: %x\tm_ext.ext_backend: %i\n",
                    m->m_ext.ext_type, m->m_ext.ext_backend);
-               (*pr)("m_ext.ext_ifp: %p\n", m->m_ext.ext_ifp);
+               (*pr)("m_ext.ext_ifidx: %u\n", m->m_ext.ext_ifidx);
                (*pr)("m_ext.ext_free: %p\tm_ext.ext_arg: %p\n",
                    m->m_ext.ext_free, m->m_ext.ext_arg);
                (*pr)("m_ext.ext_nextref: %p\tm_ext.ext_prevref: %p\n",
Index: sys/sys/mbuf.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/mbuf.h,v
retrieving revision 1.173
diff -u -p -r1.173 mbuf.h
--- sys/sys/mbuf.h      19 Mar 2014 10:09:20 -0000      1.173
+++ sys/sys/mbuf.h      26 Mar 2014 15:26:36 -0000
@@ -130,7 +130,7 @@ struct mbuf_ext {
        void    *ext_arg;               /* argument for ext_free */
        u_int   ext_size;               /* size of buffer, for ext_free */
        int     ext_type;
-       struct ifnet* ext_ifp;
+       u_short ext_ifidx;              /* index of the interface */
        int     ext_backend;            /* backend pool the storage came from */
        struct mbuf *ext_nextref;
        struct mbuf *ext_prevref;

Reply via email to