On Sat, Sep 03, 2022 at 03:39:00AM +0300, Vitaliy Makkoveev wrote: > Since we are not the special case where we have no resource allocation > in runtime, because all required resources are pre-allocated by design,
During packet processing we do not wait, but drop the packet. Network semantics allows packet loss. > the memory errors are absolutely normal Yes. But in system call you wait. Then userland gets consistent behavior. System call must not fail due to temporary memory shortage. System call fails if it is a persistent failure. The persistent failure is caused by bad behavior from the userland, like exceeding some limit. Temporary failure can happen anytime. > and should be handled by userland. Userland does not retry. Kernel is buggy and does not do it either. I have a diff that introduces random malloc failures. You cannot boot to multiuser as handling NULL is incomplete. The kernel should recover by waiting. Only if this is not feasable, pass the error to userland. Then the userland has to do something smart. In theory OpenBSD should run with the diff below. But we would have to fix a lot of bugs for that. Currently these are races that are not triggered. The design of malloc(9) is that if some userland process needs memory, but there is not enough in the system, it has to wait. Some other part of the kernel or userland will free it eventually. Then the request can succeed. bluhm Index: kern/kern_malloc.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/kern/kern_malloc.c,v retrieving revision 1.148 diff -u -p -r1.148 kern_malloc.c --- kern/kern_malloc.c 14 Aug 2022 01:58:27 -0000 1.148 +++ kern/kern_malloc.c 3 Sep 2022 13:18:24 -0000 @@ -184,6 +184,15 @@ malloc(size_t size, int type, int flags) } #endif + if (!cold && (flags & (M_NOWAIT|M_CANFAIL))) { + static int failcount; + + if (failcount == 0) + failcount = arc4random(); + if ((failcount++ & 0xfff) == 0) + return (NULL); + } + if (size > 65535 * PAGE_SIZE) { if (flags & M_CANFAIL) { #ifndef SMALL_KERNEL Index: kern/subr_pool.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/kern/subr_pool.c,v retrieving revision 1.236 diff -u -p -r1.236 subr_pool.c --- kern/subr_pool.c 14 Aug 2022 01:58:28 -0000 1.236 +++ kern/subr_pool.c 3 Sep 2022 13:17:33 -0000 @@ -567,6 +567,15 @@ pool_get(struct pool *pp, int flags) if (pp->pr_flags & PR_RWLOCK) KASSERT(flags & PR_WAITOK); + if (!cold && (flags & (PR_NOWAIT|PR_LIMITFAIL))) { + static int failcount; + + if (failcount == 0) + failcount = arc4random(); + if ((failcount++ & 0xfff) == 0) + return (NULL); + } + #ifdef MULTIPROCESSOR if (pp->pr_cache != NULL) { v = pool_cache_get(pp);