commit dc6e0760fd72e3cafecc358e66690f6e0b97deee Author: Ryota Ozaki Date: Mon Jan 4 14:40:52 2016 +0900 Apply a patch from mlelstv@ Conflicts: sys/net/if.c sys/net/if.h diff --git a/sys/net/if.c b/sys/net/if.c index bd158bd..f047c00 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -200,6 +200,7 @@ static void if_attachdomain1(struct ifnet *); static int ifconf(u_long, void *); static int if_clone_create(const char *); static int if_clone_destroy(const char *); +static void if_link_state_change_si(void *); struct if_percpuq { struct ifnet *ipq_ifp; @@ -602,6 +603,7 @@ if_initialize(ifnet_t *ifp) ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */ ifp->if_link_state = LINK_STATE_UNKNOWN; + ifp->if_old_link_state = LINK_STATE_UNKNOWN; ifp->if_capenable = 0; ifp->if_csum_flags_tx = 0; @@ -627,6 +629,10 @@ if_initialize(ifnet_t *ifp) IF_AFDATA_LOCK_INIT(ifp); + ifp->if_link_si = softint_establish(SOFTINT_NET, if_link_state_change_si, ifp); + if (ifp->if_link_si == NULL) + panic("%s: softint_establish() failed", __func__); + if_getindex(ifp); } @@ -1045,6 +1051,9 @@ again: IF_AFDATA_LOCK_DESTROY(ifp); + softint_disestablish(ifp->if_link_si); + ifp->if_link_si = NULL; + /* * remove packets that came from ifp, from software interrupt queues. */ @@ -1562,8 +1571,6 @@ void if_link_state_change(struct ifnet *ifp, int link_state) { int s; - int old_link_state; - struct domain *dp; s = splnet(); if (ifp->if_link_state == link_state) { @@ -1571,8 +1578,26 @@ if_link_state_change(struct ifnet *ifp, int link_state) return; } - old_link_state = ifp->if_link_state; ifp->if_link_state = link_state; + softint_schedule(ifp->if_link_si); + + splx(s); +} + + +static void +if_link_state_change_si(void *arg) +{ + struct ifnet *ifp = arg; + int s; + int link_state, old_link_state; + struct domain *dp; + + s = splnet(); + link_state = ifp->if_link_state; + old_link_state = ifp->if_old_link_state; + ifp->if_old_link_state = ifp->if_link_state; + #ifdef DEBUG log(LOG_DEBUG, "%s: link state %s (was %s)\n", ifp->if_xname, link_state == LINK_STATE_UP ? "UP" : diff --git a/sys/net/if.h b/sys/net/if.h index e85b29c..b0789de2 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -358,6 +358,8 @@ typedef struct ifnet { struct krwlock *if_afdata_lock; #endif struct if_percpuq *if_percpuq; /* We should remove it in the future */ + void *if_link_si; /* softint to handle link state changes */ + int if_old_link_state; /* previous link state */ #endif } ifnet_t;