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-all
mailing list