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;