svn commit: r208864 - head/sys/netinet

Randall Stewart rrs at FreeBSD.org
Sun Jun 6 02:33:47 UTC 2010


Author: rrs
Date: Sun Jun  6 02:33:46 2010
New Revision: 208864
URL: http://svn.freebsd.org/changeset/base/208864

Log:
  Hopefully this fixes a LOR by making
  so we only hold the iterator lock during
  updates to the iterators work.
  
  MFC after:	1 week

Modified:
  head/sys/netinet/sctp_pcb.c

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c	Sun Jun  6 02:32:20 2010	(r208863)
+++ head/sys/netinet/sctp_pcb.c	Sun Jun  6 02:33:46 2010	(r208864)
@@ -2296,7 +2296,7 @@ sctp_inpcb_alloc(struct socket *so, uint
 	if (inp->sctp_asocidhash == NULL) {
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
 		SCTP_INP_INFO_WUNLOCK();
-		return error;
+		return (ENOBUFS);
 	}
 #ifdef IPSEC
 	{
@@ -3107,29 +3107,13 @@ sctp_inpcb_free(struct sctp_inpcb *inp, 
 #ifdef SCTP_LOG_CLOSING
 	sctp_log_closing(inp, NULL, 0);
 #endif
-	SCTP_ITERATOR_LOCK();
-
-	so = inp->sctp_socket;
-	if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
-		/* been here before.. eeks.. get out of here */
-		SCTP_PRINTF("This conflict in free SHOULD not be happening! from %d, imm %d\n", from, immediate);
-		SCTP_ITERATOR_UNLOCK();
-#ifdef SCTP_LOG_CLOSING
-		sctp_log_closing(inp, NULL, 1);
-#endif
-		return;
-	}
-	SCTP_ASOC_CREATE_LOCK(inp);
-	SCTP_INP_INFO_WLOCK();
-
-	SCTP_INP_WLOCK(inp);
-	/* First time through we have the socket lock, after that no more. */
 	if (from == SCTP_CALLED_AFTER_CMPSET_OFCLOSE) {
 		/*
 		 * Once we are in we can remove the flag from = 1 is only
 		 * passed from the actual closing routines that are called
 		 * via the sockets layer.
 		 */
+		SCTP_ITERATOR_LOCK();
 		inp->sctp_flags &= ~SCTP_PCB_FLAGS_CLOSE_IP;
 		/* socket is gone, so no more wakeups allowed */
 		inp->sctp_flags |= SCTP_PCB_FLAGS_DONT_WAKE;
@@ -3138,7 +3122,22 @@ sctp_inpcb_free(struct sctp_inpcb *inp, 
 
 		/* mark any iterators on the list or being processed */
 		sctp_iterator_inp_being_freed(inp);
+		SCTP_ITERATOR_UNLOCK();
+	}
+	so = inp->sctp_socket;
+	if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
+		/* been here before.. eeks.. get out of here */
+		SCTP_PRINTF("This conflict in free SHOULD not be happening! from %d, imm %d\n", from, immediate);
+#ifdef SCTP_LOG_CLOSING
+		sctp_log_closing(inp, NULL, 1);
+#endif
+		return;
 	}
+	SCTP_ASOC_CREATE_LOCK(inp);
+	SCTP_INP_INFO_WLOCK();
+
+	SCTP_INP_WLOCK(inp);
+	/* First time through we have the socket lock, after that no more. */
 	sctp_timer_stop(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL,
 	    SCTP_FROM_SCTP_PCB + SCTP_LOC_1);
 
@@ -3338,7 +3337,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, 
 			SCTP_INP_WUNLOCK(inp);
 			SCTP_ASOC_CREATE_UNLOCK(inp);
 			SCTP_INP_INFO_WUNLOCK();
-			SCTP_ITERATOR_UNLOCK();
 #ifdef SCTP_LOG_CLOSING
 			sctp_log_closing(inp, NULL, 2);
 #endif
@@ -3416,7 +3414,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, 
 		SCTP_INP_WUNLOCK(inp);
 		SCTP_ASOC_CREATE_UNLOCK(inp);
 		SCTP_INP_INFO_WUNLOCK();
-		SCTP_ITERATOR_UNLOCK();
 #ifdef SCTP_LOG_CLOSING
 		sctp_log_closing(inp, NULL, 3);
 #endif
@@ -3428,7 +3425,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, 
 		SCTP_INP_WUNLOCK(inp);
 		SCTP_ASOC_CREATE_UNLOCK(inp);
 		SCTP_INP_INFO_WUNLOCK();
-		SCTP_ITERATOR_UNLOCK();
 #ifdef SCTP_LOG_CLOSING
 		sctp_log_closing(inp, NULL, 4);
 #endif
@@ -3550,7 +3546,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, 
 	SCTP_INP_READ_DESTROY(inp);
 	SCTP_ASOC_CREATE_LOCK_DESTROY(inp);
 	SCTP_INP_INFO_WUNLOCK();
-	SCTP_ITERATOR_UNLOCK();
 	SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
 	SCTP_DECR_EP_COUNT();
 }


More information about the svn-src-all mailing list