<HTML><HEAD><TITLE>Samsung Enterprise Portal mySingle</TITLE>
<META content=IE=5 http-equiv=X-UA-Compatible>
<META content="text/html; charset=windows-1252" http-equiv=Content-Type>
<STYLE id=mysingle_style type=text/css>P {
        MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial, arial; MARGIN-TOP: 5px
}
TD {
        MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial, arial; MARGIN-TOP: 5px
}
LI {
        MARGIN-BOTTOM: 5px; FONT-SIZE: 9pt; FONT-FAMILY: Arial, arial; MARGIN-TOP: 5px
}
BODY {
        FONT-SIZE: 9pt; FONT-FAMILY: Arial, arial; MARGIN: 10px; LINE-HEIGHT: 1.4
}
</STYLE>

<META name=GENERATOR content=ActiveSquare></HEAD>
<BODY>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">Hi Everyone,</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><BR>We have a patch for the Hot plug fixes.</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">Please find attached the source code. The password is samsung123</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"></SPAN> </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>Please find the change description below - </STRONG></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG></STRONG></SPAN> </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>1) Surprise removal while IOs are in progress.</STRONG></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>To reproduce this scenario -<BR></STRONG>Connect the disk and execute IOmeter on the disk volume. When IOs are in progress, surprise remove the device. User expects that </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">the device should be removed from device manager immediately and iometer should increase the error count field. This does not </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">happen since we don't handle this scenario in OFA driver.</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>Resolution -</STRONG><BR>a. Added a new function IsdeviceRemoved(). This is a recursive function. Compares the values of Version Register values with old </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">value and incase of mismatch complete the outstanding commands with SRB_STATUS_ERROR. (nvmeStd.c/IsDeviceRemoved)<BR>b. Start the Timer for IsDeviceRemoved() when the NextDriverState is set to StartComplete.(nvmeStat.c/NVMeRunning)<BR>c. Stop the timer for IsDeviceRemoved() incase of ScsiStopAdapter. (nvmeStat.c/NVMeAdapterControl)<BR>d. Restart the timer for IsDeviceRemoved() incase of ScsiRestartAdapter. (nvmeStat.c/NVMeAdapterControl)<BR>e. Stop the timer for IsDeviceRemoved() incase of SRB_FUNCTION_SHUTDOWN. (nvmeStd.c/NVMeBuildIo)<BR>f. If DeviceRemovedDuringIO flag is set to TRUE, complete the SRBs with SRB_STATUS_ERROR for the IOs. This case is to handle the </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">IOs received once the device has been surprise removed. (nvmeStdc/NVMeBuildIo)<BR>g. Modified the prototype of NVMeDetectPendingCmds function. When device is surprise removed when IOs are pending, the </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">outstanding IOs has to be completed with SRB_STATUS_ERROR. (nvmeIo.c/NVMeDetectPendingCmds)<BR>h. Call the NVMeDetectPendingCmds function with SRB_STATUS_BUS_RESET. (nvmeInit.c/NVMeNormalShutdown, </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">nvmePwrMgmt.c/NVMeAdapterControlPowerDown, nvmeStd.c/RecoveryDpcRoutine)</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"></SPAN> </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>2) Memory leak issues.</STRONG></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>To reproduce this scenario -<BR></STRONG>a. Memory leak observed during hot removal in Resource monitor->Non-paged pool. (On Server2012R2 -> Task Manager -> Performance -> </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">Non-paged pool)<BR>b. Memory leak observed during disable/enable the NVMe controller in device manager.</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>Resolution -</STRONG><BR>To fix memory leak, in NVMeBuildIo()->SRB_FUNCTION_PNP, when PnPAction is StorRemoveDevice(disable controller) and </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">StorSurpriseRemoval(hot remove device), NVMeAdapterControlPowerDown() is invoked to stop the adapter and then NVMeFreeBuffers is </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">invoked to free the memory. At this point, since the ShutdownInProgress is set in NVMeAdapterControlPowerDown(), nothing is done </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">during NVMeAdapterControl() - ScsiStopAdapter -> NVMeAdapterControlPowerDown().</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"></SPAN> </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>3) Surprise Removal during Disk Initialization</STRONG></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>To reproduce this scenario - <BR></STRONG>Hot insert the device and hot remove the device immediately. At this point, our driver might be executing the initialization </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">state machine in NVMePassiveInitialize. The device will not be immediately removed from the device manger. The while loop will be </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">active till passiveTimeout happens, then system BSOD.</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>Resolution -</STRONG><BR>a. Read the Version register. This is used to compare against the value in version register after a surprise removal. </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">(nvmeStd.c/NVMeFindAdapter)<BR>b. Read the Version Register and compare with old Version Register value(i.e. value read in NVMeFindAdapter). Mismatch in these </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">values means surprise removal. (nvmeStd.c/NVMePassiveInitialize)<BR>c. Set the NextDriverState to NVMeStartComplete and DeviceRemovedDuringIO to TRUE and return TRUE from NVMePassiveInitialize.<BR>d. Driver may get commands in NVMeBuildIo, where driver returns SRB_STATUS_ERROR when DeviceRemovedDuringIO is set to TRUE.<BR>e. Then NVMeAdapterControl() - ScsiStopAdapter is executed. </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"></SPAN> </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>4) Delay in removing the device from device manager after hot removal of device. </STRONG>When device is hot removed, the NVMeAdapterControlPowerDown() -> NVMeResetAdapter() -> NVMeWaitForCtrlRDY() is invoked which sets </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">the EN bit to 0 and waits for RDY bit to become 0. Since the device is physically removed, the memory mapped registers will be </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">come all 1's and the RDY bit will never become 0. Hence the while loop in NVMeWaitForCtrlRDY() is active for some time even after </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">device removal and hence device is not removed from device manager immediately. </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>Resolution -</STRONG><BR>Check for the value of CSTS. If its 0xFFFFFFFF, then device has been surprise removed and return TRUE. </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">(nvmeStd.c/NVMeWaitForCtrlRDY)</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"></SPAN> </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>5) Avoid redundant call of NVMeResetAdapter()</STRONG><BR>a. File/Function: nvmeInit.c/NVMeEnableAdapter - Removed the NVMeResetAdapter() function call from NVMeEnableAdapter() as this is </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">redundant.  The NVMeResetAdapter() is being invoked in the RecoveryDpcRouitne() and then again its being invoked in the </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">NVMeEnableAdapter.<BR>b. In the NVMeInitialize() function the EN and RDY bit are set to 0 before the  NVMeEnableAdapter() is being invoked. But </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">NVMeResetAdapter() does again the same functionality.</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"></SPAN> </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"><STRONG>6) </STRONG>When testing hot insertion with different devices, we observed some devices returned NAMESPACE_NOT_READY for IO commands </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">during learning cores and disk initialization(report luns, inquiry, etc). To address this issue and provide support for these </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">devices in the driver, we have done the following changes.<BR>a. During learning cores, driver sends read commands on all the queues to get the core to MSI-x mapping. When the read commands </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">are interrupted, in the NVMeInitCallback(), if the SC and SCT values are not 0, then the learning cores is not completed. This </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">check is not required as driver wants only the core to MSI-x mapping. Since this is not a fatal error, we can skip reading the SC </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">and SCT values, as this will impact the performance. (nvmeInit.c/NVMeInitCallback).<BR>b. Following the above, when the initialization state machine is complete and kernel starts sending SCSI commands for disk </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">initialization, and when device returns NAMESPACE_NOT_READY, this has to be translated to the corresponding SCSI sense data so </SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">that the commands will be re-tried after some time. (nvmeSnti.c/genericCommandStatusTable[]).  </SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"> <BR><STRONG>Tested the following.</STRONG></SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">- WHCK on Win7 and 2012R2<BR>- Install/Uninstall, Enable/Disable, FS Format<BR>- Hibernation/Resume, Sleep/Resume<BR>- IOmeter<BR>- Hot removal which iometer is running.<BR>- Hot removal immediately after hot insertion.<BR>- Continous hot insert and remove operations.<BR>- Check for device removal after following sequence - Hot insert, system hibernation, Hot remove, system resume.<BR>- Check for device presense after following sequence - System hibernation, hot insert, system resume.<BR>- Memory leaks during hot plug operations and disable/enable.</SPAN></P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri"></SPAN> </P>
<P><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Calibri">Thanks,<BR>Suman</SPAN></P><SPAN style="FONT-FAMILY: Calibri"></SPAN><!--SP:suman.p--><!--suman.p:EP-->
<P> </P>
<TABLE id=confidentialsignimg>
<TBODY>
<TR>
<TD NAMO_LOCK>
<P><IMG border=0 src="cid:TEACQZUWXYH6@namo.co.kr"></P></TD></TR></TBODY></TABLE></BODY></HTML><img src='http://ext.samsung.net/mailcheck/SeenTimeChecker?do=27783e66f4ae159f577e025300a19f1b6b789e13ae6bb28d7d9badbdf7e30042d1afaaba7860cdcd9564217c646641ad61e16949eaa607501b20909a04efd4d2748cfe1d4e847419cf878f9a26ce15a0' border=0 width=0 height=0 style='display:none'>