NvmeStorage: Fixed an issue that caused registers to be read wrong occassionaly.
authorTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Wed, 10 Jun 2020 15:15:33 +0000 (16:15 +0100)
committerTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Wed, 10 Jun 2020 15:15:33 +0000 (16:15 +0100)
Test: Added extra performance testing code including deallocate performance.

docsrc/DuneNvmeStorageDesign.odt
docsrc/DuneNvmeStorageManual.odt
src/NvmeStorage.vhd
test/Makefile
test/test_deallocate.sh [new file with mode: 0644]
test/test_nvme.cpp

index 57f6ed74937d22c7c7b8bf26f009c24c9f00b79c..5275a61d9ad49b16e6053be5cef5cb0d7e37830d 100644 (file)
Binary files a/docsrc/DuneNvmeStorageDesign.odt and b/docsrc/DuneNvmeStorageDesign.odt differ
index 8e5545b108aa9c72429764b8144ddab7792816bc..e4237fb2c294bcf40d578ec12e7684dd0699a840 100644 (file)
Binary files a/docsrc/DuneNvmeStorageManual.odt and b/docsrc/DuneNvmeStorageManual.odt differ
index d9e42d237fe4f07ac4b80fc9d2ecbe9adcaa0fc0..b976c63a14d35918d560536d9b81d91872e5a0ca 100644 (file)
@@ -257,7 +257,7 @@ begin
                                        regAddress <= unsigned(axilIn.awaddr(9 downto 0));
                                elsif(axilIn.arvalid = '1') then
                                        regAddress <= unsigned(axilIn.araddr(9 downto 0));
