Re: protocol attach wait

2022-09-23 Thread Alexander Bluhm
On Sat, Sep 03, 2022 at 03:39:00AM +0300, Vitaliy Makkoveev wrote:
> On Fri, Sep 02, 2022 at 11:56:02AM +0200, Alexander Bluhm wrote:
> I'm not blocking this, may be something other has the different opinion.

I strongly believe that userland should not care about short time
memory shortage in kernel.  This is the idea of the M_WAIT flag.

Is there any reason why I should not commit this and keep unreliable
socket(2) system call?

> 
> > ok?
> > 
> > bluhm
> > 
> > Index: kern/uipc_socket.c
> > ===
> > RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket.c,v
> > retrieving revision 1.286
> > diff -u -p -r1.286 uipc_socket.c
> > --- kern/uipc_socket.c  28 Aug 2022 18:43:12 -  1.286
> > +++ kern/uipc_socket.c  1 Sep 2022 18:47:36 -
> > @@ -138,11 +138,12 @@ soinit(void)
> >  }
> >  
> >  struct socket *
> > -soalloc(int prflags)
> > +soalloc(int wait)
> >  {
> > struct socket *so;
> >  
> > -   so = pool_get(_pool, prflags);
> > +   so = pool_get(_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
> > +   PR_ZERO);
> > if (so == NULL)
> > return (NULL);
> > rw_init_flags(>so_lock, "solock", RWL_DUPOK);
> > @@ -174,7 +175,7 @@ socreate(int dom, struct socket **aso, i
> > return (EPROTONOSUPPORT);
> > if (prp->pr_type != type)
> > return (EPROTOTYPE);
> > -   so = soalloc(PR_WAITOK | PR_ZERO);
> > +   so = soalloc(M_WAIT);
> > klist_init(>so_rcv.sb_sel.si_note, _klistops, so);
> > klist_init(>so_snd.sb_sel.si_note, _klistops, so);
> > sigio_init(>so_sigio);
> > @@ -193,7 +194,7 @@ socreate(int dom, struct socket **aso, i
> > so->so_rcv.sb_timeo_nsecs = INFSLP;
> >  
> > solock(so);
> > -   error = pru_attach(so, proto);
> > +   error = pru_attach(so, proto, M_WAIT);
> > if (error) {
> > so->so_state |= SS_NOFDREF;
> > /* sofree() calls sounlock(). */
> > Index: kern/uipc_socket2.c
> > ===
> > RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket2.c,v
> > retrieving revision 1.127
> > diff -u -p -r1.127 uipc_socket2.c
> > --- kern/uipc_socket2.c 13 Aug 2022 21:01:46 -  1.127
> > +++ kern/uipc_socket2.c 1 Sep 2022 18:47:36 -
> > @@ -168,7 +168,7 @@ soisdisconnected(struct socket *so)
> >   * Connstatus may be 0 or SS_ISCONNECTED.
> >   */
> >  struct socket *
> > -sonewconn(struct socket *head, int connstatus)
> > +sonewconn(struct socket *head, int connstatus, int wait)
> >  {
> > struct socket *so;
> > int persocket = solock_persocket(head);
> > @@ -185,7 +185,7 @@ sonewconn(struct socket *head, int conns
> > return (NULL);
> > if (head->so_qlen + head->so_q0len > head->so_qlimit * 3)
> > return (NULL);
> > -   so = soalloc(PR_NOWAIT | PR_ZERO);
> > +   so = soalloc(wait);
> > if (so == NULL)
> > return (NULL);
> > so->so_type = head->so_type;
> > @@ -238,7 +238,7 @@ sonewconn(struct socket *head, int conns
> > sounlock(head);
> > }
> >  
> > -   error = pru_attach(so, 0);
> > +   error = pru_attach(so, 0, wait);
> >  
> > if (persocket) {
> > sounlock(so);
> > Index: kern/uipc_usrreq.c
> > ===
> > RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_usrreq.c,v
> > retrieving revision 1.181
> > diff -u -p -r1.181 uipc_usrreq.c
> > --- kern/uipc_usrreq.c  31 Aug 2022 21:23:02 -  1.181
> > +++ kern/uipc_usrreq.c  1 Sep 2022 18:47:36 -
> > @@ -302,7 +302,7 @@ const struct sysctl_bounded_args unpdgct
> >  };
> >  
> >  int
> > -uipc_attach(struct socket *so, int proto)
> > +uipc_attach(struct socket *so, int proto, int wait)
> >  {
> > struct unpcb *unp;
> > int error;
> > @@ -330,7 +330,8 @@ uipc_attach(struct socket *so, int proto
> > if (error)
> > return (error);
> > }
> > -   unp = pool_get(_pool, PR_NOWAIT|PR_ZERO);
> > +   unp = pool_get(_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
> > +   PR_ZERO);
> > if (unp == NULL)
> > return (ENOBUFS);
> > refcnt_init(>unp_refcnt);
> > @@ -855,7 +856,7 @@ unp_connect(struct socket *so, struct mb
> > solock(so2);
> >  
> > if ((so2->so_options & SO_ACCEPTCONN) == 0 ||
> > -   (so3 = sonewconn(so2, 0)) == NULL) {
> > +   (so3 = sonewconn(so2, 0, M_WAIT)) == NULL) {
> > error = ECONNREFUSED;
> > }
> >  
> > Index: net/pfkeyv2.c
> > ===
> > RCS file: /data/mirror/openbsd/cvs/src/sys/net/pfkeyv2.c,v
> > retrieving revision 1.248
> > diff -u -p -r1.248 pfkeyv2.c
> > --- net/pfkeyv2.c   31 Aug 2022 21:23:02 -  1.248
> > +++ net/pfkeyv2.c   2 Sep 2022 09:32:49 -
> > @@ -169,7 +169,7 @@ static int 

Re: protocol attach wait

2022-09-03 Thread Alexander Bluhm
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 -  1.148
+++ kern/kern_malloc.c  3 Sep 2022 13:18:24 -
@@ -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.c14 Aug 2022 01:58:28 -  1.236
+++ kern/subr_pool.c3 Sep 2022 13:17:33 -
@@ -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);



Re: protocol attach wait

2022-09-02 Thread Vitaliy Makkoveev
On Fri, Sep 02, 2022 at 11:56:02AM +0200, Alexander Bluhm wrote:
> On Thu, Sep 01, 2022 at 11:04:19PM +0300, Vitaliy Makkoveev wrote:
> > On Thu, Sep 01, 2022 at 10:58:49PM +0300, Vitaliy Makkoveev wrote:
> > > On Thu, Sep 01, 2022 at 09:00:50PM +0200, Alexander Bluhm wrote:
> > > > On Mon, Aug 15, 2022 at 05:12:22PM +0200, Alexander Bluhm wrote:
> > > > > System calls should not fail due to temporary memory shortage in
> > > > > malloc(9) or pool_get(9).
> > > > > 
> > > > > Pass down a wait flag to pru_attach().  During syscall socket(2)
> > > > > it is ok to wait, this logic was missing for internet pcb.  Pfkey
> > > > > and route sockets were already waiting.
> > > > > 
> > > > > sonewconn() cannot wait when called during TCP 3-way handshake.
> > > > > This logic has been preserved.  Unix domain stream socket connect(2)
> > > > > can wait until the other side has created the socket to accept.
> > > > 
> > > > rebased to -current.
> > > > 
> > > > Anyone?
> > > > 
> > > 
> > > At least these ones should have the "pcb == NULL" check as the inet and
> > > unix cases. Or the `wait' could be ignored for all cases except tcp.
> 
> Although it should not happen, I made is consistent.  Now all
> allocators respect the wait and return ENOBUFS in case of failure.
> 
> > But I don't understand what this diff fixes? Userland will check the
> > socket(2) return value in any cases, because it's absolutely normal to
> > fail here. And nothing stops userland to call socket(2) as times as
> > required.
> 
> Userland does not retry socket after memory error.  Kernel has to
> handle this kind of failure.  Otherwise you have to modify all
> userland to this:
> 
> #ifdef __OpenBSD__
> while (1) {
>   fd = socket(...);
>   if (fd != -1 || error != ENOBUFS)
>   break;
>   sleep(1);
> }
> #else
>   fd = socket(...);
> #edif
> 

Your example is not apposite. The socket(2) error handling depends on
logic we implement, but not on the underlying OS.

Since we are not the special case where we have no resource allocation
in runtime, because all required resources are pre-allocated by design,
the memory errors are absolutely normal and should be handled by
userland.

I'm not blocking this, may be something other has the different opinion.

> ok?
> 
> bluhm
> 
> Index: kern/uipc_socket.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.286
> diff -u -p -r1.286 uipc_socket.c
> --- kern/uipc_socket.c28 Aug 2022 18:43:12 -  1.286
> +++ kern/uipc_socket.c1 Sep 2022 18:47:36 -
> @@ -138,11 +138,12 @@ soinit(void)
>  }
>  
>  struct socket *
> -soalloc(int prflags)
> +soalloc(int wait)
>  {
>   struct socket *so;
>  
> - so = pool_get(_pool, prflags);
> + so = pool_get(_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
> + PR_ZERO);
>   if (so == NULL)
>   return (NULL);
>   rw_init_flags(>so_lock, "solock", RWL_DUPOK);
> @@ -174,7 +175,7 @@ socreate(int dom, struct socket **aso, i
>   return (EPROTONOSUPPORT);
>   if (prp->pr_type != type)
>   return (EPROTOTYPE);
> - so = soalloc(PR_WAITOK | PR_ZERO);
> + so = soalloc(M_WAIT);
>   klist_init(>so_rcv.sb_sel.si_note, _klistops, so);
>   klist_init(>so_snd.sb_sel.si_note, _klistops, so);
>   sigio_init(>so_sigio);
> @@ -193,7 +194,7 @@ socreate(int dom, struct socket **aso, i
>   so->so_rcv.sb_timeo_nsecs = INFSLP;
>  
>   solock(so);
> - error = pru_attach(so, proto);
> + error = pru_attach(so, proto, M_WAIT);
>   if (error) {
>   so->so_state |= SS_NOFDREF;
>   /* sofree() calls sounlock(). */
> Index: kern/uipc_socket2.c
> ===
> RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket2.c,v
> retrieving revision 1.127
> diff -u -p -r1.127 uipc_socket2.c
> --- kern/uipc_socket2.c   13 Aug 2022 21:01:46 -  1.127
> +++ kern/uipc_socket2.c   1 Sep 2022 18:47:36 -
> @@ -168,7 +168,7 @@ soisdisconnected(struct socket *so)
>   * Connstatus may be 0 or SS_ISCONNECTED.
>   */
>  struct socket *
> -sonewconn(struct socket *head, int connstatus)
> +sonewconn(struct socket *head, int connstatus, int wait)
>  {
>   struct socket *so;
>   int persocket = solock_persocket(head);
> @@ -185,7 +185,7 @@ sonewconn(struct socket *head, int conns
>   return (NULL);
>   if (head->so_qlen + head->so_q0len > head->so_qlimit * 3)
>   return (NULL);
> - so = soalloc(PR_NOWAIT | PR_ZERO);
> + so = soalloc(wait);
>   if (so == NULL)
>   return (NULL);
>   so->so_type = head->so_type;
> @@ -238,7 +238,7 @@ sonewconn(struct socket *head, int conns
>   sounlock(head);
>   }
>  
> - error = pru_attach(so, 0);
> + error = pru_attach(so, 0, wait);
>  
>

Re: protocol attach wait

2022-09-02 Thread Alexander Bluhm
On Thu, Sep 01, 2022 at 11:04:19PM +0300, Vitaliy Makkoveev wrote:
> On Thu, Sep 01, 2022 at 10:58:49PM +0300, Vitaliy Makkoveev wrote:
> > On Thu, Sep 01, 2022 at 09:00:50PM +0200, Alexander Bluhm wrote:
> > > On Mon, Aug 15, 2022 at 05:12:22PM +0200, Alexander Bluhm wrote:
> > > > System calls should not fail due to temporary memory shortage in
> > > > malloc(9) or pool_get(9).
> > > > 
> > > > Pass down a wait flag to pru_attach().  During syscall socket(2)
> > > > it is ok to wait, this logic was missing for internet pcb.  Pfkey
> > > > and route sockets were already waiting.
> > > > 
> > > > sonewconn() cannot wait when called during TCP 3-way handshake.
> > > > This logic has been preserved.  Unix domain stream socket connect(2)
> > > > can wait until the other side has created the socket to accept.
> > > 
> > > rebased to -current.
> > > 
> > > Anyone?
> > > 
> > 
> > At least these ones should have the "pcb == NULL" check as the inet and
> > unix cases. Or the `wait' could be ignored for all cases except tcp.

Although it should not happen, I made is consistent.  Now all
allocators respect the wait and return ENOBUFS in case of failure.

> But I don't understand what this diff fixes? Userland will check the
> socket(2) return value in any cases, because it's absolutely normal to
> fail here. And nothing stops userland to call socket(2) as times as
> required.

Userland does not retry socket after memory error.  Kernel has to
handle this kind of failure.  Otherwise you have to modify all
userland to this:

#ifdef __OpenBSD__
while (1) {
fd = socket(...);
if (fd != -1 || error != ENOBUFS)
break;
sleep(1);
}
#else
fd = socket(...);
#edif

ok?

bluhm

Index: kern/uipc_socket.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.286
diff -u -p -r1.286 uipc_socket.c
--- kern/uipc_socket.c  28 Aug 2022 18:43:12 -  1.286
+++ kern/uipc_socket.c  1 Sep 2022 18:47:36 -
@@ -138,11 +138,12 @@ soinit(void)
 }
 
 struct socket *
-soalloc(int prflags)
+soalloc(int wait)
 {
struct socket *so;
 
-   so = pool_get(_pool, prflags);
+   so = pool_get(_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
+   PR_ZERO);
if (so == NULL)
return (NULL);
rw_init_flags(>so_lock, "solock", RWL_DUPOK);
@@ -174,7 +175,7 @@ socreate(int dom, struct socket **aso, i
return (EPROTONOSUPPORT);
if (prp->pr_type != type)
return (EPROTOTYPE);
-   so = soalloc(PR_WAITOK | PR_ZERO);
+   so = soalloc(M_WAIT);
klist_init(>so_rcv.sb_sel.si_note, _klistops, so);
klist_init(>so_snd.sb_sel.si_note, _klistops, so);
sigio_init(>so_sigio);
@@ -193,7 +194,7 @@ socreate(int dom, struct socket **aso, i
so->so_rcv.sb_timeo_nsecs = INFSLP;
 
solock(so);
-   error = pru_attach(so, proto);
+   error = pru_attach(so, proto, M_WAIT);
if (error) {
so->so_state |= SS_NOFDREF;
/* sofree() calls sounlock(). */
Index: kern/uipc_socket2.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.127
diff -u -p -r1.127 uipc_socket2.c
--- kern/uipc_socket2.c 13 Aug 2022 21:01:46 -  1.127
+++ kern/uipc_socket2.c 1 Sep 2022 18:47:36 -
@@ -168,7 +168,7 @@ soisdisconnected(struct socket *so)
  * Connstatus may be 0 or SS_ISCONNECTED.
  */
 struct socket *
-sonewconn(struct socket *head, int connstatus)
+sonewconn(struct socket *head, int connstatus, int wait)
 {
struct socket *so;
int persocket = solock_persocket(head);
@@ -185,7 +185,7 @@ sonewconn(struct socket *head, int conns
return (NULL);
if (head->so_qlen + head->so_q0len > head->so_qlimit * 3)
return (NULL);
-   so = soalloc(PR_NOWAIT | PR_ZERO);
+   so = soalloc(wait);
if (so == NULL)
return (NULL);
so->so_type = head->so_type;
@@ -238,7 +238,7 @@ sonewconn(struct socket *head, int conns
sounlock(head);
}
 
-   error = pru_attach(so, 0);
+   error = pru_attach(so, 0, wait);
 
if (persocket) {
sounlock(so);
Index: kern/uipc_usrreq.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.181
diff -u -p -r1.181 uipc_usrreq.c
--- kern/uipc_usrreq.c  31 Aug 2022 21:23:02 -  1.181
+++ kern/uipc_usrreq.c  1 Sep 2022 18:47:36 -
@@ -302,7 +302,7 @@ const struct sysctl_bounded_args unpdgct
 };
 
 int
-uipc_attach(struct socket *so, int proto)
+uipc_attach(struct socket *so, int proto, int wait)
 {
struct unpcb *unp;
int error;
@@ -330,7 +330,8 @@ uipc_attach(struct socket *so, int proto
 

Re: protocol attach wait

2022-09-01 Thread Vitaliy Makkoveev
On Thu, Sep 01, 2022 at 10:58:49PM +0300, Vitaliy Makkoveev wrote:
> On Thu, Sep 01, 2022 at 09:00:50PM +0200, Alexander Bluhm wrote:
> > On Mon, Aug 15, 2022 at 05:12:22PM +0200, Alexander Bluhm wrote:
> > > System calls should not fail due to temporary memory shortage in
> > > malloc(9) or pool_get(9).
> > > 
> > > Pass down a wait flag to pru_attach().  During syscall socket(2)
> > > it is ok to wait, this logic was missing for internet pcb.  Pfkey
> > > and route sockets were already waiting.
> > > 
> > > sonewconn() cannot wait when called during TCP 3-way handshake.
> > > This logic has been preserved.  Unix domain stream socket connect(2)
> > > can wait until the other side has created the socket to accept.
> > 
> > rebased to -current.
> > 
> > Anyone?
> > 
> 
> At least these ones should have the "pcb == NULL" check as the inet and
> unix cases. Or the `wait' could be ignored for all cases except tcp.
> 
> > -   kp = pool_get(_pool, PR_WAITOK|PR_ZERO);
> > +   kp = pool_get(_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
> > +   PR_ZERO);
> > so->so_pcb = kp;
> 
> > -   rop = pool_get(_pool, PR_WAITOK|PR_ZERO);
> > +   rop = pool_get(_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
> > +   PR_ZERO);
> > so->so_pcb = rop;
> 

But I don't understand what this diff fixes? Userland will check the
socket(2) return value in any cases, because it's absolutely normal to
fail here. And nothing stops userland to call socket(2) as times as
required.



Re: protocol attach wait

2022-09-01 Thread Vitaliy Makkoveev
On Thu, Sep 01, 2022 at 09:00:50PM +0200, Alexander Bluhm wrote:
> On Mon, Aug 15, 2022 at 05:12:22PM +0200, Alexander Bluhm wrote:
> > System calls should not fail due to temporary memory shortage in
> > malloc(9) or pool_get(9).
> > 
> > Pass down a wait flag to pru_attach().  During syscall socket(2)
> > it is ok to wait, this logic was missing for internet pcb.  Pfkey
> > and route sockets were already waiting.
> > 
> > sonewconn() cannot wait when called during TCP 3-way handshake.
> > This logic has been preserved.  Unix domain stream socket connect(2)
> > can wait until the other side has created the socket to accept.
> 
> rebased to -current.
> 
> Anyone?
> 

At least these ones should have the "pcb == NULL" check as the inet and
unix cases. Or the `wait' could be ignored for all cases except tcp.

> - kp = pool_get(_pool, PR_WAITOK|PR_ZERO);
> + kp = pool_get(_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
> + PR_ZERO);
>   so->so_pcb = kp;

> - rop = pool_get(_pool, PR_WAITOK|PR_ZERO);
> + rop = pool_get(_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
> + PR_ZERO);
>   so->so_pcb = rop;



Re: protocol attach wait

2022-09-01 Thread Alexander Bluhm
On Mon, Aug 15, 2022 at 05:12:22PM +0200, Alexander Bluhm wrote:
> System calls should not fail due to temporary memory shortage in
> malloc(9) or pool_get(9).
> 
> Pass down a wait flag to pru_attach().  During syscall socket(2)
> it is ok to wait, this logic was missing for internet pcb.  Pfkey
> and route sockets were already waiting.
> 
> sonewconn() cannot wait when called during TCP 3-way handshake.
> This logic has been preserved.  Unix domain stream socket connect(2)
> can wait until the other side has created the socket to accept.

rebased to -current.

Anyone?

bluhm

Index: kern/uipc_socket.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.286
diff -u -p -r1.286 uipc_socket.c
--- kern/uipc_socket.c  28 Aug 2022 18:43:12 -  1.286
+++ kern/uipc_socket.c  1 Sep 2022 18:47:36 -
@@ -138,11 +138,12 @@ soinit(void)
 }
 
 struct socket *
-soalloc(int prflags)
+soalloc(int wait)
 {
struct socket *so;
 
-   so = pool_get(_pool, prflags);
+   so = pool_get(_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
+   PR_ZERO);
if (so == NULL)
return (NULL);
rw_init_flags(>so_lock, "solock", RWL_DUPOK);
@@ -174,7 +175,7 @@ socreate(int dom, struct socket **aso, i
return (EPROTONOSUPPORT);
if (prp->pr_type != type)
return (EPROTOTYPE);
-   so = soalloc(PR_WAITOK | PR_ZERO);
+   so = soalloc(M_WAIT);
klist_init(>so_rcv.sb_sel.si_note, _klistops, so);
klist_init(>so_snd.sb_sel.si_note, _klistops, so);
sigio_init(>so_sigio);
@@ -193,7 +194,7 @@ socreate(int dom, struct socket **aso, i
so->so_rcv.sb_timeo_nsecs = INFSLP;
 
solock(so);
-   error = pru_attach(so, proto);
+   error = pru_attach(so, proto, M_WAIT);
if (error) {
so->so_state |= SS_NOFDREF;
/* sofree() calls sounlock(). */
Index: kern/uipc_socket2.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.127
diff -u -p -r1.127 uipc_socket2.c
--- kern/uipc_socket2.c 13 Aug 2022 21:01:46 -  1.127
+++ kern/uipc_socket2.c 1 Sep 2022 18:47:36 -
@@ -168,7 +168,7 @@ soisdisconnected(struct socket *so)
  * Connstatus may be 0 or SS_ISCONNECTED.
  */
 struct socket *
-sonewconn(struct socket *head, int connstatus)
+sonewconn(struct socket *head, int connstatus, int wait)
 {
struct socket *so;
int persocket = solock_persocket(head);
@@ -185,7 +185,7 @@ sonewconn(struct socket *head, int conns
return (NULL);
if (head->so_qlen + head->so_q0len > head->so_qlimit * 3)
return (NULL);
-   so = soalloc(PR_NOWAIT | PR_ZERO);
+   so = soalloc(wait);
if (so == NULL)
return (NULL);
so->so_type = head->so_type;
@@ -238,7 +238,7 @@ sonewconn(struct socket *head, int conns
sounlock(head);
}
 
-   error = pru_attach(so, 0);
+   error = pru_attach(so, 0, wait);
 
if (persocket) {
sounlock(so);
Index: kern/uipc_usrreq.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.181
diff -u -p -r1.181 uipc_usrreq.c
--- kern/uipc_usrreq.c  31 Aug 2022 21:23:02 -  1.181
+++ kern/uipc_usrreq.c  1 Sep 2022 18:47:36 -
@@ -302,7 +302,7 @@ const struct sysctl_bounded_args unpdgct
 };
 
 int
-uipc_attach(struct socket *so, int proto)
+uipc_attach(struct socket *so, int proto, int wait)
 {
struct unpcb *unp;
int error;
@@ -330,7 +330,8 @@ uipc_attach(struct socket *so, int proto
if (error)
return (error);
}
-   unp = pool_get(_pool, PR_NOWAIT|PR_ZERO);
+   unp = pool_get(_pool, (wait == M_WAIT ? PR_WAITOK : PR_NOWAIT) |
+   PR_ZERO);
if (unp == NULL)
return (ENOBUFS);
refcnt_init(>unp_refcnt);
@@ -855,7 +856,7 @@ unp_connect(struct socket *so, struct mb
solock(so2);
 
if ((so2->so_options & SO_ACCEPTCONN) == 0 ||
-   (so3 = sonewconn(so2, 0)) == NULL) {
+   (so3 = sonewconn(so2, 0, M_WAIT)) == NULL) {
error = ECONNREFUSED;
}
 
Index: net/pfkeyv2.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pfkeyv2.c,v
retrieving revision 1.248
diff -u -p -r1.248 pfkeyv2.c
--- net/pfkeyv2.c   31 Aug 2022 21:23:02 -  1.248
+++ net/pfkeyv2.c   1 Sep 2022 18:47:36 -
@@ -169,7 +169,7 @@ static int npromisc = 0;
 
 void pfkey_init(void);
 
-int pfkeyv2_attach(struct socket *, int);
+int pfkeyv2_attach(struct socket *, int, int);
 int