Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Dec 2018 06:10:11 +0000 (UTC)
From:      Scott Long <scottl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r341755 - in head/sys/dev: mpr mps
Message-ID:  <201812090610.wB96ABUf045821@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: scottl
Date: Sun Dec  9 06:10:11 2018
New Revision: 341755
URL: https://svnweb.freebsd.org/changeset/base/341755

Log:
  Copy and clear the reply descriptor atomically.  This prevents concurrency
  in the interrupt handlers (usually due to timeout/error recovery) from
  seeing and processing the same descriptor twice.

Modified:
  head/sys/dev/mpr/mpr.c
  head/sys/dev/mps/mps.c

Modified: head/sys/dev/mpr/mpr.c
==============================================================================
--- head/sys/dev/mpr/mpr.c	Sun Dec  9 06:06:06 2018	(r341754)
+++ head/sys/dev/mpr/mpr.c	Sun Dec  9 06:10:11 2018	(r341755)
@@ -2493,12 +2493,13 @@ void
 mpr_intr_locked(void *data)
 {
 	MPI2_REPLY_DESCRIPTORS_UNION *desc;
+	MPI2_DIAG_RELEASE_REPLY *rel_rep;
+	mpr_fw_diagnostic_buffer_t *pBuffer;
 	struct mpr_softc *sc;
+	uint64_t tdesc;
 	struct mpr_command *cm = NULL;
 	uint8_t flags;
 	u_int pq;
-	MPI2_DIAG_RELEASE_REPLY *rel_rep;
-	mpr_fw_diagnostic_buffer_t *pBuffer;
 
 	sc = (struct mpr_softc *)data;
 
@@ -2510,6 +2511,17 @@ mpr_intr_locked(void *data)
 	for ( ;; ) {
 		cm = NULL;
 		desc = &sc->post_queue[sc->replypostindex];
+
+		/*
+		 * Copy and clear out the descriptor so that any reentry will
+		 * immediately know that this descriptor has already been
+		 * looked at.  There is unfortunate casting magic because the
+		 * MPI API doesn't have a cardinal 64bit type.
+		 */
+		tdesc = 0xffffffffffffffff;
+		tdesc = atomic_swap_64((uint64_t *)desc, tdesc);
+		desc = (MPI2_REPLY_DESCRIPTORS_UNION *)&tdesc;
+
 		flags = desc->Default.ReplyFlags &
 		    MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
 		if ((flags == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) ||
@@ -2604,7 +2616,8 @@ mpr_intr_locked(void *data)
 				cm = &sc->commands[
 				    le16toh(desc->AddressReply.SMID)];
 				KASSERT(cm->cm_state == MPR_CM_STATE_INQUEUE,
-				    ("command not inqueue\n"));
+				    ("command SMID %d not inqueue\n",
+				    desc->AddressReply.SMID));
 				cm->cm_state = MPR_CM_STATE_BUSY;
 				cm->cm_reply = reply;
 				cm->cm_reply_data =
@@ -2630,9 +2643,6 @@ mpr_intr_locked(void *data)
 				mpr_display_reply_info(sc,cm->cm_reply);
 			mpr_complete_command(sc, cm);
 		}
-
-		desc->Words.Low = 0xffffffff;
-		desc->Words.High = 0xffffffff;
 	}
 
 	if (pq != sc->replypostindex) {

Modified: head/sys/dev/mps/mps.c
==============================================================================
--- head/sys/dev/mps/mps.c	Sun Dec  9 06:06:06 2018	(r341754)
+++ head/sys/dev/mps/mps.c	Sun Dec  9 06:10:11 2018	(r341755)
@@ -2361,12 +2361,13 @@ void
 mps_intr_locked(void *data)
 {
 	MPI2_REPLY_DESCRIPTORS_UNION *desc;
+	MPI2_DIAG_RELEASE_REPLY *rel_rep;
+	mps_fw_diagnostic_buffer_t *pBuffer;
 	struct mps_softc *sc;
 	struct mps_command *cm = NULL;
+	uint64_t tdesc;
 	uint8_t flags;
 	u_int pq;
-	MPI2_DIAG_RELEASE_REPLY *rel_rep;
-	mps_fw_diagnostic_buffer_t *pBuffer;
 
 	sc = (struct mps_softc *)data;
 
@@ -2378,6 +2379,17 @@ mps_intr_locked(void *data)
 	for ( ;; ) {
 		cm = NULL;
 		desc = &sc->post_queue[sc->replypostindex];
+
+		/*
+		 * Copy and clear out the descriptor so that any reentry will
+		 * immediately know that this descriptor has already been
+		 * looked at.  There is unfortunate casting magic because the
+		 * MPI API doesn't have a cardinal 64bit type.
+		 */
+		tdesc = 0xffffffffffffffff;
+		tdesc = atomic_swap_64((uint64_t *)desc, tdesc);
+		desc = (MPI2_REPLY_DESCRIPTORS_UNION *)&tdesc;
+
 		flags = desc->Default.ReplyFlags &
 		    MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
 		if ((flags == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
@@ -2496,9 +2508,6 @@ mps_intr_locked(void *data)
 				mps_display_reply_info(sc,cm->cm_reply);
 			mps_complete_command(sc, cm);
 		}
-
-		desc->Words.Low = 0xffffffff;
-		desc->Words.High = 0xffffffff;
 	}
 
 	if (pq != sc->replypostindex) {



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