ruby: MOESI_CMP_token dma fixes
authorBrad Beckmann <Brad.Beckmann@amd.com>
Fri, 20 Aug 2010 18:46:13 +0000 (11:46 -0700)
committerBrad Beckmann <Brad.Beckmann@amd.com>
Fri, 20 Aug 2010 18:46:13 +0000 (11:46 -0700)
This patch fixes various protocol bugs regarding races between dma requests
and persistent requests.

src/mem/protocol/MOESI_CMP_token-dir.sm

index 261fbba07c34296f529e764804f3174e388ff2cf..79a3839f73de2a84430f643232c9daa4031fb737 100644 (file)
@@ -86,6 +86,7 @@ machine(Directory, "Token protocol")
     Lockdown, desc="A lockdown request arrives";
     Unlockdown, desc="An un-lockdown request arrives";
     Own_Lock_or_Unlock, desc="own lock or unlock";
+    Own_Lock_or_Unlock_Tokens, desc="own lock or unlock with tokens";
     Data_Owner, desc="Data arrive";
     Data_All_Tokens, desc="Data and all tokens";
     Ack_Owner, desc="Owner token arrived without data because it was clean";
@@ -179,7 +180,7 @@ machine(Directory, "Token protocol")
     }
     getDirectoryEntry(addr).DirectoryState := state;
 
