Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Dec 2018 20:29:17 +0000 (UTC)
From:      Conrad Meyer <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r342354 - in head/sys/dev: mpr mps
Message-ID:  <201812212029.wBLKTHx4008393@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cem
Date: Fri Dec 21 20:29:16 2018
New Revision: 342354
URL: https://svnweb.freebsd.org/changeset/base/342354

Log:
  mps(4), mpr(4): Fix lifetime of command buffer for mp?sas_get_sata_identify
  
  In the event that the ID command timed out, mps(4)/mpr(4) did not free the
  command until it could be cancelled.  However, it freed the associated
  buffer (cm_data).  Fix the lifetime issue by freeing the associated buffer
  only after Abort Task or controller reset.
  
  Reviewed by:	scottl
  Sponsored by:	Dell EMC Isilon
  Differential Revision:	https://reviews.freebsd.org/D18612

Modified:
  head/sys/dev/mpr/mpr_sas.c
  head/sys/dev/mpr/mpr_sas_lsi.c
  head/sys/dev/mps/mps_sas.c
  head/sys/dev/mps/mps_sas_lsi.c

Modified: head/sys/dev/mpr/mpr_sas.c
==============================================================================
--- head/sys/dev/mpr/mpr_sas.c	Fri Dec 21 20:12:43 2018	(r342353)
+++ head/sys/dev/mpr/mpr_sas.c	Fri Dec 21 20:29:16 2018	(r342354)
@@ -1169,6 +1169,12 @@ mprsas_complete_all_commands(struct mpr_softc *sc)
 		cm->cm_reply = NULL;
 		completed = 0;
 
+		if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) {
+			MPASS(cm->cm_data);
+			free(cm->cm_data, M_MPR);
+			cm->cm_data = NULL;
+		}
+
 		if (cm->cm_flags & MPR_CM_FLAGS_POLLED)
 			cm->cm_flags |= MPR_CM_FLAGS_COMPLETE;
 

Modified: head/sys/dev/mpr/mpr_sas_lsi.c
==============================================================================
--- head/sys/dev/mpr/mpr_sas_lsi.c	Fri Dec 21 20:12:43 2018	(r342353)
+++ head/sys/dev/mpr/mpr_sas_lsi.c	Fri Dec 21 20:29:16 2018	(r342354)
@@ -1026,6 +1026,7 @@ out:
 	for (i = 1; i < sc->num_reqs; i++) {
 		cm = &sc->commands[i];
 		if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) {
+			free(cm->cm_data, M_MPR);
 			mpr_free_command(sc, cm);
 		}
 	}
@@ -1208,15 +1209,14 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 han
 out:
 	/*
 	 * If the SATA_ID_TIMEOUT flag has been set for this command, don't free
-	 * it.  The command will be freed after sending a target reset TM. If
-	 * the command did timeout, use EWOULDBLOCK.
+	 * it.  The command and buffer will be freed after sending an Abort
+	 * Task TM.  If the command did timeout, use EWOULDBLOCK.
 	 */
-	if ((cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) == 0)
+	if ((cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) == 0) {
 		mpr_free_command(sc, cm);
-	else if (error == 0)
+		free(buffer, M_MPR);
+	} else if (error == 0)
 		error = EWOULDBLOCK;
-	cm->cm_data = NULL;
-	free(buffer, M_MPR);
 	return (error);
 }
 

Modified: head/sys/dev/mps/mps_sas.c
==============================================================================
--- head/sys/dev/mps/mps_sas.c	Fri Dec 21 20:12:43 2018	(r342353)
+++ head/sys/dev/mps/mps_sas.c	Fri Dec 21 20:29:16 2018	(r342354)
@@ -1108,6 +1108,12 @@ mpssas_complete_all_commands(struct mps_softc *sc)
 		cm->cm_reply = NULL;
 		completed = 0;
 
+		if (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) {
+			MPASS(cm->cm_data);
+			free(cm->cm_data, M_MPT2);
+			cm->cm_data = NULL;
+		}
+
 		if (cm->cm_flags & MPS_CM_FLAGS_POLLED)
 			cm->cm_flags |= MPS_CM_FLAGS_COMPLETE;
 

Modified: head/sys/dev/mps/mps_sas_lsi.c
==============================================================================
--- head/sys/dev/mps/mps_sas_lsi.c	Fri Dec 21 20:12:43 2018	(r342353)
+++ head/sys/dev/mps/mps_sas_lsi.c	Fri Dec 21 20:29:16 2018	(r342354)
@@ -818,6 +818,7 @@ out:
 	for (i = 1; i < sc->num_reqs; i++) {
 		cm = &sc->commands[i];
 		if (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) {
+			free(cm->cm_data, M_MPT2);
 			mps_free_command(sc, cm);
 		}
 	}
@@ -1000,15 +1001,15 @@ mpssas_get_sata_identify(struct mps_softc *sc, u16 han
 out:
 	/*
 	 * If the SATA_ID_TIMEOUT flag has been set for this command, don't free
-	 * it.  The command will be freed after sending a target reset TM. If
-	 * the command did timeout, use EWOULDBLOCK.
+	 * it.  The command and buffer will be freed after sending an Abort
+	 * Task TM.  If the command did timeout, use EWOULDBLOCK.
 	 */
 	if ((cm != NULL)
-	 && (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) == 0)
+	    && (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) == 0) {
 		mps_free_command(sc, cm);
-	else if (error == 0)
+		free(buffer, M_MPT2);
+	} else if (error == 0)
 		error = EWOULDBLOCK;
-	free(buffer, M_MPT2);
 	return (error);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812212029.wBLKTHx4008393>