Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 3 Nov 2017 15:07:36 +0000 (UTC)
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r325363 - head/sys/dev/mpr
Message-ID:  <201711031507.vA3F7aZ3001875@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Fri Nov  3 15:07:36 2017
New Revision: 325363
URL: https://svnweb.freebsd.org/changeset/base/325363

Log:
  Fix mpr(4) panics caused by bad drive mapping tables
  
  sys/dev/mpr/mpr_mapping.c
  	If _mapping_process_dpm_pg0 detects inconsistencies in the drive
  	mapping table (stored in the HBA's NVRAM), abort reading it and
  	continue to boot as if the mapping table were blank.  I observed
  	such inconsistencies in several HBAs after upgrading firmware from
  	14.0.0.0 to 15.0.0.0.
  
  Reviewed by:	slm
  MFC after:	3 weeks
  Sponsored by:	Spectra Logic Corp
  Differential Revision:	https://reviews.freebsd.org/D12901

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

Modified: head/sys/dev/mpr/mpr_mapping.c
==============================================================================
--- head/sys/dev/mpr/mpr_mapping.c	Fri Nov  3 14:10:57 2017	(r325362)
+++ head/sys/dev/mpr/mpr_mapping.c	Fri Nov  3 15:07:36 2017	(r325363)
@@ -2207,7 +2207,7 @@ mpr_mapping_free_memory(struct mpr_softc *sc)
 	free(sc->dpm_pg0, M_MPR);
 }
 
-static void
+static bool
 _mapping_process_dpm_pg0(struct mpr_softc *sc)
 {
 	u8 missing_cnt, enc_idx;
@@ -2336,7 +2336,7 @@ _mapping_process_dpm_pg0(struct mpr_softc *sc)
 					    "%s: Conflict in mapping table for "
 					    " enclosure %d\n", __func__,
 					    enc_idx);
-					break;
+					goto fail;
 				}
 				physical_id =
 				    dpm_entry->PhysicalIdentifier.High;
@@ -2363,7 +2363,7 @@ _mapping_process_dpm_pg0(struct mpr_softc *sc)
 				mpr_dprint(sc, MPR_ERROR | MPR_MAPPING, "%s: "
 				    "Conflict in mapping table for device %d\n",
 				    __func__, map_idx);
-				break;
+				goto fail;
 			}
 			physical_id = dpm_entry->PhysicalIdentifier.High;
 			mt_entry->physical_id = (physical_id << 32) |
@@ -2375,6 +2375,18 @@ _mapping_process_dpm_pg0(struct mpr_softc *sc)
 			mt_entry->device_info = MPR_DEV_RESERVED;
 		}
 	} /*close the loop for DPM table */
+	return (true);
+
+fail:
+	for (entry_num = 0; entry_num < sc->max_dpm_entries; entry_num++) {
+		sc->dpm_entry_used[entry_num] = 0;
+		/*
+		 * for IR firmware, it may be necessary to wipe out
+		 * sc->mapping_table volumes tooi
+		 */
+	}
+	sc->num_enc_table_entries = 0;
+	return (false);
 }
 
 /*
@@ -2614,9 +2626,11 @@ retry_read_dpm:
 		}
 	}
 
-	if (sc->is_dpm_enable)
-		_mapping_process_dpm_pg0(sc);
-	else {
+	if (sc->is_dpm_enable) {
+		if (!_mapping_process_dpm_pg0(sc))
+			sc->is_dpm_enable = 0;
+	}
+	if (! sc->is_dpm_enable) {
 		mpr_dprint(sc, MPR_MAPPING, "%s: DPM processing is disabled. "
 		    "Device mappings will not persist across reboots or "
 		    "resets.\n", __func__);



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