mshr.cc (7636:59b6a1b5bb0c) | mshr.cc (7667:aa8fd8f6a495) |
---|---|
1/* 2 * Copyright (c) 2002-2005 The Regents of The University of Michigan 3 * Copyright (c) 2010 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright --- 75 unchanged lines hidden (view full) --- 84 mshr->downstreamPending = true; 85 } 86 } 87 88 push_back(Target(pkt, readyTime, order, source, markPending)); 89} 90 91 | 1/* 2 * Copyright (c) 2002-2005 The Regents of The University of Michigan 3 * Copyright (c) 2010 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright --- 75 unchanged lines hidden (view full) --- 84 mshr->downstreamPending = true; 85 } 86 } 87 88 push_back(Target(pkt, readyTime, order, source, markPending)); 89} 90 91 |
92static void 93replaceUpgrade(PacketPtr pkt) 94{ 95 if (pkt->cmd == MemCmd::UpgradeReq) { 96 pkt->cmd = MemCmd::ReadExReq; 97 DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n"); 98 } else if (pkt->cmd == MemCmd::SCUpgradeReq) { 99 pkt->cmd = MemCmd::SCUpgradeFailReq; 100 DPRINTF(Cache, "Replacing SCUpgradeReq with SCUpgradeFailReq\n"); 101 } 102} 103 104 |
|
92void 93MSHR::TargetList::replaceUpgrades() 94{ 95 if (!hasUpgrade) 96 return; 97 98 Iterator end_i = end(); 99 for (Iterator i = begin(); i != end_i; ++i) { | 105void 106MSHR::TargetList::replaceUpgrades() 107{ 108 if (!hasUpgrade) 109 return; 110 111 Iterator end_i = end(); 112 for (Iterator i = begin(); i != end_i; ++i) { |
100 if (i->pkt->cmd == MemCmd::UpgradeReq) { 101 i->pkt->cmd = MemCmd::ReadExReq; 102 DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n"); 103 } else if (i->pkt->cmd == MemCmd::SCUpgradeReq) { 104 i->pkt->cmd = MemCmd::SCUpgradeFailReq; 105 DPRINTF(Cache, "Replacing SCUpgradeReq with SCUpgradeFailReq\n"); 106 } | 113 replaceUpgrade(i->pkt); |
107 } 108 109 hasUpgrade = false; 110} 111 112 113void 114MSHR::TargetList::clearDownstreamPending() --- 60 unchanged lines hidden (view full) --- 175 ntargets = 1; 176 assert(targets->isReset()); 177 // Don't know of a case where we would allocate a new MSHR for a 178 // snoop (mem-side request), so set source according to request here 179 Target::Source source = (target->cmd == MemCmd::HardPFReq) ? 180 Target::FromPrefetcher : Target::FromCPU; 181 targets->add(target, whenReady, _order, source, true); 182 assert(deferredTargets->isReset()); | 114 } 115 116 hasUpgrade = false; 117} 118 119 120void 121MSHR::TargetList::clearDownstreamPending() --- 60 unchanged lines hidden (view full) --- 182 ntargets = 1; 183 assert(targets->isReset()); 184 // Don't know of a case where we would allocate a new MSHR for a 185 // snoop (mem-side request), so set source according to request here 186 Target::Source source = (target->cmd == MemCmd::HardPFReq) ? 187 Target::FromPrefetcher : Target::FromCPU; 188 targets->add(target, whenReady, _order, source, true); 189 assert(deferredTargets->isReset()); |
183 pendingInvalidate = false; 184 pendingShared = false; | |
185 data = NULL; 186} 187 188 189void 190MSHR::clearDownstreamPending() 191{ 192 assert(downstreamPending); 193 downstreamPending = false; 194 // recursively clear flag on any MSHRs we will be forwarding 195 // responses to 196 targets->clearDownstreamPending(); 197} 198 199bool | 190 data = NULL; 191} 192 193 194void 195MSHR::clearDownstreamPending() 196{ 197 assert(downstreamPending); 198 downstreamPending = false; 199 // recursively clear flag on any MSHRs we will be forwarding 200 // responses to 201 targets->clearDownstreamPending(); 202} 203 204bool |
200MSHR::markInService() | 205MSHR::markInService(PacketPtr pkt) |
201{ 202 assert(!inService); 203 if (isForwardNoResponse()) { 204 // we just forwarded the request packet & don't expect a 205 // response, so get rid of it 206 assert(getNumTargets() == 1); 207 popTarget(); 208 return true; 209 } 210 inService = true; | 206{ 207 assert(!inService); 208 if (isForwardNoResponse()) { 209 // we just forwarded the request packet & don't expect a 210 // response, so get rid of it 211 assert(getNumTargets() == 1); 212 popTarget(); 213 return true; 214 } 215 inService = true; |
216 pendingDirty = (targets->needsExclusive || 217 (!pkt->sharedAsserted() && pkt->memInhibitAsserted())); 218 postInvalidate = postDowngrade = false; 219 |
|
211 if (!downstreamPending) { 212 // let upstream caches know that the request has made it to a 213 // level where it's going to get a response 214 targets->clearDownstreamPending(); 215 } 216 return false; 217} 218 219 220void 221MSHR::deallocate() 222{ 223 assert(targets->empty()); 224 targets->resetFlags(); 225 assert(deferredTargets->isReset()); 226 assert(ntargets == 0); 227 inService = false; | 220 if (!downstreamPending) { 221 // let upstream caches know that the request has made it to a 222 // level where it's going to get a response 223 targets->clearDownstreamPending(); 224 } 225 return false; 226} 227 228 229void 230MSHR::deallocate() 231{ 232 assert(targets->empty()); 233 targets->resetFlags(); 234 assert(deferredTargets->isReset()); 235 assert(ntargets == 0); 236 inService = false; |
228 //allocIter = NULL; 229 //readyIter = NULL; | |
230} 231 232/* 233 * Adds a target to an MSHR 234 */ 235void 236MSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order) 237{ 238 // if there's a request already in service for this MSHR, we will 239 // have to defer the new target until after the response if any of 240 // the following are true: 241 // - there are other targets already deferred 242 // - there's a pending invalidate to be applied after the response 243 // comes back (but before this target is processed) | 237} 238 239/* 240 * Adds a target to an MSHR 241 */ 242void 243MSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order) 244{ 245 // if there's a request already in service for this MSHR, we will 246 // have to defer the new target until after the response if any of 247 // the following are true: 248 // - there are other targets already deferred 249 // - there's a pending invalidate to be applied after the response 250 // comes back (but before this target is processed) |
244 // - the outstanding request is for a non-exclusive block and this 245 // target requires an exclusive block | 251 // - this target requires an exclusive block and either we're not 252 // getting an exclusive block back or we have already snooped 253 // another read request that will downgrade our exclusive block 254 // to shared |
246 247 // assume we'd never issue a prefetch when we've got an 248 // outstanding miss 249 assert(pkt->cmd != MemCmd::HardPFReq); 250 251 if (inService && | 255 256 // assume we'd never issue a prefetch when we've got an 257 // outstanding miss 258 assert(pkt->cmd != MemCmd::HardPFReq); 259 260 if (inService && |
252 (!deferredTargets->empty() || pendingInvalidate || 253 (!targets->needsExclusive && pkt->needsExclusive()))) { | 261 (!deferredTargets->empty() || hasPostInvalidate() || 262 (pkt->needsExclusive() && 263 (!isPendingDirty() || hasPostDowngrade() || isForward)))) { |
254 // need to put on deferred list | 264 // need to put on deferred list |
265 if (hasPostInvalidate()) 266 replaceUpgrade(pkt); |
|
255 deferredTargets->add(pkt, whenReady, _order, Target::FromCPU, true); 256 } else { 257 // No request outstanding, or still OK to append to 258 // outstanding request: append to regular target list. Only 259 // mark pending if current request hasn't been issued yet 260 // (isn't in service). 261 targets->add(pkt, whenReady, _order, Target::FromCPU, !inService); 262 } --- 23 unchanged lines hidden (view full) --- 286 deferredTargets->replaceUpgrades(); 287 } 288 289 return false; 290 } 291 292 // From here on down, the request issued by this MSHR logically 293 // precedes the request we're snooping. | 267 deferredTargets->add(pkt, whenReady, _order, Target::FromCPU, true); 268 } else { 269 // No request outstanding, or still OK to append to 270 // outstanding request: append to regular target list. Only 271 // mark pending if current request hasn't been issued yet 272 // (isn't in service). 273 targets->add(pkt, whenReady, _order, Target::FromCPU, !inService); 274 } --- 23 unchanged lines hidden (view full) --- 298 deferredTargets->replaceUpgrades(); 299 } 300 301 return false; 302 } 303 304 // From here on down, the request issued by this MSHR logically 305 // precedes the request we're snooping. |
294 | |
295 if (pkt->needsExclusive()) { 296 // snooped request still precedes the re-request we'll have to 297 // issue for deferred targets, if any... 298 deferredTargets->replaceUpgrades(); 299 } 300 | 306 if (pkt->needsExclusive()) { 307 // snooped request still precedes the re-request we'll have to 308 // issue for deferred targets, if any... 309 deferredTargets->replaceUpgrades(); 310 } 311 |
301 if (pendingInvalidate) { | 312 if (hasPostInvalidate()) { |
302 // a prior snoop has already appended an invalidation, so 303 // logically we don't have the block anymore; no need for 304 // further snooping. 305 return true; 306 } 307 | 313 // a prior snoop has already appended an invalidation, so 314 // logically we don't have the block anymore; no need for 315 // further snooping. 316 return true; 317 } 318 |
308 if (targets->needsExclusive || pkt->needsExclusive()) { 309 // actual target device (typ. PhysicalMemory) will delete the 310 // packet on reception, so we need to save a copy here | 319 if (isPendingDirty() || pkt->isInvalidate()) { 320 // We need to save and replay the packet in two cases: 321 // 1. We're awaiting an exclusive copy, so ownership is pending, 322 // and we need to respond after we receive data. 323 // 2. It's an invalidation (e.g., UpgradeReq), and we need 324 // to forward the snoop up the hierarchy after the current 325 // transaction completes. 326 327 // Actual target device (typ. PhysicalMemory) will delete the 328 // packet on reception, so we need to save a copy here. |
311 PacketPtr cp_pkt = new Packet(pkt, true); 312 targets->add(cp_pkt, curTick, _order, Target::FromSnoop, 313 downstreamPending && targets->needsExclusive); 314 ++ntargets; 315 | 329 PacketPtr cp_pkt = new Packet(pkt, true); 330 targets->add(cp_pkt, curTick, _order, Target::FromSnoop, 331 downstreamPending && targets->needsExclusive); 332 ++ntargets; 333 |
316 if (targets->needsExclusive) { 317 // We're awaiting an exclusive copy, so ownership is pending. 318 // It's up to us to respond once the data arrives. | 334 if (isPendingDirty()) { |
319 pkt->assertMemInhibit(); 320 pkt->setSupplyExclusive(); | 335 pkt->assertMemInhibit(); 336 pkt->setSupplyExclusive(); |
321 } else { 322 // Someone else may respond before we get around to 323 // processing this snoop, which means the copied request 324 // pointer will no longer be valid 325 cp_pkt->req = NULL; | |
326 } 327 328 if (pkt->needsExclusive()) { 329 // This transaction will take away our pending copy | 337 } 338 339 if (pkt->needsExclusive()) { 340 // This transaction will take away our pending copy |
330 pendingInvalidate = true; | 341 postInvalidate = true; |
331 } | 342 } |
332 } else { 333 // Read to a read: no conflict, so no need to record as 334 // target, but make sure neither reader thinks he's getting an 335 // exclusive copy 336 pendingShared = true; | 343 } 344 345 if (!pkt->needsExclusive()) { 346 // This transaction will get a read-shared copy, downgrading 347 // our copy if we had an exclusive one 348 postDowngrade = true; |
337 pkt->assertShared(); 338 } 339 340 return true; 341} 342 343 344bool --- 9 unchanged lines hidden (view full) --- 354 targets = deferredTargets; 355 deferredTargets = tmp; 356 357 assert(targets->size() == ntargets); 358 359 // clear deferredTargets flags 360 deferredTargets->resetFlags(); 361 | 349 pkt->assertShared(); 350 } 351 352 return true; 353} 354 355 356bool --- 9 unchanged lines hidden (view full) --- 366 targets = deferredTargets; 367 deferredTargets = tmp; 368 369 assert(targets->size() == ntargets); 370 371 // clear deferredTargets flags 372 deferredTargets->resetFlags(); 373 |
362 pendingInvalidate = false; 363 pendingShared = false; | |
364 order = targets->front().order; 365 readyTime = std::max(curTick, targets->front().readyTime); 366 367 return true; 368} 369 370 371void 372MSHR::handleFill(Packet *pkt, CacheBlk *blk) 373{ | 374 order = targets->front().order; 375 readyTime = std::max(curTick, targets->front().readyTime); 376 377 return true; 378} 379 380 381void 382MSHR::handleFill(Packet *pkt, CacheBlk *blk) 383{ |
374 if (pendingShared) { 375 // we snooped another read while this read was in 376 // service... assert shared line on its behalf 377 pkt->assertShared(); 378 } 379 380 if (!pkt->sharedAsserted() && !pendingInvalidate | 384 if (!pkt->sharedAsserted() 385 && !(hasPostInvalidate() || hasPostDowngrade()) |
381 && deferredTargets->needsExclusive) { 382 // We got an exclusive response, but we have deferred targets 383 // which are waiting to request an exclusive copy (not because 384 // of a pending invalidate). This can happen if the original 385 // request was for a read-only (non-exclusive) block, but we 386 // got an exclusive copy anyway because of the E part of the 387 // MOESI/MESI protocol. Since we got the exclusive copy 388 // there's no need to defer the targets, so move them up to --- 33 unchanged lines hidden (view full) --- 422 ccprintf(os, "%s[%x:%x] %s %s %s state: %s %s %s %s\n", 423 prefix, addr, addr+size-1, 424 isForward ? "Forward" : "", 425 isForwardNoResponse() ? "ForwNoResp" : "", 426 needsExclusive() ? "Excl" : "", 427 _isUncacheable ? "Unc" : "", 428 inService ? "InSvc" : "", 429 downstreamPending ? "DwnPend" : "", | 386 && deferredTargets->needsExclusive) { 387 // We got an exclusive response, but we have deferred targets 388 // which are waiting to request an exclusive copy (not because 389 // of a pending invalidate). This can happen if the original 390 // request was for a read-only (non-exclusive) block, but we 391 // got an exclusive copy anyway because of the E part of the 392 // MOESI/MESI protocol. Since we got the exclusive copy 393 // there's no need to defer the targets, so move them up to --- 33 unchanged lines hidden (view full) --- 427 ccprintf(os, "%s[%x:%x] %s %s %s state: %s %s %s %s\n", 428 prefix, addr, addr+size-1, 429 isForward ? "Forward" : "", 430 isForwardNoResponse() ? "ForwNoResp" : "", 431 needsExclusive() ? "Excl" : "", 432 _isUncacheable ? "Unc" : "", 433 inService ? "InSvc" : "", 434 downstreamPending ? "DwnPend" : "", |
430 pendingInvalidate ? "PendInv" : "", 431 pendingShared ? "PendShared" : ""); | 435 hasPostInvalidate() ? "PostInv" : "", 436 hasPostDowngrade() ? "PostDowngr" : ""); |
432 433 ccprintf(os, "%s Targets:\n", prefix); 434 targets->print(os, verbosity, prefix + " "); 435 if (!deferredTargets->empty()) { 436 ccprintf(os, "%s Deferred Targets:\n", prefix); 437 deferredTargets->print(os, verbosity, prefix + " "); 438 } 439} 440 441MSHR::~MSHR() 442{ 443} | 437 438 ccprintf(os, "%s Targets:\n", prefix); 439 targets->print(os, verbosity, prefix + " "); 440 if (!deferredTargets->empty()) { 441 ccprintf(os, "%s Deferred Targets:\n", prefix); 442 deferredTargets->print(os, verbosity, prefix + " "); 443 } 444} 445 446MSHR::~MSHR() 447{ 448} |