On 16/07/19(Tue) 21:35, Alexander Bluhm wrote:
> Hi,
>
> When the kernel reaches the sysclt kern.maxclusters limit, operations
> get stuck while holding the net lock. Increasing the limit does
> not help as there is no wakeup of the pools. So run through the
> mbuf pool request list when the limit changes.
Should you call pool_wakeup() only if the new limit is greater than the
current one?
> There seem to more problems when recovering from mbuf shortage, but
> this is the most obvious one.
By more problems to you mean "How to give mbuf back to the pool"?
> ok?
>
> bluhm
>
> Index: kern/subr_pool.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/kern/subr_pool.c,v
> retrieving revision 1.227
> diff -u -p -r1.227 subr_pool.c
> --- kern/subr_pool.c 23 Apr 2019 13:35:12 -0000 1.227
> +++ kern/subr_pool.c 16 Jul 2019 18:02:08 -0000
> @@ -815,6 +815,12 @@ pool_put(struct pool *pp, void *v)
> if (freeph != NULL)
> pool_p_free(pp, freeph);
>
> + pool_wakeup(pp);
> +}
> +
> +void
> +pool_wakeup(struct pool *pp)
> +{
> if (!TAILQ_EMPTY(&pp->pr_requests)) {
> pl_enter(pp, &pp->pr_requests_lock);
> pool_runqueue(pp, PR_NOWAIT);
> Index: kern/uipc_mbuf.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_mbuf.c,v
> retrieving revision 1.270
> diff -u -p -r1.270 uipc_mbuf.c
> --- kern/uipc_mbuf.c 16 Jul 2019 17:39:02 -0000 1.270
> +++ kern/uipc_mbuf.c 16 Jul 2019 18:04:33 -0000
> @@ -167,8 +167,6 @@ mbinit(void)
>
> m_pool_allocator.pa_pagesz = pool_allocator_multi.pa_pagesz;
>
> - error = nmbclust_update(nmbclust);
> - KASSERT(error == 0);
> mbuf_mem_alloc = 0;
>
> #if DIAGNOSTIC
> @@ -196,6 +194,9 @@ mbinit(void)
> m_pool_init(&mclpools[i], mclsizes[i], 64, mclnames[i]);
> }
>
> + error = nmbclust_update(nmbclust);
> + KASSERT(error == 0);
> +
> (void)mextfree_register(m_extfree_pool);
> KASSERT(num_extfree_fns == 1);
> }
> @@ -217,11 +218,18 @@ mbcpuinit()
> int
> nmbclust_update(long newval)
> {
> + int i;
> +
> if (newval < 0 || newval > LONG_MAX / MCLBYTES)
> return ERANGE;
> /* update the global mbuf memory limit */
> nmbclust = newval;
> mbuf_mem_limit = nmbclust * MCLBYTES;
> +
> + pool_wakeup(&mbpool);
> + for (i = 0; i < nitems(mclsizes); i++)
> + pool_wakeup(&mclpools[i]);
> +
> return 0;
> }
>
> Index: sys/pool.h
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/sys/pool.h,v
> retrieving revision 1.76
> diff -u -p -r1.76 pool.h
> --- sys/pool.h 10 Feb 2019 22:45:58 -0000 1.76
> +++ sys/pool.h 16 Jul 2019 18:02:08 -0000
> @@ -271,6 +271,7 @@ void pool_request_init(struct pool_requ
> void (*)(struct pool *, void *, void *), void *);
> void pool_request(struct pool *, struct pool_request *);
> void pool_put(struct pool *, void *);
> +void pool_wakeup(struct pool *);
> int pool_reclaim(struct pool *);
> void pool_reclaim_all(void);
> int pool_prime(struct pool *, int);
>