Module Name: src Committed By: riastradh Date: Thu Aug 20 21:34:13 UTC 2020
Modified Files: src/sys/net: if_wg.c Log Message: Fix race in wg_worker kthread destruction. Also allow the thread to migrate between CPUs -- just not while we're in the middle of processing and holding onto things with psrefs. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/sys/net/if_wg.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_wg.c diff -u src/sys/net/if_wg.c:1.9 src/sys/net/if_wg.c:1.10 --- src/sys/net/if_wg.c:1.9 Thu Aug 20 21:34:03 2020 +++ src/sys/net/if_wg.c Thu Aug 20 21:34:13 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wg.c,v 1.9 2020/08/20 21:34:03 riastradh Exp $ */ +/* $NetBSD: if_wg.c,v 1.10 2020/08/20 21:34:13 riastradh Exp $ */ /* * Copyright (C) Ryota Ozaki <ozaki.ry...@gmail.com> @@ -43,7 +43,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.9 2020/08/20 21:34:03 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.10 2020/08/20 21:34:13 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -2736,32 +2736,32 @@ wg_worker(void *arg) { struct wg_softc *wg = arg; struct wg_worker *wgw = wg->wg_worker; - int bound = curlwp_bind(); + bool todie = false; KASSERT(wg != NULL); KASSERT(wgw != NULL); - while (!wgw->wgw_todie) { + while (!todie) { int reasons; + int bound; mutex_enter(&wgw->wgw_lock); /* New tasks may come during task handling */ - if (wgw->wgw_wakeup_reasons == 0) + while ((reasons = wgw->wgw_wakeup_reasons) == 0 && + !(todie = wgw->wgw_todie)) cv_wait(&wgw->wgw_cv, &wgw->wgw_lock); - reasons = wgw->wgw_wakeup_reasons; wgw->wgw_wakeup_reasons = 0; mutex_exit(&wgw->wgw_lock); + bound = curlwp_bind(); if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV4)) wg_receive_packets(wg, AF_INET); if (ISSET(reasons, WG_WAKEUP_REASON_RECEIVE_PACKETS_IPV6)) wg_receive_packets(wg, AF_INET6); - if (!ISSET(reasons, WG_WAKEUP_REASON_PEER)) - continue; - - wg_process_peer_tasks(wg); + if (ISSET(reasons, WG_WAKEUP_REASON_PEER)) + wg_process_peer_tasks(wg); + curlwp_bindx(bound); } - curlwp_bindx(bound); kthread_exit(0); }