svn commit: r354986 - in head/sys: kern sys

Alexander Motin mav at FreeBSD.org
Thu Nov 21 21:59:36 UTC 2019


Author: mav
Date: Thu Nov 21 21:59:35 2019
New Revision: 354986
URL: https://svnweb.freebsd.org/changeset/base/354986

Log:
  Add variant of root_mount_hold() without allocation.
  
  It allows to use this KPI in non-sleepable contexts.
  
  MFC after:	2 weeks
  Sponsored by:	iXsystems, Inc.

Modified:
  head/sys/kern/vfs_mountroot.c
  head/sys/sys/systm.h

Modified: head/sys/kern/vfs_mountroot.c
==============================================================================
--- head/sys/kern/vfs_mountroot.c	Thu Nov 21 20:36:46 2019	(r354985)
+++ head/sys/kern/vfs_mountroot.c	Thu Nov 21 21:59:35 2019	(r354986)
@@ -111,14 +111,9 @@ char *rootdevnames[2] = {NULL, NULL};
 struct mtx root_holds_mtx;
 MTX_SYSINIT(root_holds, &root_holds_mtx, "root_holds", MTX_DEF);
 
-struct root_hold_token {
-	const char			*who;
-	LIST_ENTRY(root_hold_token)	list;
-};
+static TAILQ_HEAD(, root_hold_token)	root_holds =
+    TAILQ_HEAD_INITIALIZER(root_holds);
 
-static LIST_HEAD(, root_hold_token)	root_holds =
-    LIST_HEAD_INITIALIZER(root_holds);
-
 enum action {
 	A_CONTINUE,
 	A_PANIC,
@@ -126,6 +121,12 @@ enum action {
 	A_RETRY
 };
 
+enum rh_flags {
+	RH_FREE,
+	RH_ALLOC,
+	RH_ARG,
+};
+
 static enum action root_mount_onfail = A_CONTINUE;
 
 static int root_mount_mddev;
@@ -155,8 +156,8 @@ sysctl_vfs_root_mount_hold(SYSCTL_HANDLER_ARGS)
 	sbuf_new(&sb, NULL, 256, SBUF_AUTOEXTEND | SBUF_INCLUDENUL);
 
 	mtx_lock(&root_holds_mtx);
-	LIST_FOREACH(h, &root_holds, list) {
-		if (h != LIST_FIRST(&root_holds))
+	TAILQ_FOREACH(h, &root_holds, list) {
+		if (h != TAILQ_FIRST(&root_holds))
 			sbuf_putc(&sb, ' ');
 		sbuf_printf(&sb, "%s", h->who);
 	}
@@ -175,27 +176,54 @@ root_mount_hold(const char *identifier)
 	struct root_hold_token *h;
 
 	h = malloc(sizeof *h, M_DEVBUF, M_ZERO | M_WAITOK);
+	h->flags = RH_ALLOC;
 	h->who = identifier;
 	mtx_lock(&root_holds_mtx);
 	TSHOLD("root mount");
-	LIST_INSERT_HEAD(&root_holds, h, list);
+	TAILQ_INSERT_TAIL(&root_holds, h, list);
 	mtx_unlock(&root_holds_mtx);
 	return (h);
 }
 
 void
+root_mount_hold_token(const char *identifier, struct root_hold_token *h)
+{
+#ifdef INVARIANTS
+	struct root_hold_token *t;
+#endif
+
+	h->flags = RH_ARG;
+	h->who = identifier;
+	mtx_lock(&root_holds_mtx);
+#ifdef INVARIANTS
+	TAILQ_FOREACH(t, &root_holds, list) {
+		if (t == h) {
+			panic("Duplicate mount hold by '%s' on %p",
+			    identifier, h);
+		}
+	}
+#endif
+	TSHOLD("root mount");
+	TAILQ_INSERT_TAIL(&root_holds, h, list);
+	mtx_unlock(&root_holds_mtx);
+}
+
+void
 root_mount_rel(struct root_hold_token *h)
 {
 
-	if (h == NULL)
+	if (h == NULL || h->flags == RH_FREE)
 		return;
 
 	mtx_lock(&root_holds_mtx);
-	LIST_REMOVE(h, list);
+	TAILQ_REMOVE(&root_holds, h, list);
 	TSRELEASE("root mount");
 	wakeup(&root_holds);
 	mtx_unlock(&root_holds_mtx);
-	free(h, M_DEVBUF);
+	if (h->flags == RH_ALLOC) {
+		free(h, M_DEVBUF);
+	} else
+		h->flags = RH_FREE;
 }
 
 int
@@ -964,13 +992,13 @@ vfs_mountroot_wait(void)
 	while (1) {
 		g_waitidle();
 		mtx_lock(&root_holds_mtx);
-		if (LIST_EMPTY(&root_holds)) {
+		if (TAILQ_EMPTY(&root_holds)) {
 			mtx_unlock(&root_holds_mtx);
 			break;
 		}
 		if (ppsratecheck(&lastfail, &curfail, 1)) {
 			printf("Root mount waiting for:");
-			LIST_FOREACH(h, &root_holds, list)
+			TAILQ_FOREACH(h, &root_holds, list)
 				printf(" %s", h->who);
 			printf("\n");
 		}

Modified: head/sys/sys/systm.h
==============================================================================
--- head/sys/sys/systm.h	Thu Nov 21 20:36:46 2019	(r354985)
+++ head/sys/sys/systm.h	Thu Nov 21 21:59:35 2019	(r354986)
@@ -536,9 +536,14 @@ int poll_no_poll(int events);
 void	DELAY(int usec);
 
 /* Root mount holdback API */
-struct root_hold_token;
+struct root_hold_token {
+	int				flags;
+	const char			*who;
+	TAILQ_ENTRY(root_hold_token)	list;
+};
 
 struct root_hold_token *root_mount_hold(const char *identifier);
+void root_mount_hold_token(const char *identifier, struct root_hold_token *h);
 void root_mount_rel(struct root_hold_token *h);
 int root_mounted(void);
 


More information about the svn-src-all mailing list