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

Reply via email to