Subject: Re: kern/22002: panic: double tcp_freeq() may happen - TAILQ_*
To: None <gnats-bugs@gnats.netbsd.org>
From: Havard Eidnes <he@nordu.net>
List: netbsd-bugs
Date: 06/27/2003 18:16:24
Hm,

> >Fix:
> 	Explicitly mark queues as empty when they have been released
> 	in tcp_freeq()?

On second thought, it should not be necessary to do this if the queues
are properly initialized.  However, contrary to what tcp_freeq()
expect, it appears that the segq and timeq queues are of different
length:

(gdb) up 10
#10 0xc01bf150 in tcp_freeq (tp=3D0xc089f164)
    at /sys/arch/i386/compile/BLACKHOLE/../../../../netinet/tcp_subr.c:=
1181
1181                    TAILQ_REMOVE(&tp->segq, qe, ipqe_q);
(gdb) p tp
$1 =3D (struct tcpcb *) 0xc089f164
(gdb) p tp->segq
$2 =3D {tqh_first =3D 0xc0867b04, tqh_last =3D 0xc089f168}
(gdb) p $.tqh_first
$3 =3D (struct ipqent *) 0xc0867b04
(gdb) p *$
$4 =3D {ipqe_q =3D {tqe_next =3D 0xc089f164, tqe_prev =3D 0xc089f164}, =
_ipqe_u1 =3D {
    _ip =3D 0x0, _tcp =3D 0x0}, ipqe_m =3D 0xc08b7480, ipre_mlast =3D 0=
xb, =

  ipqe_mff =3D 0 '\000', ipqe_timeq =3D {tqe_next =3D 0x3ef40783, =

    tqe_prev =3D 0xdbba0}, ipqe_seq =3D 3230038900, ipqe_len =3D 323003=
8620, =

  ipqe_flags =3D 0}
(gdb) p *$.ipqe_q.tqe_next
$5 =3D {ipqe_q =3D {tqe_next =3D 0x0, tqe_prev =3D 0xc0867b04}, _ipqe_u=
1 =3D {
    _ip =3D 0xc089f168, _tcp =3D 0xc089f168}, ipqe_m =3D 0x1, ipre_mlas=
t =3D 0x1, =

  ipqe_mff =3D 244 '=F4', ipqe_timeq =3D {tqe_next =3D 0x0, tqe_prev =3D=
 0xc089f164}, =

  ipqe_seq =3D 0, ipqe_len =3D 0, ipqe_flags =3D 0}
(gdb) p tp->timeq
$6 =3D {tqh_first =3D 0x0, tqh_last =3D 0xc089f294}
(gdb)

It is also somewhat weird that a tcpcb's address is found as a list
element on the segq, isn't it, since the storage for ipqent and tcpcb
is supposed to come from different pools?

Hints for further debugging gracefully accepted.

Regards,

- Havard