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>