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);
        }
 

Reply via email to