As mpi@ noticed malloc() with M_WAITOK can cause context switch too. I wish to drop concurency while RBT pppx_ifs is accessed. So, remove malloc() from pppx_if_find(). Looks like original code should do search in the same way, but it didn't.
Index: sys/net/if_pppx.c =================================================================== RCS file: /cvs/src/sys/net/if_pppx.c,v retrieving revision 1.82 diff -u -p -r1.82 if_pppx.c --- sys/net/if_pppx.c 7 Apr 2020 13:27:52 -0000 1.82 +++ sys/net/if_pppx.c 8 Apr 2020 13:18:07 -0000 @@ -643,20 +643,20 @@ pppx_if_next_unit(void) struct pppx_if * pppx_if_find(struct pppx_dev *pxd, int session_id, int protocol) { - struct pppx_if *s, *p; - s = malloc(sizeof(*s), M_DEVBUF, M_WAITOK | M_ZERO); - - s->pxi_key.pxik_session_id = session_id; - s->pxi_key.pxik_protocol = protocol; + struct pppx_if_key key; + struct pppx_if *pxi; + memset(&key, 0, sizeof(key)); + key.pxik_session_id = session_id; + key.pxik_protocol = protocol; + rw_enter_read(&pppx_ifs_lk); - p = RBT_FIND(pppx_ifs, &pppx_ifs, s); - if (p && p->pxi_ready == 0) - p = NULL; + pxi = RBT_FIND(pppx_ifs, &pppx_ifs, (struct pppx_if *)&key); + if (pxi && pxi->pxi_ready == 0) + pxi = NULL; rw_exit_read(&pppx_ifs_lk); - free(s, M_DEVBUF, sizeof(*s)); - return (p); + return pxi; } int