Module Name:    src
Committed By:   riastradh
Date:           Sun Mar 20 13:17:32 UTC 2022

Modified Files:
        src/sys/kern: kern_entropy.c

Log Message:
entropy(9): Lock the per-CPU state in entropy_account_cpu.

This was previously called with the per-CPU state locked, which
worked fine as long as the global entropy lock was a spin lock so
acquiring it would never sleep.  Now it's an adaptive lock, so it's
not safe to take with the per-CPU state lock -- but we still need to
prevent reentrant access to the per-CPU entropy pool by interrupt
handlers while we're extracting from it.  So now the logic for
entering a sample is:

- lock per-CPU state
- entpool_enter
- unlock per-CPU state
- if anything pending on this CPU and it's time to consolidate:
  - lock global entropy state
  - lock per-CPU state
  - transfer
  - unlock per-CPU state
  - unlock global entropy state


To generate a diff of this commit:
cvs rdiff -u -r1.43 -r1.44 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.43 src/sys/kern/kern_entropy.c:1.44
--- src/sys/kern/kern_entropy.c:1.43	Sun Mar 20 13:17:09 2022
+++ src/sys/kern/kern_entropy.c	Sun Mar 20 13:17:32 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_entropy.c,v 1.43 2022/03/20 13:17:09 riastradh Exp $	*/
+/*	$NetBSD: kern_entropy.c,v 1.44 2022/03/20 13:17:32 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.43 2022/03/20 13:17:09 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_entropy.c,v 1.44 2022/03/20 13:17:32 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -728,8 +728,9 @@ entropy_ready(void)
 static void
 entropy_account_cpu(struct entropy_cpu *ec)
 {
+	struct entropy_cpu_lock lock;
+	struct entropy_cpu *ec0;
 	unsigned diff;
-	int s;
 
 	KASSERT(E->stage >= ENTROPY_WARM);
 
@@ -742,9 +743,13 @@ entropy_account_cpu(struct entropy_cpu *
 	    __predict_true((time_uptime - E->timestamp) <= 60))
 		return;
 
-	/* Consider consolidation, under the lock.  */
+	/*
+	 * Consider consolidation, under the global lock and with the
+	 * per-CPU state locked.
+	 */
 	mutex_enter(&E->lock);
-	s = splsoftserial();
+	ec0 = entropy_cpu_get(&lock);
+	KASSERT(ec0 == ec);
 	if (E->needed != 0 && E->needed <= ec->ec_pending) {
 		/*
 		 * If we have not yet attained full entropy but we can
@@ -799,7 +804,7 @@ entropy_account_cpu(struct entropy_cpu *
 			entropy_partial_evcnt.ev_count++;
 		}
 	}
-	splx(s);
+	entropy_cpu_put(&lock, ec);
 	mutex_exit(&E->lock);
 }
 

Reply via email to