snoop_filter.cc (11199:929fd978ab4e) | snoop_filter.cc (11284:b3926db25371) |
---|---|
1/* 2 * Copyright (c) 2013-2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 94 unchanged lines hidden (view full) --- 103 __func__, sf_item.requested, sf_item.holder); 104 105 // If we are not allocating, we are done 106 if (!allocate) 107 return snoopSelected(maskToPortList(interested & ~req_port), 108 lookupLatency); 109 110 if (cpkt->needsResponse()) { | 1/* 2 * Copyright (c) 2013-2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 94 unchanged lines hidden (view full) --- 103 __func__, sf_item.requested, sf_item.holder); 104 105 // If we are not allocating, we are done 106 if (!allocate) 107 return snoopSelected(maskToPortList(interested & ~req_port), 108 lookupLatency); 109 110 if (cpkt->needsResponse()) { |
111 if (!cpkt->memInhibitAsserted()) { | 111 if (!cpkt->cacheResponding()) { |
112 // Max one request per address per port 113 panic_if(sf_item.requested & req_port, "double request :( " \ 114 "SF value %x.%x\n", sf_item.requested, sf_item.holder); 115 116 // Mark in-flight requests to distinguish later on 117 sf_item.requested |= req_port; 118 DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 119 __func__, sf_item.requested, sf_item.holder); --- 83 unchanged lines hidden (view full) --- 203 hitMultiSnoops++; 204 205 // ReadEx and Writes require both invalidation and exlusivity, while reads 206 // require neither. Writebacks on the other hand require exclusivity but 207 // not the invalidation. Previously Writebacks did not generate upward 208 // snoops so this was never an aissue. Now that Writebacks generate snoops 209 // we need to special case for Writebacks. 210 assert(cpkt->isWriteback() || cpkt->req->isUncacheable() || | 112 // Max one request per address per port 113 panic_if(sf_item.requested & req_port, "double request :( " \ 114 "SF value %x.%x\n", sf_item.requested, sf_item.holder); 115 116 // Mark in-flight requests to distinguish later on 117 sf_item.requested |= req_port; 118 DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 119 __func__, sf_item.requested, sf_item.holder); --- 83 unchanged lines hidden (view full) --- 203 hitMultiSnoops++; 204 205 // ReadEx and Writes require both invalidation and exlusivity, while reads 206 // require neither. Writebacks on the other hand require exclusivity but 207 // not the invalidation. Previously Writebacks did not generate upward 208 // snoops so this was never an aissue. Now that Writebacks generate snoops 209 // we need to special case for Writebacks. 210 assert(cpkt->isWriteback() || cpkt->req->isUncacheable() || |
211 (cpkt->isInvalidate() == cpkt->needsExclusive())); | 211 (cpkt->isInvalidate() == cpkt->needsWritable())); |
212 if (cpkt->isInvalidate() && !sf_item.requested) { 213 // Early clear of the holder, if no other request is currently going on 214 // @todo: This should possibly be updated even though we do not filter 215 // upward snoops 216 sf_item.holder = 0; 217 } 218 219 eraseIfNullEntry(sf_it); --- 8 unchanged lines hidden (view full) --- 228 const SlavePort& rsp_port, 229 const SlavePort& req_port) 230{ 231 DPRINTF(SnoopFilter, "%s: packet rsp %s req %s addr 0x%x cmd %s\n", 232 __func__, rsp_port.name(), req_port.name(), cpkt->getAddr(), 233 cpkt->cmdString()); 234 235 assert(cpkt->isResponse()); | 212 if (cpkt->isInvalidate() && !sf_item.requested) { 213 // Early clear of the holder, if no other request is currently going on 214 // @todo: This should possibly be updated even though we do not filter 215 // upward snoops 216 sf_item.holder = 0; 217 } 218 219 eraseIfNullEntry(sf_it); --- 8 unchanged lines hidden (view full) --- 228 const SlavePort& rsp_port, 229 const SlavePort& req_port) 230{ 231 DPRINTF(SnoopFilter, "%s: packet rsp %s req %s addr 0x%x cmd %s\n", 232 __func__, rsp_port.name(), req_port.name(), cpkt->getAddr(), 233 cpkt->cmdString()); 234 235 assert(cpkt->isResponse()); |
236 assert(cpkt->memInhibitAsserted()); | 236 assert(cpkt->cacheResponding()); |
237 238 // Ultimately we should check if the packet came from an 239 // allocating source, not just if the port is snooping 240 bool allocate = !cpkt->req->isUncacheable() && req_port.isSnooping(); 241 if (!allocate) 242 return; 243 244 Addr line_addr = cpkt->getBlockAddr(linesize); --- 8 unchanged lines hidden (view full) --- 253 panic_if(!(sf_item.holder & rsp_mask), "SF value %x.%x does not have "\ 254 "the line\n", sf_item.requested, sf_item.holder); 255 256 // The destination should have had a request in 257 panic_if(!(sf_item.requested & req_mask), "SF value %x.%x missing "\ 258 "the original request\n", sf_item.requested, sf_item.holder); 259 260 // Update the residency of the cache line. | 237 238 // Ultimately we should check if the packet came from an 239 // allocating source, not just if the port is snooping 240 bool allocate = !cpkt->req->isUncacheable() && req_port.isSnooping(); 241 if (!allocate) 242 return; 243 244 Addr line_addr = cpkt->getBlockAddr(linesize); --- 8 unchanged lines hidden (view full) --- 253 panic_if(!(sf_item.holder & rsp_mask), "SF value %x.%x does not have "\ 254 "the line\n", sf_item.requested, sf_item.holder); 255 256 // The destination should have had a request in 257 panic_if(!(sf_item.requested & req_mask), "SF value %x.%x missing "\ 258 "the original request\n", sf_item.requested, sf_item.holder); 259 260 // Update the residency of the cache line. |
261 if (cpkt->needsExclusive() || !cpkt->sharedAsserted()) { 262 DPRINTF(SnoopFilter, "%s: dropping %x because needs: %i shared: %i "\ | 261 if (cpkt->needsWritable() || !cpkt->hasSharers()) { 262 DPRINTF(SnoopFilter, "%s: dropping %x because needs: %i writable: %i "\ |
263 "SF val: %x.%x\n", __func__, rsp_mask, | 263 "SF val: %x.%x\n", __func__, rsp_mask, |
264 cpkt->needsExclusive(), cpkt->sharedAsserted(), | 264 cpkt->needsWritable(), !cpkt->hasSharers(), |
265 sf_item.requested, sf_item.holder); 266 267 sf_item.holder &= ~rsp_mask; 268 // The snoop filter does not see any ACKs from non-responding sharers 269 // that have been invalidated :( So below assert would be nice, but.. 270 //assert(sf_item.holder == 0); 271 sf_item.holder = 0; 272 } --- 9 unchanged lines hidden (view full) --- 282SnoopFilter::updateSnoopForward(const Packet* cpkt, 283 const SlavePort& rsp_port, const MasterPort& req_port) 284{ 285 DPRINTF(SnoopFilter, "%s: packet rsp %s req %s addr 0x%x cmd %s\n", 286 __func__, rsp_port.name(), req_port.name(), cpkt->getAddr(), 287 cpkt->cmdString()); 288 289 assert(cpkt->isResponse()); | 265 sf_item.requested, sf_item.holder); 266 267 sf_item.holder &= ~rsp_mask; 268 // The snoop filter does not see any ACKs from non-responding sharers 269 // that have been invalidated :( So below assert would be nice, but.. 270 //assert(sf_item.holder == 0); 271 sf_item.holder = 0; 272 } --- 9 unchanged lines hidden (view full) --- 282SnoopFilter::updateSnoopForward(const Packet* cpkt, 283 const SlavePort& rsp_port, const MasterPort& req_port) 284{ 285 DPRINTF(SnoopFilter, "%s: packet rsp %s req %s addr 0x%x cmd %s\n", 286 __func__, rsp_port.name(), req_port.name(), cpkt->getAddr(), 287 cpkt->cmdString()); 288 289 assert(cpkt->isResponse()); |
290 assert(cpkt->memInhibitAsserted()); | 290 assert(cpkt->cacheResponding()); |
291 292 Addr line_addr = cpkt->getBlockAddr(linesize); 293 auto sf_it = cachedLocations.find(line_addr); 294 bool is_hit = sf_it != cachedLocations.end(); 295 296 // Nothing to do if it is not a hit 297 if (!is_hit) 298 return; 299 300 SnoopItem& sf_item = sf_it->second; 301 302 DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 303 __func__, sf_item.requested, sf_item.holder); 304 305 // Remote (to this snoop filter) snoops update the filter 306 // already when they arrive from below, because we may not see 307 // any response. | 291 292 Addr line_addr = cpkt->getBlockAddr(linesize); 293 auto sf_it = cachedLocations.find(line_addr); 294 bool is_hit = sf_it != cachedLocations.end(); 295 296 // Nothing to do if it is not a hit 297 if (!is_hit) 298 return; 299 300 SnoopItem& sf_item = sf_it->second; 301 302 DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 303 __func__, sf_item.requested, sf_item.holder); 304 305 // Remote (to this snoop filter) snoops update the filter 306 // already when they arrive from below, because we may not see 307 // any response. |
308 if (cpkt->needsExclusive()) { | 308 if (cpkt->needsWritable()) { |
309 // If the request to this snoop response hit an in-flight 310 // transaction, 311 // the holder was not reset -> no assertion & do that here, now! 312 //assert(sf_item.holder == 0); 313 sf_item.holder = 0; 314 } 315 DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 316 __func__, sf_item.requested, sf_item.holder); --- 23 unchanged lines hidden (view full) --- 340 __func__, sf_item.requested, sf_item.holder); 341 342 // Make sure we have seen the actual request, too 343 panic_if(!(sf_item.requested & slave_mask), "SF value %x.%x missing "\ 344 "request bit\n", sf_item.requested, sf_item.holder); 345 346 // Update the residency of the cache line. Here we assume that the 347 // line has been zapped in all caches that are not the responder. | 309 // If the request to this snoop response hit an in-flight 310 // transaction, 311 // the holder was not reset -> no assertion & do that here, now! 312 //assert(sf_item.holder == 0); 313 sf_item.holder = 0; 314 } 315 DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 316 __func__, sf_item.requested, sf_item.holder); --- 23 unchanged lines hidden (view full) --- 340 __func__, sf_item.requested, sf_item.holder); 341 342 // Make sure we have seen the actual request, too 343 panic_if(!(sf_item.requested & slave_mask), "SF value %x.%x missing "\ 344 "request bit\n", sf_item.requested, sf_item.holder); 345 346 // Update the residency of the cache line. Here we assume that the 347 // line has been zapped in all caches that are not the responder. |
348 if (cpkt->needsExclusive() || !cpkt->sharedAsserted()) | 348 if (cpkt->needsWritable() || !cpkt->hasSharers()) |
349 sf_item.holder = 0; 350 sf_item.holder |= slave_mask; 351 sf_item.requested &= ~slave_mask; 352 assert(sf_item.holder | sf_item.requested); 353 DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 354 __func__, sf_item.requested, sf_item.holder); 355} 356 --- 37 unchanged lines hidden --- | 349 sf_item.holder = 0; 350 sf_item.holder |= slave_mask; 351 sf_item.requested &= ~slave_mask; 352 assert(sf_item.holder | sf_item.requested); 353 DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 354 __func__, sf_item.requested, sf_item.holder); 355} 356 --- 37 unchanged lines hidden --- |