-                                       rvalid_delay(0) <= '1';
+                                       rvalid_delay <= to_unsigned(1, rvalid_delay'length);
                                else
                                        -- rvalid delay to handle clock domain crossing latency
                                        rvalid_delay <= shift_left(rvalid_delay, 1);
index ca2bc175e9532c312ec58e280a4fb8014dc1f4e4..71ba7320429eb2097ac8dc397181634958a9b45f 100644 (file)
@@ -32,5 +32,9 @@ driver_load:
 
 ${PROG}: ${OBJS}
 
+installPackages:
+       # Install the necessary Fedora Linux packages
+       dnf install @development-tools gcc-c++ kernel-devel
+       
 # Dependancies
 -include $(OBJS:.o=.d)
diff --git a/test/test_deallocate.sh b/test/test_deallocate.sh
new file mode 100644 (file)
index 0000000..74629ff
--- /dev/null
@@ -0,0 +1,84 @@
+#!/usr/bin/sh
+#######################################################################
+# test_deallocate.shh  Test performance with various dellocate delays
+#######################################################################
+#
+# Note this test should be performed with the NvmeStorage modules NvmeWrite
+# trim functionality disabled.
+#
+
+# Drives testing with two off 500 GByte drives
+let "driveAllBlocks = 2 * 450 * 1024 * 1024 * 1024 / 4096"
+let "captureBlocks = 200 * 1024 * 1024 * 1024 / 4096"
+delay=60
+
+echo "Test for NVMe drive deallocate time. Total drive blocks: ${driveAllBlocks} Capture Blocks: ${captureBlocks}"
+
+testCapture(){
+       #echo "Simple capture of available space"
+
+       IFS=, r1=(`./test_nvme -m -nr -d 2 -s $1 -n ${captureBlocks} capture`)
+       
+       #echo "Capture: ${r1[*]}"
+       echo ${r1[2]}
+}
+
+compareRate(){
+       r=`(echo "$1 > 4000" | bc)`
+       if [ "$r" = "1" ]; then
+               return 1;
+       else
+               return 0;
+       fi
+}
+
+test1(){
+       # Initiallity allocate most of the drives blocks for worst case
+       echo "Allocate most of the drives blocks to start"
+       start=0
+       ./test_nvme -d 2 -s ${start} -n ${captureBlocks} capture
+       start=`expr ${start} + ${captureBlocks}`
+       ./test_nvme -d 2 -s ${start} -n ${captureBlocks} capture
+       start=`expr ${start} + ${captureBlocks}`
+       ./test_nvme -d 2 -s ${start} -n ${captureBlocks} capture
+       start=`expr ${start} + ${captureBlocks}`
+       ./test_nvme -d 2 -s ${start} -n ${captureBlocks} capture
+       
+       while true; do
+               echo
+               echo "Test cycle with deallocate delay set to: $delay"
+               echo "Deallocate at 0"
+               ./test_nvme -nr -d 2 -s 0 -n ${captureBlocks} trim
+               sleep $delay
+
+               echo "Run Capture at block: 0"
+               rate=`testCapture 0`
+               echo "Rate: $rate"
+               if compareRate $rate; then
+                       echo "Error rate was ${rate}"
+                       #return 1;
+               fi
+               
+
+               echo
+               echo "Deallocate at ${captureBlocks}"
+               ./test_nvme -nr -d 2 -s ${captureBlocks} -n ${captureBlocks} trim
+               sleep $delay
+
+               echo "Run Capture at block: ${captureBlocks}"
+               rate=`testCapture ${captureBlocks}`
+               echo "Rate: $rate"
+               if compareRate $rate; then
+                       echo "Error Rate was ${rate}"
+                       #return 1;
+               fi;
+
+               delay=`expr $delay + 10`
+       done
+}
+
+
+#captureBlocks=100
+test1
+
+exit 0
index aac41a6d9603a1ed658587eb0b94675b56dacaf2..40e837c64c59933760d8f92ea72c9c15b65db900 100644 (file)
@@ -101,6 +101,7 @@ public:
        BUInt           overbose;                               ///< Verbose operation
        Bool            oreset;                                 ///< Perform reset/config
        Bool            ovalidate;                              ///< Validate data
+       Bool            omachine;                               ///< Return machine readable data only
        BUInt32         ostartBlock;                            ///< The starting block number
        BUInt32         onumBlocks;                             ///< The number of blocks
        BUInt32         oreadStartBlock;                        ///< The read starting block number
@@ -117,6 +118,7 @@ public:
 
 Control::Control() : ofifo0(1024*1024), ofifo1(1024*1024){
        overbose = 0;
+       omachine = 0;
        oreset = 1;
        ovalidate = 1;
        ostartBlock = 0;
@@ -491,7 +493,8 @@ int Control::nvmeCapture(){
        double  ts;
        BUInt   numBlocks;
        
-       printf("nvmeCapture: Write FPGA data stream to Nvme devices. nvme: %u startBlock: %u numBlocks: %u\n", onvmeNum, ostartBlock, onumBlocks);
+       if(!omachine)
+               printf("nvmeCapture: Write FPGA data stream to Nvme devices. nvme: %u startBlock: %u numBlocks: %u\n", onvmeNum, ostartBlock, onumBlocks);
 
        // Initialise Nvme devices
        if(e = nvmeInit())
@@ -548,7 +551,10 @@ int Control::nvmeCapture(){
        }
 
        uprintf("Time: %u\n", t);
-       tprintf("StartBlock: %8u ErrorStatus: 0x%x, DataRate: %.3f MBytes/s, PeakLatancy: %8u us\n", ostartBlock, e, r / (1024 * 1024), l);
+       if(omachine)
+               printf("0x%x,%u,%.3f,%u\n", e, ostartBlock, r / (1024 * 1024), l);
+       else
+               tprintf("ErrorStatus: 0x%x, StartBlock: %8u, DataRate: %.3f MBytes/s, PeakLatancy: %8u us\n", e, ostartBlock, r / (1024 * 1024), l);
 
        uprintf("Stop NvmeWrite engine\n");
        writeNvmeStorageReg(RegControl, 0x00000000);
@@ -646,7 +652,7 @@ int Control::nvmeCaptureRepeat(){
                }
 
                uprintf("Process time: %u\n", t);
-               tprintf("%8d StartBlock: %8u ErrorStatus: 0x%x, DataRate: %.3f MBytes/s, PeakLatancy: %8u us\n", n, startBlock, e, r / (1024 * 1024), l);
+               tprintf("%8u ErrorStatus: 0x%x, StartBlock: %8u, DataRate: %.3f MBytes/s, PeakLatancy: %8u us\n", n, e, ostartBlock, r / (1024 * 1024), l);
 
                if(e){
                        printf("Error status: 0x%x, aborted\n", e);
@@ -872,12 +878,34 @@ int Control::nvmeTrim(){
 
 int Control::nvmeRegs(){
        int     e = 0;
+       BUInt   n = 0;
+       BUInt32 v;
 
        printf("NvmeRegs\n");
        
        // Note no reset and config
        dumpRegs(0);
        dumpRegs(1);
+
+#ifdef ZAP
+       // Soak test register interface 
+       //setNvme(1);
+
+       while(1){
+               v = readNvmeStorageReg(RegIdent);
+               if(v != 0x56000901){
+                       printf("Error: %u RegIdent: %8.8x\n", n, v);
+                       return 1;
+               }
+
+               v = readNvmeStorageReg(RegTotalBlocks);
+               if(v != 104857600){
+                       printf("Error: %u RegTotalBlocks: %u %8.8x\n", n, v, v);
+                       return 1;
+               }
+               n++;
+       }
+#endif
        
        return 0;
 }
@@ -1251,6 +1279,7 @@ void usage(void) {
        fprintf(stderr, "This program provides the ability perform access tests to an Nvme device on a FPGA development board\n");
        fprintf(stderr, " -help,-h              - Help on command line parameters\n");
        fprintf(stderr, " -v                    - Verbose. Two adds more verbosity\n");
+       fprintf(stderr, " -m                    - Just return software readable data.\n");
        fprintf(stderr, " -l                    - List tests\n");
        fprintf(stderr, " -no-reset || -nr      - Disable reset/config on startup\n");
        fprintf(stderr, " -no-validate || -nv   - Disable data validation on read's\n");
@@ -1266,6 +1295,7 @@ static struct option options[] = {
                { "h",                  0, NULL, 0 },
                { "help",               0, NULL, 0 },
                { "v",                  0, NULL, 0 },
+               { "m",                  0, NULL, 0 },
                { "l",                  0, NULL, 0 },
                { "no-reset",           0, NULL, 0 },
                { "nr",                 0, NULL, 0 },
@@ -1297,6 +1327,9 @@ int main(int argc, char** argv){
                else if(!strcmp(s, "v")){
                        control.overbose++;
                }
+               else if(!strcmp(s, "m")){
+                       control.omachine = 1;
+               }
                else if(!strcmp(s, "l")){
                        listTests = 1;
                }