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 ---