Author: smh
Date: Wed Mar 14 21:32:23 2018
New Revision: 330951
URL: https://svnweb.freebsd.org/changeset/base/330951

Log:
  Fix mps deadlock when handling panic
  
  During shutdown mps waits for its SSU requests to complete however when
  performing a reboot after handling a panic the scheduler is stopped so
  getmicrotime which is used can be non-functional.
  
  Switch to using the same method as shutdown_panic to ensure we actually
  complete.
  
  In addition reduce the timeout when RB_NOSYNC is set in howto as we expect
  this to fail.
  
  Reviewed by:  slm
  MFC after:    1 week
  Sponsored by: Multiplay
  Differential Revision:        https://reviews.freebsd.org/D12776

Modified:
  head/sys/dev/mps/mps_sas_lsi.c
  head/sys/dev/mps/mpsvar.h

Modified: head/sys/dev/mps/mps_sas_lsi.c
==============================================================================
--- head/sys/dev/mps/mps_sas_lsi.c      Wed Mar 14 21:21:03 2018        
(r330950)
+++ head/sys/dev/mps/mps_sas_lsi.c      Wed Mar 14 21:32:23 2018        
(r330951)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/kthread.h>
 #include <sys/taskqueue.h>
 #include <sys/sbuf.h>
+#include <sys/reboot.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
@@ -126,7 +127,7 @@ int mpssas_get_sas_address_for_sata_disk(struct mps_so
     u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD);
 static int mpssas_volume_add(struct mps_softc *sc,
     u16 handle);
-static void mpssas_SSU_to_SATA_devices(struct mps_softc *sc);
+static void mpssas_SSU_to_SATA_devices(struct mps_softc *sc, int howto);
 static void mpssas_stop_unit_done(struct cam_periph *periph,
     union ccb *done_ccb);
 
@@ -1122,7 +1123,7 @@ out:
  * Return nothing.
  */
 static void
-mpssas_SSU_to_SATA_devices(struct mps_softc *sc)
+mpssas_SSU_to_SATA_devices(struct mps_softc *sc, int howto)
 {
        struct mpssas_softc *sassc = sc->sassc;
        union ccb *ccb;
@@ -1130,7 +1131,7 @@ mpssas_SSU_to_SATA_devices(struct mps_softc *sc)
        target_id_t targetid;
        struct mpssas_target *target;
        char path_str[64];
-       struct timeval cur_time, start_time;
+       int timeout;
 
        /*
         * For each target, issue a StartStopUnit command to stop the device.
@@ -1193,17 +1194,23 @@ mpssas_SSU_to_SATA_devices(struct mps_softc *sc)
        }
 
        /*
-        * Wait until all of the SSU commands have completed or time has
-        * expired (60 seconds).  Pause for 100ms each time through.  If any
-        * command times out, the target will be reset in the SCSI command
-        * timeout routine.
+        * Timeout after 60 seconds by default or 10 seconds if howto has
+        * RB_NOSYNC set which indicates we're likely handling a panic.
         */
-       getmicrotime(&start_time);
-       while (sc->SSU_refcount) {
+       timeout = 600;
+       if (howto & RB_NOSYNC)
+               timeout = 100;
+
+       /*
+        * Wait until all of the SSU commands have completed or timeout has
+        * expired.  Pause for 100ms each time through.  If any command
+        * times out, the target will be reset in the SCSI command timeout
+        * routine.
+        */
+       while (sc->SSU_refcount > 0) {
                pause("mpswait", hz/10);
                
-               getmicrotime(&cur_time);
-               if ((cur_time.tv_sec - start_time.tv_sec) > 60) {
+               if (--timeout == 0) {
                        mps_dprint(sc, MPS_FAULT, "Time has expired waiting "
                            "for SSU commands to complete.\n");
                        break;
@@ -1245,7 +1252,7 @@ mpssas_stop_unit_done(struct cam_periph *periph, union
  * Return nothing.
  */
 void
-mpssas_ir_shutdown(struct mps_softc *sc)
+mpssas_ir_shutdown(struct mps_softc *sc, int howto)
 {
        u16 volume_mapping_flags;
        u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
@@ -1350,5 +1357,5 @@ out:
                        }
                }
        }
-       mpssas_SSU_to_SATA_devices(sc);
+       mpssas_SSU_to_SATA_devices(sc, howto);
 }

Modified: head/sys/dev/mps/mpsvar.h
==============================================================================
--- head/sys/dev/mps/mpsvar.h   Wed Mar 14 21:21:03 2018        (r330950)
+++ head/sys/dev/mps/mpsvar.h   Wed Mar 14 21:32:23 2018        (r330951)
@@ -772,7 +772,7 @@ int mps_config_get_volume_wwid(struct mps_softc *sc, u
 int mps_config_get_raid_pd_pg0(struct mps_softc *sc,
     Mpi2ConfigReply_t *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page,
     u32 page_address);
-void mpssas_ir_shutdown(struct mps_softc *sc);
+void mpssas_ir_shutdown(struct mps_softc *sc, int howto);
 
 int mps_reinit(struct mps_softc *sc);
 void mpssas_handle_reinit(struct mps_softc *sc);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to