As I described on the phone, we have a stuck ifconfig unplumb:

d20b0880 d3ad94e0 ceb04af0   1  59 cf0613d0
  PC: _resume_from_idle+0xb1    CMD: ifconfig bge0 inet6 unplumb
  stack pointer for thread d20b0880: cf4b9a18
    swtch+0x20e()
    cv_wait+0x5d(cf0613d0, cf061398)
    ip_modclose+0x179(cf061254)
    ip_close+0x2a(ceae0480, 3, c9e46ad0)
    qdetach+0x9b(ceae0480, 1, 3, c9e46ad0, 0)
    strclose+0x391(cf049040, 3, c9e46ad0)
    device_close+0x8c(cf049100, 3, c9e46ad0)
    spec_close+0x122(cf049100, 3, 1, 0, 0, c9e46ad0, 0)
    fop_close+0x51(cf049100, 3, 1, 0, 0, c9e46ad0, 0)
    closef+0x88(cbec43f8)
    munlink+0x3eb(db171b00, cbec3f08, 2, d5a2d018, cf4b9f70, ca196818)
    strioctl+0x3bf6(d5b77d00, 5317, 7, 100003, 1, d5a2d018, cf4b9f70)
    spec_ioctl+0x4b(d5b77d00, 5317, 7, 100003, d5a2d018, cf4b9f70, 0)
    fop_ioctl+0x49(d5b77d00, 5317, 7, 100003, d5a2d018, cf4b9f70, 0)
    ioctl+0x155()
    sys_sysenter+0x1a4()

So ifconfig is doing a I_PUNLINK and we're tearing down the ill in
ip_modclose(), but the call to ill_is_freeable() came back to cause us
to cv_wait():

        ill_delete(ill);
        mutex_enter(&ill->ill_lock);
        while (!ill_is_freeable(ill))
                cv_wait(&ill->ill_cv, &ill->ill_lock);

Why did ill_is_freeable(ill) fail?  It's because of the failed check for
ILL_FREE_OK(ill) in ill_is_freeable(ill).  Why did ILL_FREE_OK(ill)
fail?

/*
 * ILL_FREE_OK() means that there are no incoming pointer references
 * to the ill.
 */
#define ILL_FREE_OK(ill)                                        \
        ((ill)->ill_ire_cnt == 0 && (ill)->ill_ilm_cnt == 0 &&  \
        (ill)->ill_nce_cnt == 0)

And:

> cf061254::print ill_t ill_ilm_cnt
ill_ilm_cnt = 0x1
> cf061254::print ill_t ill_ilm | ::print ilm_t
{
    ilm_v6addr = {
        _S6_un = {
            _S6_u32 = [ 0, 0, 0, 0 ]
            _S6_u8 = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
            __S6_align = 0
        }
    }
...

Well well well.  This is the ilm for the allmulti group that ipnet
joined.  At this point, I'm wondering how ilm's get cleaned up on
unplumb...  Clearly ours isn't getting deleted automatically.  How is
this supposed to work for ilm's added by conn_t's doing multicast joins?

-Seb



Reply via email to