Links are reset or re-trained for power changes, error recovery or clock changes. Resetting a crossing clears its FIFOs and pointers. Anything inside is gone. The protocol never expected a message to vanish: the course model assumes reliable delivery, so nothing in H or the caches will notice or replay a lost message. A safe link reset therefore resets only an empty link with no transaction that still needs it.
The rule: quiesce first. Quiesce is four conditions, then the reset itself:
Step | What is done or checked | Why |
|---|---|---|
1. Stop new requests | C0 and C1 send no new GetS, GetM or Put. H admits no new request, from any agent, that would send an Inv or Fwd into this cluster. | Otherwise new work keeps arriving while you drain. |
2. Keep forwards and responses running | Inv, Fwd-GetS, Fwd-GetM, Inv-Ack, Data and Put-Ack still flow in both directions. | In-flight transactions need them to finish. A cache in MI^A must still answer a forward from its writeback buffer. |
3. No transaction half done | C0 and C1 MSHRs empty, no MI^A, EI^A, SI^A or II^A entries, H pending table empty for lines this cluster touches. | A pending entry will still send or expect a message: the link is still in use. |
4. Link empty | Every class FIFO empty in both directions, and every credit returned (sender credits = depth). | A FIFO can be empty for a moment while a pending entry is about to write into it, so check this after step 3. |
5. Reset, then re-enable | Reset both sides of every crossing together, credits back to full depth, retrain, then lift step 1. | Resetting one side only leaves stale credits or pointers (next lesson). |
Stable cache lines survive a link reset untouched. C0 may still hold M / 1 and H exclusive(C0): both sides agree, nothing is in flight, so the next Fwd-GetM after re-enable works normally. If the cluster itself will lose its contents, flushing comes first; see the sibling topic's lesson Flushing Before Power-Down.
Keep the roles of Upgrade from Shared: C0 and C1 both S / 0, C0 upgrades, C1 is invalidated. A link reset fires after step 2, while C1's Inv-Ack is in the cluster-to-H response FIFO.
Step | C0 state / value | C1 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|
Checkpoint (as in the upgrade trace) | S / 0 | S / 0 | S{C0,C1} | 0 | C0, C1 and memory: 0 |
1. GetM at H | SM^D / 0 | S / 0 | S{C0,C1}, pend GetM C0, acks 0/1 | 0 | C0, C1 and memory: 0 |
2. Inv at C1, Inv-Ack written into the crossing | SM^D / 0 | I / - | S{C0,C1}, pend GetM C0, acks 0/1 | 0 | C0 and memory: 0 |
Link reset clears the FIFO, Inv-Ack lost | SM^D / 0 | I / - | S{C0,C1}, pend GetM C0, acks 0/1 | 0 | C0 and memory: 0 |
No message reached H, so its entry does not change: it waits for an ack that will never come. C0 stays in SM^D, its loads hit and its store stalls forever. Nothing is corrupted, but X is hung, and every later request for X queues behind the pending entry. Resending the Inv could recover only if the protocol was designed to tolerate duplicate Inv and Inv-Ack; the course model is not.
Keep the roles of A Protocol Deadlock, four-hop route: C0 holds M / 1, memory = 0, C1 sends GetM. C0 answers Fwd-GetM, gives up X, and its Data(1) is in the response crossing when the link resets.
Step | C0 state / value | C1 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|
Warm-up | M / 1 | I / - | exclusive(C0) | 0 | C0: 1 |
1. GetM at H | M / 1 | IM^D / - | exclusive(C0), pend GetM C1 | 0 | C0: 1 |
2. Fwd-GetM at C0, Data(1) written into the crossing | I / - | IM^D / - | exclusive(C0), pend GetM C1 | 0 | Data(1) in flight to H |
Link reset clears the FIFO, Data(1) lost | I / - | IM^D / - | exclusive(C0), pend GetM C1 | 0 | none: 1 is lost |
(assumed, bug) timeout: H reads memory, sends Data(0, M) | I / - | IM^D / - | exclusive(C0), pend GetM C1 | 0 | none: 1 is lost |
Data(0) at C1 | I / - | M / 0 | exclusive(C0), pend GetM C1 | 0 | none: 1 is lost |
This is worse than a hang. The only copy of 1 was in the FIFO. If recovery logic times out and refills C1 from memory, C1 reads 0 after a completed store of 1: a silent data-value violation. The lesson is the same as Part 5's: a timeout is not a safe recovery, and a reset must never be the way a stuck transaction is cleared.
Not until the reset is done. Step 1 stops H admitting any request that needs a forward into this cluster, from any agent. Otherwise the forward or its Data could be in the crossing when the reset fires, which is the lost-Data case.