-    if (state == State:L) {
+    if (state == State:L || state == State:DW_L || state == State:DR_L) {
       assert(getDirectoryEntry(addr).Tokens == 0);
     } 
 
@@ -190,7 +191,7 @@ machine(Directory, "Token protocol")
     assert(getDirectoryEntry(addr).Tokens >= 0);
     assert(getDirectoryEntry(addr).Tokens <= max_tokens());
 
-    if (state == State:O) {
+    if (state == State:O || state == State:O_W || state == State:O_DW) {
       assert(getDirectoryEntry(addr).Tokens >= 1); // Must have at least one token
       // assert(getDirectoryEntry(addr).Tokens >= (max_tokens() / 2)); // Only mostly true; this might not always hold
     }
@@ -293,7 +294,11 @@ machine(Directory, "Token protocol")
           // React to the message based on the current state of the table
           if (persistentTable.isLocked(in_msg.Address)) {
             if (persistentTable.findSmallest(in_msg.Address) == machineID) {
-              trigger(Event:Own_Lock_or_Unlock, in_msg.Address);
+              if (getDirectoryEntry(in_msg.Address).Tokens > 0) {
+                trigger(Event:Own_Lock_or_Unlock_Tokens, in_msg.Address);
+              } else {
+                trigger(Event:Own_Lock_or_Unlock, in_msg.Address);
+              }
             } else {
               trigger(Event:Lockdown, in_msg.Address); // locked
             }   
@@ -303,7 +308,11 @@ machine(Directory, "Token protocol")
         }
         else {
           if (persistentTable.findSmallest(in_msg.Address) == machineID) {
-            trigger(Event:Own_Lock_or_Unlock, in_msg.Address);
+              if (getDirectoryEntry(in_msg.Address).Tokens > 0) {
+                trigger(Event:Own_Lock_or_Unlock_Tokens, in_msg.Address);
+              } else {
+                trigger(Event:Own_Lock_or_Unlock, in_msg.Address);
+              }
           } else if (in_msg.Type == PersistentRequestType:GETX_PERSISTENT) {
             trigger(Event:Lockdown, in_msg.Address); // locked
           } else if (in_msg.Type == PersistentRequestType:GETS_PERSISTENT) {
@@ -540,7 +549,7 @@ machine(Directory, "Token protocol")
     getDirectoryEntry(address).Tokens := 0;
   }
 
-  action(dd_sendDataWithAllTokensToStarver, "\d", desc="Send data and tokens to starver") {
+  action(dd_sendMemDataToStarver, "\d", desc="Send data and tokens to starver") {
     peek(memQueue_in, MemoryMsg) {
       enqueue(responseNetwork_out, ResponseMsg, latency="1") {
         out_msg.Address := address;
@@ -557,6 +566,21 @@ machine(Directory, "Token protocol")
     getDirectoryEntry(address).Tokens := 0;
   }
 
+  action(de_sendTbeDataToStarver, "de", desc="Send data and tokens to starver") {
+    enqueue(responseNetwork_out, ResponseMsg, latency="1") {
+      out_msg.Address := address;
+      out_msg.Type := CoherenceResponseType:DATA_OWNER;
+      out_msg.Sender := machineID;
+      out_msg.Destination.add(persistentTable.findSmallest(address));
+      assert(getDirectoryEntry(address).Tokens > 0);
+      out_msg.Tokens := getDirectoryEntry(address).Tokens;
+      out_msg.DataBlk := TBEs[address].DataBlk;
+      out_msg.Dirty := false;
+      out_msg.MessageSize := MessageSizeType:Response_Data;
+    }
+    getDirectoryEntry(address).Tokens := 0;
+  }
+
   action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
     peek(requestNetwork_in, RequestMsg) {    
       enqueue(memQueue_out, MemoryMsg, latency="1") {
@@ -865,6 +889,7 @@ machine(Directory, "Token protocol")
 
   transition(O, DMA_WRITE, O_DW) {
     vd_allocateDmaRequestInTBE;
+    cd_writeCleanDataToTbe;
     bw_broadcastWrite;
     st_scheduleTimeout;
     p_popDmaRequestQueue;
@@ -924,6 +949,11 @@ machine(Directory, "Token protocol")
   //
   // issued GETX for DMA write, waiting for all tokens
   //
+  transition(O_DW, Request_Timeout) {
+    ut_unsetReissueTimer;
+    px_tryIssuingPersistentGETXRequest;
+  }
+
   transition(O_DW, Tokens) {
     f_incrementTokens;
     k_popIncomingResponseQueue;
@@ -942,6 +972,7 @@ machine(Directory, "Token protocol")
   }
 
   transition(O_DW, Lockdown, DW_L) {
+    de_sendTbeDataToStarver;
     l_popIncomingPersistentQueue;
   }
 
@@ -1050,7 +1081,6 @@ machine(Directory, "Token protocol")
   transition(NO_DW, Data_Owner, O_DW) {
     f_incrementTokens;
     rd_recordDataInTbe;
-    lq_queueMemoryWbRequest;
     k_popIncomingResponseQueue;
   }
 
@@ -1111,12 +1141,16 @@ machine(Directory, "Token protocol")
     k_popIncomingResponseQueue;
   }
 
-  transition(L, Unlockdown, NO) {
+  transition(L, {Unlockdown, Own_Lock_or_Unlock}, NO) {
+    l_popIncomingPersistentQueue;
+  }
+
+  transition(L, Own_Lock_or_Unlock_Tokens, O) {
     l_popIncomingPersistentQueue;
   }
 
   transition({L_NO_W, L_O_W}, Memory_Data, L) {
-    dd_sendDataWithAllTokensToStarver;
+    dd_sendMemDataToStarver;
     l_popMemQueue;
   }
 
@@ -1125,16 +1159,16 @@ machine(Directory, "Token protocol")
     l_popMemQueue;
   }
 
-  transition(L_O_W, Unlockdown, O_W) {
+  transition(L_O_W, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, O_W) {
     l_popIncomingPersistentQueue;
   }
 
-  transition(L_NO_W, Unlockdown, NO_W) {
+  transition(L_NO_W, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, NO_W) {
     l_popIncomingPersistentQueue;
   }
 
   transition(DR_L_W, Memory_Data, DR_L) {
-    dd_sendDataWithAllTokensToStarver;
+    dd_sendMemDataToStarver;
     l_popMemQueue;
   }
 
@@ -1142,19 +1176,19 @@ machine(Directory, "Token protocol")
     aat_assertAllTokens;
     da_sendDmaAck;
     s_deallocateTBE;
-    dd_sendDataWithAllTokensToStarver;
+    dd_sendMemDataToStarver;
     l_popMemQueue;
   }
 
-  transition(DW_L, {Unlockdown, Own_Lock_or_Unlock}, NO_DW) {
+  transition(DW_L, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, NO_DW) {
     l_popIncomingPersistentQueue;
   }
 
-  transition(DR_L_W, Unlockdown, O_DR_W) {
+  transition(DR_L_W, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, O_DR_W) {
     l_popIncomingPersistentQueue;
   }
 
-  transition(DW_L_W, Unlockdown, O_DW_W) {
+  transition(DW_L_W, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, O_DW_W) {
     l_popIncomingPersistentQueue;
   }
 
@@ -1163,7 +1197,7 @@ machine(Directory, "Token protocol")
     px_tryIssuingPersistentGETXRequest;
   }
 
-  transition(DR_L, {Unlockdown, Own_Lock_or_Unlock}, NO_DR) {
+  transition(DR_L, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, NO_DR) {
     l_popIncomingPersistentQueue;
   }
 
@@ -1180,7 +1214,7 @@ machine(Directory, "Token protocol")
     l_popMemQueue; 
   }
 
-  transition({O, NO, O_DW, NO_DW, NO_DR}, Own_Lock_or_Unlock) {
+  transition({O, NO}, {Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}) {
     l_popIncomingPersistentQueue;
   }
 
@@ -1193,7 +1227,7 @@ machine(Directory, "Token protocol")
     y_recycleDmaRequestQueue;
   }
 
-  transition({NO_W, O_W, L_O_W, L_NO_W, DR_L_W, DW_L_W, O_DW_W, O_DR_W}, {Data_Owner, Ack_Owner, Tokens, Ack_All_Tokens}) {
+  transition({NO_W, O_W, L_O_W, L_NO_W, DR_L_W, DW_L_W, O_DW_W, O_DR_W}, {Data_Owner, Ack_Owner, Tokens, Data_All_Tokens, Ack_All_Tokens}) {
     kz_recycleResponse;
   }
 
@@ -1222,7 +1256,7 @@ machine(Directory, "Token protocol")
     l_popIncomingPersistentQueue;
   }
 
-  transition({NO_W, O_W, O_DR_W, O_DW_W}, {Unlockdown, Own_Lock_or_Unlock}) {
+  transition({NO_W, O_W, O_DR_W, O_DW_W, O_DW, NO_DR, NO_DW}, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}) {
     l_popIncomingPersistentQueue;
   }
 }