Module Name:    src
Committed By:   mlelstv
Date:           Sun Jun  5 13:54:28 UTC 2016

Modified Files:
        src/sys/dev/iscsi: iscsi_send.c iscsi_utils.c

Log Message:
Handle freeing of PDU when referencing CCB is freed.


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/iscsi/iscsi_send.c
cvs rdiff -u -r1.18 -r1.19 src/sys/dev/iscsi/iscsi_utils.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/iscsi/iscsi_send.c
diff -u src/sys/dev/iscsi/iscsi_send.c:1.29 src/sys/dev/iscsi/iscsi_send.c:1.30
--- src/sys/dev/iscsi/iscsi_send.c:1.29	Sun Jun  5 09:12:48 2016
+++ src/sys/dev/iscsi/iscsi_send.c	Sun Jun  5 13:54:28 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: iscsi_send.c,v 1.29 2016/06/05 09:12:48 mlelstv Exp $	*/
+/*	$NetBSD: iscsi_send.c,v 1.30 2016/06/05 13:54:28 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -291,6 +291,7 @@ iscsi_send_thread(void *par)
 	ccb_t *ccb, *nccb;
 	pdu_t *pdu;
 	struct file *fp;
+	pdu_disp_t pdisp;
 
 	sess = conn->session;
 	/* so cleanup thread knows there's someone left */
@@ -302,6 +303,7 @@ iscsi_send_thread(void *par)
 			while (!conn->terminating &&
 				(pdu = TAILQ_FIRST(&conn->pdus_to_send)) != NULL) {
 				TAILQ_REMOVE(&conn->pdus_to_send, pdu, send_chain);
+				pdu->flags &= ~PDUF_INQUEUE;
 				mutex_exit(&conn->lock);
 
 				/* update ExpStatSN here to avoid discontinuities */
@@ -315,12 +317,14 @@ iscsi_send_thread(void *par)
 				my_soo_write(conn, &pdu->uio);
 
 				mutex_enter(&conn->lock);
-				pdu->flags &= ~PDUF_INQUEUE;
-				if (pdu->disp > PDUDISP_FREE)
+				pdisp = pdu->disp;
+				if (pdisp <= PDUDISP_FREE)
+					pdu->disp = PDUDISP_UNUSED;
+				else
 					pdu->flags &= ~PDUF_BUSY;
 				mutex_exit(&conn->lock);
 
-				if (pdu->disp <= PDUDISP_FREE)
+				if (pdisp <= PDUDISP_FREE)
 					free_pdu(pdu);
 
 				mutex_enter(&conn->lock);

Index: src/sys/dev/iscsi/iscsi_utils.c
diff -u src/sys/dev/iscsi/iscsi_utils.c:1.18 src/sys/dev/iscsi/iscsi_utils.c:1.19
--- src/sys/dev/iscsi/iscsi_utils.c:1.18	Sun Jun  5 09:21:14 2016
+++ src/sys/dev/iscsi/iscsi_utils.c	Sun Jun  5 13:54:28 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: iscsi_utils.c,v 1.18 2016/06/05 09:21:14 mlelstv Exp $	*/
+/*	$NetBSD: iscsi_utils.c,v 1.19 2016/06/05 13:54:28 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 2004,2005,2006,2008 The NetBSD Foundation, Inc.
@@ -268,16 +268,17 @@ void
 free_ccb(ccb_t *ccb)
 {
 	session_t *sess = ccb->session;
+	connection_t *conn = ccb->connection;
 	pdu_t *pdu;
 
-	DEBC(ccb->connection, 15, (
+	DEBC(conn, 15, (
 		"free_ccb: ccb = %p, usecount = %d\n",
-		ccb, ccb->connection->usecount-1));
+		ccb, conn->usecount-1));
 
 	KASSERT((ccb->flags & CCBF_THROTTLING) == 0);
 	KASSERT((ccb->flags & CCBF_WAITQUEUE) == 0);
 
-	atomic_dec_uint(&ccb->connection->usecount);
+	atomic_dec_uint(&conn->usecount);
 	ccb->connection = NULL;
 
 	if (ccb->disp > CCBDISP_NOWAIT) {
@@ -296,6 +297,12 @@ free_ccb(ccb_t *ccb)
 	/* free PDU waiting for ACK */
 	if ((pdu = ccb->pdu_waiting) != NULL) {
 		ccb->pdu_waiting = NULL;
+		mutex_enter(&conn->lock);
+		if ((pdu->flags & PDUF_INQUEUE) != 0) {
+			TAILQ_REMOVE(&conn->pdus_to_send, pdu, send_chain);
+			pdu->flags &= ~PDUF_INQUEUE;
+		}
+		mutex_exit(&conn->lock);
 		free_pdu(pdu);
 	}
 

Reply via email to