On Wed, Nov 19, 2014 at 12:18 AM, Masao Uebayashi <uebay...@gmail.com> wrote:
> On Mon, Nov 17, 2014 at 7:03 PM, Ryota Ozaki <ozak...@netbsd.org> wrote:
>> - http://www.netbsd.org/~ozaki-r/psz-ifnet.diff
>
> IFNET_RENTER();
> IFNET_FOREACH() {
>         if->if_watchdog();
> }
> IFNET_REXIT();
>
> This is not safe; if_watchdog() may resend packets, too slow operation
> to do in critical section.

Sure.

>
> I think you need to allocate a global array if_watchdog_t
> **if_slowtimo_watchdog, like ifindex2ifnet, which grows and can store
> pointers of if_watchdog of all interfaces, and do:
>
> IFNET_RENTER();
> i = 0;
> IFNET_FOREACH() {
>         if_slowtimo_watchdog[i++] = if->if_watchdog;
> }
> IFNET_REXIT();
> for (j = 0; j < i; j++) {
>         (*(if_slowtimo_watchdog[j]))();
> }

It seems incomplete. We have to store both a function
pointer and an ifp for each ifnet. Additionally we have to
prevent the ifps from being freed during executing if_watchdog
functions. So a complete version would be:

IFNET_FOREACH() {
        if_watchdog_funcs[i++] = ifp->if_watchdog;
        if_watchdog_ifps[i++] = ifp;
        refcount_hold(ifp->if_refcount);
}
IFNET_REXIT();

for (j = 0; j < i; j++) {
        (*(if_watchdog_funcs[j]))(if_watchdog_ifps[j]);
        ifput(ifps[j]);
}

Weird :-/

  ozaki-r

Reply via email to