Re: panic: _mtx_lock_sleep: recursed on non-recursive mutex if_addr_mtx

From: Ed Maste <emaste_at_freebsd.org>
Date: Mon, 28 Apr 2008 20:36:08 -0400
On Tue, Mar 25, 2008 at 04:00:33PM -0400, Ed Maste wrote:

> GENERIC CURRENT as of this morning.
> 
> panic: _mtx_lock_sleep: recursed on non-recursive mutex if_addr_mtx _at_ /d2/emaste/HEAD/src/sys/netinet6/ip6_output.c:719
> ...
> panic() at panic+0x176
> _mtx_lock_sleep() at _mtx_lock_sleep+0x181
> _mtx_lock_flags() at _mtx_lock_flags+0xe1
> ip6_output() at ip6_output+0xe98
> mld6_sendpkt() at mld6_sendpkt+0x204
> mld6_input() at mld6_input+0x55c
> icmp6_input() at icmp6_input+0xf0b
> ip6_input() at ip6_input+0xa6d
> ...

What happens here is that mld6_input() does IF_ADDR_LOCK() to be able
to walk the address list, and then ends up needing to send a packet:

mld6.c
   268  void
   269  mld6_input(struct mbuf *m, int off)
   ...
   330          switch(mldh->mld_type) {
   331          case MLD_LISTENER_QUERY:
   ...
   371                  IF_ADDR_LOCK(ifp);
   372                  TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
   ...
   387                                          mld6_sendpkt(in6m, MLD_LISTENER_REPORT,
   388                                                  NULL);
   ...
   399                  }
   400                  IF_ADDR_UNLOCK(ifp);

And then mld6_sendpkt() calls ip6_output() which needs to take the
if_addr_mtx at:

ip6_output.c
   719                  IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m);

- Ed
Received on Mon Apr 28 2008 - 22:37:10 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:30 UTC