How best to debug locking/scheduler problems

Robert Watson rwatson at FreeBSD.org
Wed Jun 17 22:32:44 UTC 2009


On Wed, 17 Jun 2009, John Baldwin wrote:

> These are the key frames.  It looks like uipc_peeraddr() tries to lock two 
> unp locks w/o any protection from the global unp linkage lock.  I've changed 
> it to use the same locking as uipc_accept() where it first grabs a read lock 
> on the linkage lock and then just locks the other end of the connection to 
> copy out its sockaddr.

This change looks reasonable to me, thanks for tracking this down!

Robert N M Watson
Computer Laboratory
University of Cambridge

>
> --- //depot/user/jhb/socket/kern/uipc_usrreq.c
> +++ /home/jhb/work/p4/socket/kern/uipc_usrreq.c
> @@ -671,7 +671,7 @@
> 	KASSERT(unp != NULL, ("uipc_peeraddr: unp == NULL"));
>
> 	*nam = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
> -	UNP_PCB_LOCK(unp);
> +	UNP_LINK_RLOCK();
> 	/*
> 	 * XXX: It seems that this test always fails even when connection is
> 	 * established.  So, this else clause is added as workaround to
> @@ -681,7 +681,7 @@
> 	if (unp2 != NULL) {
> 		UNP_PCB_LOCK(unp2);
> 		if (unp2->unp_addr != NULL)
> -			sa = (struct sockaddr *) unp->unp_conn->unp_addr;
> +			sa = (struct sockaddr *) unp2->unp_addr;
> 		else
> 			sa = &sun_noname;
> 		bcopy(sa, *nam, sa->sa_len);
> @@ -690,7 +690,7 @@
> 		sa = &sun_noname;
> 		bcopy(sa, *nam, sa->sa_len);
> 	}
> -	UNP_PCB_UNLOCK(unp);
> +	UNP_LINK_RUNLOCK();
> 	return (0);
> }
>
> @@ -850,7 +850,7 @@
> 		 * return the slightly counter-intuitive but otherwise
> 		 * correct error that the socket is not connected.
> 		 *
> -		 * Locking here must be done carefully: the inkage lock
> +		 * Locking here must be done carefully: the linkage lock
> 		 * prevents interconnections between unpcbs from changing, so
> 		 * we can traverse from unp to unp2 without acquiring unp's
> 		 * lock.  Socket buffer locks follow unpcb locks, so we can
>
> -- 
> John Baldwin
>


More information about the freebsd-hackers mailing list