Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107189327
D26709.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D26709.diff
View Options
Index: sys/kern/uipc_domain.c
===================================================================
--- sys/kern/uipc_domain.c
+++ sys/kern/uipc_domain.c
@@ -81,6 +81,11 @@
static struct mtx dom_mtx; /* domain list lock */
MTX_SYSINIT(domain, &dom_mtx, "domain list", MTX_DEF);
+static CK_LIST_HEAD(, protosw) fasttimo_protos =
+ CK_LIST_HEAD_INITIALIZER(fasttimo_protos);
+static CK_LIST_HEAD(, protosw) slowtimo_protos =
+ CK_LIST_HEAD_INITIALIZER(slowtimo_protos);
+
/*
* Dummy protocol specific user requests function pointer array.
* All functions return EOPNOTSUPP.
@@ -192,8 +197,18 @@
max_datalen = MHLEN - max_hdr;
if (max_datalen < 1)
panic("%s: max_datalen < 1", __func__);
- if (IS_DEFAULT_VNET(curvnet))
+ if (IS_DEFAULT_VNET(curvnet)) {
atomic_set_rel_int(&dp->dom_flags, DOMF_INITED);
+ for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
+ if (pr->pr_fasttimo != NULL)
+ CK_LIST_INSERT_HEAD(&fasttimo_protos, pr,
+ pr_fasttimos);
+ if (pr->pr_slowtimo != NULL)
+ CK_LIST_INSERT_HEAD(&slowtimo_protos, pr,
+ pr_slowtimos);
+ }
+
+ }
}
#ifdef VIMAGE
@@ -374,8 +389,11 @@
return (EEXIST); /* XXX: Check only protocol? */
}
/* While here, remember the first free spacer. */
- if ((fpr == NULL) && (pr->pr_protocol == PROTO_SPACER))
+ if ((fpr == NULL) && (pr->pr_protocol == PROTO_SPACER)) {
+ /* See pf_proto_unregister_cb(). */
+ atomic_thread_fence_acq();
fpr = pr;
+ }
}
/* If no free spacer is found we can't add the new protocol. */
@@ -387,6 +405,12 @@
/* Copy the new struct protosw over the spacer. */
bcopy(npr, fpr, sizeof(*fpr));
+ if (fpr->pr_fasttimo != NULL)
+ CK_LIST_INSERT_HEAD(&fasttimo_protos, pr, pr_fasttimos);
+
+ if (fpr->pr_slowtimo != NULL)
+ CK_LIST_INSERT_HEAD(&slowtimo_protos, pr, pr_slowtimos);
+
/* Job is done, no more protection required. */
mtx_unlock(&dom_mtx);
@@ -402,6 +426,41 @@
return (0);
}
+static void
+pf_proto_unregister_cb(struct epoch_context *ctx)
+{
+ struct protosw *pr;
+
+ pr = __containerof(ctx, struct protosw, pr_epoch_ctx);
+
+ KASSERT((pr->pr_flags & PR_REMOVING) != 0,
+ ("Removing unmarked spacer from %s", pr->pr_domain->dom_name));
+
+ /* De-orbit the protocol and make the slot available again. */
+ pr->pr_type = 0;
+ pr->pr_flags = 0;
+ pr->pr_input = NULL;
+ pr->pr_output = NULL;
+ pr->pr_ctlinput = NULL;
+ pr->pr_ctloutput = NULL;
+ pr->pr_init = NULL;
+ pr->pr_fasttimo = NULL;
+ pr->pr_slowtimo = NULL;
+ pr->pr_drain = NULL;
+ pr->pr_usrreqs = &nousrreqs;
+
+ /*
+ * This could race with pf_proto_register() calls since we'll take the
+ * dom_mtx there but not here. We just need to make sure that it
+ * doesn't proceed on a protocol marked PROTO_SPACER before all of the
+ * previous writes have completed. The main problem here is that
+ * protocol registration will copy the dynamically registered protocol
+ * into this spacer, so we really need to avoid clobbering that.
+ */
+ atomic_thread_fence_rel();
+ pr->pr_protocol = PROTO_SPACER;
+}
+
/*
* The caller must make sure the protocol and its functions correctly shut down
* all sockets and release all locks and memory references.
@@ -447,24 +506,22 @@
return (EPROTONOSUPPORT);
}
- /* De-orbit the protocol and make the slot available again. */
- dpr->pr_type = 0;
- dpr->pr_domain = dp;
- dpr->pr_protocol = PROTO_SPACER;
- dpr->pr_flags = 0;
- dpr->pr_input = NULL;
- dpr->pr_output = NULL;
- dpr->pr_ctlinput = NULL;
- dpr->pr_ctloutput = NULL;
- dpr->pr_init = NULL;
- dpr->pr_fasttimo = NULL;
- dpr->pr_slowtimo = NULL;
- dpr->pr_drain = NULL;
- dpr->pr_usrreqs = &nousrreqs;
-
- /* Job is done, not more protection required. */
+ KASSERT(dpr->pr_domain == dp, ("Unexpected domain mismatch"));
+ KASSERT((dpr->pr_flags & PR_REMOVING) == 0,
+ ("Scheduled removal of marked spacer"));
+
+ dpr->pr_flags |= PR_REMOVING;
+ if (dpr->pr_fasttimo != NULL)
+ CK_LIST_REMOVE(dpr, pr_fasttimos);
+
+ if (dpr->pr_slowtimo != NULL)
+ CK_LIST_REMOVE(dpr, pr_slowtimos);
+
+ /* Job is done, no more protection required. */
mtx_unlock(&dom_mtx);
+ NET_EPOCH_CALL(pf_proto_unregister_cb, &dpr->pr_epoch_ctx);
+
return (0);
}
@@ -484,17 +541,11 @@
pfslowtimo(void *arg)
{
struct epoch_tracker et;
- struct domain *dp;
struct protosw *pr;
NET_EPOCH_ENTER(et);
- for (dp = domains; dp; dp = dp->dom_next) {
- if ((atomic_load_int(&dp->dom_flags) & DOMF_INITED) == 0)
- continue;
- atomic_thread_fence_acq();
- for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
- if (pr->pr_slowtimo)
- (*pr->pr_slowtimo)();
+ CK_LIST_FOREACH(pr, &slowtimo_protos, pr_slowtimos) {
+ (*pr->pr_slowtimo)();
}
NET_EPOCH_EXIT(et);
callout_reset(&pfslow_callout, hz/2, pfslowtimo, NULL);
@@ -504,17 +555,11 @@
pffasttimo(void *arg)
{
struct epoch_tracker et;
- struct domain *dp;
struct protosw *pr;
NET_EPOCH_ENTER(et);
- for (dp = domains; dp; dp = dp->dom_next) {
- if ((atomic_load_int(&dp->dom_flags) & DOMF_INITED) == 0)
- continue;
- atomic_thread_fence_acq();
- for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
- if (pr->pr_fasttimo)
- (*pr->pr_fasttimo)();
+ CK_LIST_FOREACH(pr, &fasttimo_protos, pr_fasttimos) {
+ (*pr->pr_fasttimo)();
}
NET_EPOCH_EXIT(et);
callout_reset(&pffast_callout, hz/5, pffasttimo, NULL);
Index: sys/sys/protosw.h
===================================================================
--- sys/sys/protosw.h
+++ sys/sys/protosw.h
@@ -35,6 +35,9 @@
#ifndef _SYS_PROTOSW_H_
#define _SYS_PROTOSW_H_
+#include <sys/ck.h>
+#include <sys/epoch.h>
+
/* Forward declare these structures referenced from prototypes below. */
struct kaiocb;
struct mbuf;
@@ -93,6 +96,10 @@
pr_drain_t *pr_drain; /* flush any excess space possible */
struct pr_usrreqs *pr_usrreqs; /* user-protocol hook */
+
+ struct epoch_context pr_epoch_ctx;
+ CK_LIST_ENTRY(protosw) pr_fasttimos;
+ CK_LIST_ENTRY(protosw) pr_slowtimos;
};
/*#endif*/
@@ -121,6 +128,7 @@
#define PR_RIGHTS 0x10 /* passes capabilities */
#define PR_IMPLOPCL 0x20 /* implied open/close */
#define PR_LASTHDR 0x40 /* enforce ipsec policy; last header */
+#define PR_REMOVING 0x80 /* spacer queued for removal */
/*
* In earlier BSD network stacks, a single pr_usrreq() function pointer was
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 12, 10:00 AM (21 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15767728
Default Alt Text
D26709.diff (6 KB)
Attached To
Mode
D26709: domain: explicitly track domains with fasttimo/slowtimo callbacks
Attached
Detach File
Event Timeline
Log In to Comment