Page MenuHomeFreeBSD

D28136.1785272836.diff
No OneTemporary

Size
2 KB
Referenced Files
None
Subscribers
None

D28136.1785272836.diff

diff --git a/sys/net/if.c b/sys/net/if.c
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -645,6 +645,8 @@
ifq_init(&ifp->if_snd, ifp);
refcount_init(&ifp->if_refcount, 1); /* Index reference. */
+ refcount_init(&ifp->if_slowref, 1);
+
for (int i = 0; i < IFCOUNTERS; i++)
ifp->if_counters[i] = counter_u64_alloc(M_WAITOK);
ifp->if_get_counter = if_get_counter_default;
@@ -753,6 +755,32 @@
NET_EPOCH_CALL(if_destroy, &ifp->if_epoch_ctx);
}
+/*
+ * Keep track of slow path configuration events.
+ * Returns true on success and false on failure.
+ */
+bool
+if_slow_ref(struct ifnet *ifp)
+{
+ return (refcount_acquire_if_not_zero(&ifp->if_slowref));
+}
+
+void
+if_slow_drain(struct ifnet *ifp)
+{
+ if (refcount_release(&ifp->if_slowref))
+ return;
+
+ while (refcount_load(&ifp->if_slowref) != 0)
+ pause("W", hz);
+}
+
+void
+if_slow_unref(struct ifnet *ifp)
+{
+ (void) refcount_release(&ifp->if_slowref);
+}
+
void
ifq_init(struct ifaltq *ifq, struct ifnet *ifp)
{
@@ -2459,8 +2487,8 @@
/*
* Hardware specific interface ioctls.
*/
-int
-ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
+static inline int
+ifhwioctl_sub(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
{
struct ifreq *ifr;
int error = 0, do_ifup = 0;
@@ -2887,6 +2915,19 @@
return (error);
}
+int
+ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
+{
+ int error;
+
+ if (if_slow_ref(ifp) == false)
+ return (ENXIO);
+ error = ifhwioctl_sub(cmd, ifp, data, td);
+ if_slow_unref(ifp);
+ return (error);
+}
+
+
#ifdef COMPAT_FREEBSD32
struct ifconf32 {
int32_t ifc_len;
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -313,6 +313,7 @@
void *if_linkmib; /* link-type-specific MIB data */
size_t if_linkmiblen; /* length of above data */
u_int if_refcount; /* reference count */
+ u_int if_slowref; /* reference count (slow path) */
/* These fields are shared with struct if_data. */
uint8_t if_type; /* ethernet, tokenring, etc */
@@ -660,6 +661,9 @@
int if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
void if_ref(struct ifnet *);
void if_rele(struct ifnet *);
+bool if_slow_ref(struct ifnet *) __result_use_check;
+void if_slow_drain(struct ifnet *);
+void if_slow_unref(struct ifnet *);
int if_setlladdr(struct ifnet *, const u_char *, int);
int if_tunnel_check_nesting(struct ifnet *, struct mbuf *, uint32_t, int);
void if_up(struct ifnet *);

File Metadata

Mime Type
text/plain
Expires
Tue, Jul 28, 9:07 PM (19 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29296218
Default Alt Text
D28136.1785272836.diff (2 KB)

Event Timeline