On Tuesday 16 February 2016 13:37:28 you wrote: > > Oh, I see. We shouldn't drop any events of link state changes. > > i don't see any point in keeping a huge series of link changes > if they can be collapsed into an equivalent sequence. with VMs > and other user-controlled systems it's possible to flood such a > link state checking engine.
The queue can be kept quite short because we don't care about any prior entries each time state changes to LINK_STATE_DOWN. Also, we don't care about any prior entries (other than LINK_STATE_DOWN) when setting LINK_STATE_UNKNOWN. Finally we set LINK_STATE_UP. So the queue should only ever hold a maximum of 3 items. Could even work it like so void if_link_state_change(struct ifnet *ifp, int link_state) { int s, i; s = splnet(); if (ifp->if_link_queue_len == 0 && ifp->link_state == link_state) goto out; for (i = 0; i < ifp->if_link_queue_len; i++) { if (link_state <= ifp->if_link_queue[i]) { ifp->if_link_queue[i] = link_state; ifp->if_link_queue_len = i; /* Because we are trimming the queue, * there is no need to call softint_schedule again. */ goto out; } } /* Add bounds check here for sanity */ ifp->if_link_queue[ifp->if_link_queue_len++] = link_state; softint_schedule(ifp->if_link_state_softint); out: splx(s); } static void if_link_state_change_si(void *arg) { int s, link_state, i; s = splnet(); if (ifp->if_link_queue_len == 0) goto out; link_state = ifp->if_link_queue[0]; ifp->if_link_queue_len--; for (i = 0; i < ifp->link_queue_len; i++) ifp->if_link_queue[i] = ifp->if_link_queue[i + 1]; /* process state change as normal */ out: splx(s); } Thoughts? Roy