Hi people,
while reading around in /sys/kern/uipc_mbuf.c to try to track down a
problem with my iwm(4) that seems to correlate with mbuf allocation
failures, I noticed that the MBSTAT_DROPS counter and its friends
MBSTAT_{WAIT,DRAIN} don't seem to get increased anywhere in /sys.
Does the patch below the signature make sense for counting MBSTAT_DROPS?
I've got a similar patch for MBSTAT_WAIT, but it's pretty ugly because
as far as I can see, there's no real way to notice when pool_get sleeps
except for "Try pool_get with M_NOWAIT first and if that returns NULL,
try again with M_WAITOK".
--
Gregor
Index: /sys/kern/uipc_mbuf.c
===================================================================
RCS file: /home/cvs/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.250
diff -u -p -r1.250 uipc_mbuf.c
--- /sys/kern/uipc_mbuf.c 12 Oct 2017 09:14:16 -0000 1.250
+++ /sys/kern/uipc_mbuf.c 11 Nov 2017 12:03:39 -0000
@@ -233,14 +233,14 @@ m_get(int nowait, int type)
KDASSERT(type < MT_NTYPES);
m = pool_get(&mbpool, nowait == M_WAIT ? PR_WAITOK : PR_NOWAIT);
- if (m == NULL)
- return (NULL);
s = splnet();
counters = counters_enter(&cr, mbstat);
+ if (m == NULL) {
+ counters[MBSTAT_DROPS]++;
+ goto out;
+ }
counters[type]++;
- counters_leave(&cr, mbstat);
- splx(s);
m->m_type = type;
m->m_next = NULL;
@@ -248,6 +248,10 @@ m_get(int nowait, int type)
m->m_data = m->m_dat;
m->m_flags = 0;
+out:
+ counters_leave(&cr, mbstat);
+ splx(s);
+
return (m);
}
@@ -266,16 +270,23 @@ m_gethdr(int nowait, int type)
KDASSERT(type < MT_NTYPES);
m = pool_get(&mbpool, nowait == M_WAIT ? PR_WAITOK : PR_NOWAIT);
- if (m == NULL)
- return (NULL);
s = splnet();
counters = counters_enter(&cr, mbstat);
+ if (m == NULL) {
+ counters[MBSTAT_DROPS]++;
+ goto out;
+ }
counters[type]++;
+
+ m->m_type = type;
+
+out:
counters_leave(&cr, mbstat);
splx(s);
- m->m_type = type;
+ if (m == NULL)
+ return NULL;
return (m_inithdr(m));
}
@@ -349,7 +360,10 @@ m_clget(struct mbuf *m, int how, u_int p
{
struct mbuf *m0 = NULL;
struct pool *pp;
+ struct counters_ref cr;
+ uint64_t *counters;
caddr_t buf;
+ int s;
pp = m_clpool(pktlen);
#ifdef DIAGNOSTIC
@@ -364,9 +378,16 @@ m_clget(struct mbuf *m, int how, u_int p
m = m0;
}
+
buf = pool_get(pp, how == M_WAIT ? PR_WAITOK : PR_NOWAIT);
+
if (buf == NULL) {
m_freem(m0);
+ s = splnet();
+ counters = counters_enter(&cr, mbstat);
+ counters[MBSTAT_DROPS]++;
+ counters_leave(&cr, mbstat);
+ splx(s);
return (NULL);
}