On 13/11/17(Mon) 13:47, David Gwynne wrote:
> On Sun, Nov 12, 2017 at 11:23:31PM +0100, Gregor Best wrote:
> > Hi Martin,
> >
> > On Sun, Nov 12, 2017 at 03:40:59PM +0100, Martin Pieuchot wrote:
> > > [...]
> > > It does, some comments below.
> > > [...]
> >
> > Wonderful.
> >
> > > [...]
> > > This would be an approximation because it might happen that after
> > > returning NULL the second pool_get(9) won't sleep. However I think
> > > it's the way to go because m_get(9) calls that can wait are generally
> > > not performance critical.
> > > [...]
> >
> > I had not considered that the second pool_get might not block at all. On
> > the other hand `netstat -m` says "requests for memory delayed" for that
> > counter, so returning immediately on the second try not counting as a
> > delay is OK, I think.
> >
> > > [...]
> > > Please do not expand the splx(). Only the counter need it. Simply put
> > > the NULL check after the splx().
> > > [...]
> >
> > I'm not sure I understand. If I move the NULL check after the splx(),
> > counters_leave() will already have been called so increasing the counter
> > value has no effect anymore. The only additional things running under
> > splnet will be a few assignments, so I think moving the splx() a bit
> > further down does not hurt too much.
> >
> > Alternatively, I've attached a slightly different suggestion which
> > doesn't expand the scope of the splx() but duplicates a bit of code.
> > Does that make more sense?
>
> pools maintain count of how many times they failed to provide an
> allocation. you can watch this with vmstat -m or systat pool.
> however, we could use that to populate mb_drops too.
>
> the diff below moves populating the mbstat from kern_sysctl to
> uipc_mbuf, and adds copying of pr_nfails in.
Makes sense. So if we go this way, we can get rid of MBSTAT_DROPS,
MBSTAT_WAIT and MBSTAT_DRAIN that are currently unused.
> if we want to count the number of "delays", i could easily add that
> to pools too and copy it out in sysctl_mbstat.
That's be an interesting statistic.
> Index: sys/sysctl.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/sysctl.h,v
> retrieving revision 1.175
> diff -u -p -r1.175 sysctl.h
> --- sys/sysctl.h 12 Oct 2017 09:14:16 -0000 1.175
> +++ sys/sysctl.h 13 Nov 2017 03:42:32 -0000
> @@ -936,6 +936,7 @@ int sysctl_rdstruct(void *, size_t *, vo
> int sysctl_struct(void *, size_t *, void *, size_t, void *, size_t);
> int sysctl_file(int *, u_int, char *, size_t *, struct proc *);
> int sysctl_doproc(int *, u_int, char *, size_t *);
> +int sysctl_mbstat(int *, u_int, void *, size_t *, void *, size_t);
> struct mbuf_queue;
> int sysctl_mq(int *, u_int, void *, size_t *, void *, size_t,
> struct mbuf_queue *);
> Index: kern/kern_sysctl.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
> retrieving revision 1.330
> diff -u -p -r1.330 kern_sysctl.c
> --- kern/kern_sysctl.c 11 Aug 2017 21:24:19 -0000 1.330
> +++ kern/kern_sysctl.c 13 Nov 2017 03:42:32 -0000
> @@ -392,24 +392,9 @@ kern_sysctl(int *name, u_int namelen, vo
> case KERN_FILE:
> return (sysctl_file(name + 1, namelen - 1, oldp, oldlenp, p));
> #endif
> - case KERN_MBSTAT: {
> - extern struct cpumem *mbstat;
> - uint64_t counters[MBSTAT_COUNT];
> - struct mbstat mbs;
> - unsigned int i;
> -
> - memset(&mbs, 0, sizeof(mbs));
> - counters_read(mbstat, counters, MBSTAT_COUNT);
> - for (i = 0; i < MBSTAT_TYPES; i++)
> - mbs.m_mtypes[i] = counters[i];
> -
> - mbs.m_drops = counters[MBSTAT_DROPS];
> - mbs.m_wait = counters[MBSTAT_WAIT];
> - mbs.m_drain = counters[MBSTAT_DRAIN];
> -
> - return (sysctl_rdstruct(oldp, oldlenp, newp,
> - &mbs, sizeof(mbs)));
> - }
> + case KERN_MBSTAT:
> + return (sysctl_mbstat(name + 1, namelen -1, oldp, oldlenp,
> + newp, newlen));
> #if defined(GPROF) || defined(DDBPROF)
> case KERN_PROF:
> return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp,
> Index: kern/uipc_mbuf.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_mbuf.c,v
> retrieving revision 1.250
> diff -u -p -r1.250 uipc_mbuf.c
> --- kern/uipc_mbuf.c 12 Oct 2017 09:14:16 -0000 1.250
> +++ kern/uipc_mbuf.c 13 Nov 2017 03:42:32 -0000
> @@ -1421,6 +1421,30 @@ m_pool_init(struct pool *pp, u_int size,
> pool_set_constraints(pp, &kp_dma_contig);
> }
>
> +int
> +sysctl_mbstat(int *name, u_int namelen, void *oldp, size_t *oldlenp,
> + void *newp, size_t newlen)
> +{
> + uint64_t counters[MBSTAT_COUNT];
> + struct mbstat mbs;
> + unsigned int i;
> +
> + if (namelen != 0)
> + return (ENOTDIR);
> +
> + memset(&mbs, 0, sizeof(mbs));
> +
> + counters_read(mbstat, counters, MBSTAT_COUNT);
> + for (i = 0; i < MBSTAT_TYPES; i++)
> + mbs.m_mtypes[i] = counters[i];
> +
> + mbs.m_drops = counters[MBSTAT_DROPS] + mbpool.pr_nfail;
> + mbs.m_wait = counters[MBSTAT_WAIT];
> + mbs.m_drain = counters[MBSTAT_DRAIN]; /* pool gcs? */
> +
> + return (sysctl_rdstruct(oldp, oldlenp, newp, &mbs, sizeof(mbs)));
> +}
> +
> #ifdef DDB
> void
> m_print(void *v,