Module Name: src Committed By: riastradh Date: Wed Mar 23 23:18:18 UTC 2022
Modified Files: src/sys/kern: kern_entropy.c Log Message: entropy(9): Bind to CPU temporarily to avoid race with lwp migration. More fallout from the IPL_VM->IPL_SOFTSERIAL change. In entropy_enter, there is a window when the lwp can be migrated to another CPU: ec = entropy_cpu_get(); ... pending = ec->ec_pending + ...; ... entropy_cpu_put(); /* lwp migration possible here */ if (pending) entropy_account_cpu(ec); If this happens, we may trip over any of several problems in entropy_account_cpu because it assumes ec is the current CPU's state in order to decide whether we have anything to contribute from the local pool to the global pool. No need to do this in entropy_softintr because softints are bound to the CPU anyway. To generate a diff of this commit: cvs rdiff -u -r1.51 -r1.52 src/sys/kern/kern_entropy.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/kern/kern_entropy.c diff -u src/sys/kern/kern_entropy.c:1.51 src/sys/kern/kern_entropy.c:1.52 --- src/sys/kern/kern_entropy.c:1.51 Mon Mar 21 00:25:04 2022 +++ src/sys/kern/kern_entropy.c Wed Mar 23 23:18:17 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_entropy.c,v 1.51 2022/03/21 00:25:04 riastradh Exp $ */ +/* $NetBSD: kern_entropy.c,v 1.52 2022/03/23 23:18:17 riastradh Exp $ */ /*- * Copyright (c) 2019 The NetBSD Foundation, Inc. @@ -75,7 +75,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_entropy.c,v 1.51 2022/03/21 00:25:04 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_entropy.c,v 1.52 2022/03/23 23:18:17 riastradh Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -735,6 +735,7 @@ entropy_account_cpu(struct entropy_cpu * unsigned diff; KASSERT(E->stage >= ENTROPY_WARM); + KASSERT(curlwp->l_pflag & LP_BOUND); /* * If there's no entropy needed, and entropy has been @@ -869,6 +870,7 @@ entropy_enter(const void *buf, size_t le struct entropy_cpu_lock lock; struct entropy_cpu *ec; unsigned pending; + int bound; KASSERTMSG(!cpu_intr_p(), "use entropy_enter_intr from interrupt context"); @@ -882,6 +884,14 @@ entropy_enter(const void *buf, size_t le } /* + * Bind ourselves to the current CPU so we don't switch CPUs + * between entering data into the current CPU's pool (and + * updating the pending count) and transferring it to the + * global pool in entropy_account_cpu. + */ + bound = curlwp_bind(); + + /* * With the per-CPU state locked, enter into the per-CPU pool * and count up what we can add. */ @@ -895,6 +905,8 @@ entropy_enter(const void *buf, size_t le /* Consolidate globally if appropriate based on what we added. */ if (pending) entropy_account_cpu(ec); + + curlwp_bindx(bound); } /*