git: b2954f0a8f7d - main - netgraph: add ng_uncallout_drain().

Gleb Smirnoff glebius at FreeBSD.org
Fri Sep 10 18:27:59 UTC 2021


The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=b2954f0a8f7db160053555d4ad86ce3abf036077

commit b2954f0a8f7db160053555d4ad86ce3abf036077
Author:     Gleb Smirnoff <glebius at FreeBSD.org>
AuthorDate: 2021-08-06 20:16:32 +0000
Commit:     Gleb Smirnoff <glebius at FreeBSD.org>
CommitDate: 2021-09-10 18:27:04 +0000

    netgraph: add ng_uncallout_drain().
    
    Move shared code into ng_uncallout_internal(). While here add a comment
    mentioning a problem with scheduled+executing callout.
    
    Reviewed by:            mjg, markj
    Differential Revision:  https://reviews.freebsd.org/D31476
---
 sys/netgraph/netgraph.h |  1 +
 sys/netgraph/ng_base.c  | 50 +++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/sys/netgraph/netgraph.h b/sys/netgraph/netgraph.h
index 9cc298b38236..d0be5a88b088 100644
--- a/sys/netgraph/netgraph.h
+++ b/sys/netgraph/netgraph.h
@@ -1162,6 +1162,7 @@ int 	ng_send_fn1(node_p node, hook_p hook, ng_item_fn *fn, void *arg1,
 int 	ng_send_fn2(node_p node, hook_p hook, item_p pitem, ng_item_fn2 *fn,
 	void *arg1, int arg2, int flags);
 int	ng_uncallout(struct callout *c, node_p node);
+int	ng_uncallout_drain(struct callout *c, node_p node);
 int	ng_callout(struct callout *c, node_p node, hook_p hook, int ticks,
 	    ng_item_fn *fn, void * arg1, int arg2);
 #define	ng_callout_init(c)	callout_init(c, 1)
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c
index e0832e794089..655761c2f897 100644
--- a/sys/netgraph/ng_base.c
+++ b/sys/netgraph/ng_base.c
@@ -3816,20 +3816,18 @@ ng_callout(struct callout *c, node_p node, hook_p hook, int ticks,
 	return (0);
 }
 
-/* A special modified version of callout_stop() */
-int
-ng_uncallout(struct callout *c, node_p node)
+/*
+ * Free references and item if callout_stop/callout_drain returned 1,
+ * meaning that callout was successfully stopped and now references
+ * belong to us.
+ */
+static void
+ng_uncallout_internal(struct callout *c, node_p node)
 {
 	item_p item;
-	int rval;
-
-	KASSERT(c != NULL, ("ng_uncallout: NULL callout"));
-	KASSERT(node != NULL, ("ng_uncallout: NULL node"));
 
-	rval = callout_stop(c);
 	item = c->c_arg;
-	/* Do an extra check */
-	if ((rval > 0) && (c->c_func == &ng_callout_trampoline) &&
+	if ((c->c_func == &ng_callout_trampoline) &&
 	    (item != NULL) && (NGI_NODE(item) == node)) {
 		/*
 		 * We successfully removed it from the queue before it ran
@@ -3839,6 +3837,38 @@ ng_uncallout(struct callout *c, node_p node)
 		NG_FREE_ITEM(item);
 	}
 	c->c_arg = NULL;
+}
+
+
+/* A special modified version of callout_stop() */
+int
+ng_uncallout(struct callout *c, node_p node)
+{
+	int rval;
+
+	rval = callout_stop(c);
+	if (rval > 0)
+		/*
+		 * XXXGL: in case if callout is already running and next
+		 * invocation is scheduled at the same time, callout_stop()
+		 * returns 0. See d153eeee97d. In this case netgraph(4) would
+		 * leak resources. However, no nodes are known to induce such
+		 * behavior.
+		 */
+		ng_uncallout_internal(c, node);
+
+	return (rval);
+}
+
+/* A special modified version of callout_drain() */
+int
+ng_uncallout_drain(struct callout *c, node_p node)
+{
+	int rval;
+
+	rval = callout_drain(c);
+	if (rval > 0)
+		ng_uncallout_internal(c, node);
 
 	return (rval);
 }


More information about the dev-commits-src-main mailing list