Thu Aug 27 18:49:36 2020 UTC ()
npf: Don't stop early after sleeping and before processing instances.

We already check winfo->exit below, after processing instances and
before sleeping again.

Candidate fix for:

panic: kernel diagnostic assertion "LIST_EMPTY(&winfo->instances)" failed: file "/home/riastradh/netbsd/current/src/sys/rump/net/lib/libnpf/../../../..//net/npf/npf_worker.c", line 300 NPF instances must be discharged before the npfk_sysfini() call


(riastradh)
diff -r1.9 -r1.10 src/sys/net/npf/npf_worker.c

cvs diff -r1.9 -r1.10 src/sys/net/npf/npf_worker.c (expand / switch to unified diff)

--- src/sys/net/npf/npf_worker.c 2020/05/30 20:54:54 1.9
+++ src/sys/net/npf/npf_worker.c 2020/08/27 18:49:36 1.10
@@ -19,27 +19,27 @@ @@ -19,27 +19,27 @@
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE. 27 * POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30#ifdef _KERNEL 30#ifdef _KERNEL
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: npf_worker.c,v 1.9 2020/05/30 20:54:54 rmind Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: npf_worker.c,v 1.10 2020/08/27 18:49:36 riastradh Exp $");
33 33
34#include <sys/param.h> 34#include <sys/param.h>
35#include <sys/types.h> 35#include <sys/types.h>
36 36
37#include <sys/mutex.h> 37#include <sys/mutex.h>
38#include <sys/kmem.h> 38#include <sys/kmem.h>
39#include <sys/kernel.h> 39#include <sys/kernel.h>
40#include <sys/kthread.h> 40#include <sys/kthread.h>
41#include <sys/cprng.h> 41#include <sys/cprng.h>
42#endif 42#endif
43 43
44#include "npf_impl.h" 44#include "npf_impl.h"
45 45
@@ -261,27 +261,27 @@ process_npf_instance(npf_workerinfo_t *w @@ -261,27 +261,27 @@ process_npf_instance(npf_workerinfo_t *w
261 * npf_worker: the main worker loop, processing enlisted NPF instances. 261 * npf_worker: the main worker loop, processing enlisted NPF instances.
262 * 262 *
263 * XXX: Currently, npf_workerinfo_t::lock would serialize all workers, 263 * XXX: Currently, npf_workerinfo_t::lock would serialize all workers,
264 * so there is no point to have more than one worker; but there might 264 * so there is no point to have more than one worker; but there might
265 * not be much point anyway. 265 * not be much point anyway.
266 */ 266 */
267static void 267static void
268npf_worker(void *arg) 268npf_worker(void *arg)
269{ 269{
270 npf_workerinfo_t *winfo = arg; 270 npf_workerinfo_t *winfo = arg;
271 npf_t *npf; 271 npf_t *npf;
272 272
273 mutex_enter(&winfo->lock); 273 mutex_enter(&winfo->lock);
274 while (!winfo->exit) { 274 for (;;) {
275 unsigned wait_time = NPF_GC_MAXWAIT; 275 unsigned wait_time = NPF_GC_MAXWAIT;
276 276
277 /* 277 /*
278 * Iterate all instances. We do not use LIST_FOREACH here, 278 * Iterate all instances. We do not use LIST_FOREACH here,
279 * since the instance can be removed. 279 * since the instance can be removed.
280 */ 280 */
281 npf = LIST_FIRST(&winfo->instances); 281 npf = LIST_FIRST(&winfo->instances);
282 while (npf) { 282 while (npf) {
283 npf_t *next = LIST_NEXT(npf, worker_entry); 283 npf_t *next = LIST_NEXT(npf, worker_entry);
284 unsigned i_wait_time = process_npf_instance(winfo, npf); 284 unsigned i_wait_time = process_npf_instance(winfo, npf);
285 wait_time = MIN(wait_time, i_wait_time); 285 wait_time = MIN(wait_time, i_wait_time);
286 npf = next; 286 npf = next;
287 } 287 }