snoop_filter.hh (11133:81e46b63daff) snoop_filter.hh (11135:9d09dab39689)
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

--- 20 unchanged lines hidden (view full) ---

29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
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

--- 20 unchanged lines hidden (view full) ---

29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Stephan Diestelhorst <stephan.diestelhorst@arm.com>
37 * Authors: Stephan Diestelhorst
38 */
39
40/**
41 * @file
42 * Definition of a snoop filter.
43 */
44
45#ifndef __MEM_SNOOP_FILTER_HH__

--- 45 unchanged lines hidden (view full) ---

91 SnoopFilter (const SnoopFilterParams *p) :
92 SimObject(p), reqLookupResult(cachedLocations.end()), retryItem{0, 0},
93 linesize(p->system->cacheLineSize()), lookupLatency(p->lookup_latency),
94 maxEntryCount(p->max_capacity / p->system->cacheLineSize())
95 {
96 }
97
98 /**
38 */
39
40/**
41 * @file
42 * Definition of a snoop filter.
43 */
44
45#ifndef __MEM_SNOOP_FILTER_HH__

--- 45 unchanged lines hidden (view full) ---

91 SnoopFilter (const SnoopFilterParams *p) :
92 SimObject(p), reqLookupResult(cachedLocations.end()), retryItem{0, 0},
93 linesize(p->system->cacheLineSize()), lookupLatency(p->lookup_latency),
94 maxEntryCount(p->max_capacity / p->system->cacheLineSize())
95 {
96 }
97
98 /**
99 * Init a new snoop filter and tell it about all the
100 * slave ports of the enclosing bus.
99 * Init a new snoop filter and tell it about all the slave ports
100 * of the enclosing bus.
101 *
102 * @param slave_ports Slave ports that the bus is attached to.
103 */
104 void setSlavePorts(const SnoopList& slave_ports) {
105 localSlavePortIds.resize(slave_ports.size(), InvalidPortID);
106
107 PortID id = 0;
108 for (const auto& p : slave_ports) {

--- 13 unchanged lines hidden (view full) ---

122 /**
123 * Lookup a request (from a slave port) in the snoop filter and
124 * return a list of other slave ports that need forwarding of the
125 * resulting snoops. Additionally, update the tracking structures
126 * with new request information. Note that the caller must also
127 * call finishRequest once it is known if the request needs to
128 * retry or not.
129 *
101 *
102 * @param slave_ports Slave ports that the bus is attached to.
103 */
104 void setSlavePorts(const SnoopList& slave_ports) {
105 localSlavePortIds.resize(slave_ports.size(), InvalidPortID);
106
107 PortID id = 0;
108 for (const auto& p : slave_ports) {

--- 13 unchanged lines hidden (view full) ---

122 /**
123 * Lookup a request (from a slave port) in the snoop filter and
124 * return a list of other slave ports that need forwarding of the
125 * resulting snoops. Additionally, update the tracking structures
126 * with new request information. Note that the caller must also
127 * call finishRequest once it is known if the request needs to
128 * retry or not.
129 *
130 * @param cpkt Pointer to the request packet. Not changed.
130 * @param cpkt Pointer to the request packet. Not changed.
131 * @param slave_port Slave port where the request came from.
132 * @return Pair of a vector of snoop target ports and lookup latency.
133 */
134 std::pair<SnoopList, Cycles> lookupRequest(const Packet* cpkt,
135 const SlavePort& slave_port);
136
137 /**
138 * For an un-successful request, revert the change to the snoop
139 * filter. Also take care of erasing any null entries. This method
140 * relies on the result from lookupRequest being stored in
141 * reqLookupResult.
142 *
143 * @param will_retry This request will retry on this bus / snoop filter
131 * @param slave_port Slave port where the request came from.
132 * @return Pair of a vector of snoop target ports and lookup latency.
133 */
134 std::pair<SnoopList, Cycles> lookupRequest(const Packet* cpkt,
135 const SlavePort& slave_port);
136
137 /**
138 * For an un-successful request, revert the change to the snoop
139 * filter. Also take care of erasing any null entries. This method
140 * relies on the result from lookupRequest being stored in
141 * reqLookupResult.
142 *
143 * @param will_retry This request will retry on this bus / snoop filter
144 * @param cpkt Request packet, merely for sanity checking
144 * @param cpkt Request packet, merely for sanity checking
145 */
146 void finishRequest(bool will_retry, const Packet* cpkt);
147
148 /**
145 */
146 void finishRequest(bool will_retry, const Packet* cpkt);
147
148 /**
149 * Handle an incoming snoop from below (the master port). These can upgrade the
150 * tracking logic and may also benefit from additional steering thanks to the
151 * snoop filter.
149 * Handle an incoming snoop from below (the master port). These
150 * can upgrade the tracking logic and may also benefit from
151 * additional steering thanks to the snoop filter.
152 *
152 * @param cpkt Pointer to const Packet containing the snoop.
153 * @return Pair with a vector of SlavePorts that need snooping and a lookup
154 * latency.
155 */
156 std::pair<SnoopList, Cycles> lookupSnoop(const Packet* cpkt);
157
158 /**
153 * @param cpkt Pointer to const Packet containing the snoop.
154 * @return Pair with a vector of SlavePorts that need snooping and a lookup
155 * latency.
156 */
157 std::pair<SnoopList, Cycles> lookupSnoop(const Packet* cpkt);
158
159 /**
159 * Let the snoop filter see any snoop responses that turn into request responses
160 * and indicate cache to cache transfers. These will update the corresponding
161 * state in the filter.
160 * Let the snoop filter see any snoop responses that turn into
161 * request responses and indicate cache to cache transfers. These
162 * will update the corresponding state in the filter.
162 *
163 * @param cpkt Pointer to const Packet holding the snoop response.
164 * @param rsp_port SlavePort that sends the response.
165 * @param req_port SlavePort that made the original request and is the
166 * destination of the snoop response.
167 */
168 void updateSnoopResponse(const Packet *cpkt, const SlavePort& rsp_port,
169 const SlavePort& req_port);
170
171 /**
163 *
164 * @param cpkt Pointer to const Packet holding the snoop response.
165 * @param rsp_port SlavePort that sends the response.
166 * @param req_port SlavePort that made the original request and is the
167 * destination of the snoop response.
168 */
169 void updateSnoopResponse(const Packet *cpkt, const SlavePort& rsp_port,
170 const SlavePort& req_port);
171
172 /**
172 * Pass snoop responses that travel downward through the snoop filter and let
173 * them update the snoop filter state. No additional routing happens.
173 * Pass snoop responses that travel downward through the snoop
174 * filter and let them update the snoop filter state. No
175 * additional routing happens.
174 *
175 * @param cpkt Pointer to const Packet holding the snoop response.
176 * @param rsp_port SlavePort that sends the response.
176 *
177 * @param cpkt Pointer to const Packet holding the snoop response.
178 * @param rsp_port SlavePort that sends the response.
177 * @param req_port MasterPort through which the response leaves this cluster.
179 * @param req_port MasterPort through which the response is forwarded.
178 */
179 void updateSnoopForward(const Packet *cpkt, const SlavePort& rsp_port,
180 const MasterPort& req_port);
181
182 /**
180 */
181 void updateSnoopForward(const Packet *cpkt, const SlavePort& rsp_port,
182 const MasterPort& req_port);
183
184 /**
183 * Update the snoop filter with a response from below (outer / other cache,
184 * or memory) and update the tracking information in the snoop filter.
185 * Update the snoop filter with a response from below (outer /
186 * other cache, or memory) and update the tracking information in
187 * the snoop filter.
185 *
186 * @param cpkt Pointer to const Packet holding the snoop response.
188 *
189 * @param cpkt Pointer to const Packet holding the snoop response.
187 * @param slave_port SlavePort that made the original request and is the target
188 * of this response.
190 * @param slave_port SlavePort that made the original request and
191 * is the target of this response.
189 */
190 void updateResponse(const Packet *cpkt, const SlavePort& slave_port);
191
192 */
193 void updateResponse(const Packet *cpkt, const SlavePort& slave_port);
194
195 virtual void regStats();
196
197 protected:
198
192 /**
199 /**
193 * Simple factory methods for standard return values for lookupRequest
200 * The underlying type for the bitmask we use for tracking. This
201 * limits the number of snooping ports supported per crossbar. For
202 * the moment it is an uint64_t to offer maximum
203 * scalability. However, it is possible to use e.g. a uint16_t or
204 * uint32_to slim down the footprint of the hash map (and
205 * ultimately improve the simulation performance).
194 */
206 */
207 typedef uint64_t SnoopMask;
208
209 /**
210 * Per cache line item tracking a bitmask of SlavePorts who have an
211 * outstanding request to this line (requested) or already share a
212 * cache line with this address (holder).
213 */
214 struct SnoopItem {
215 SnoopMask requested;
216 SnoopMask holder;
217 };
218 /**
219 * HashMap of SnoopItems indexed by line address
220 */
221 typedef m5::hash_map<Addr, SnoopItem> SnoopFilterCache;
222
223 /**
224 * Simple factory methods for standard return values.
225 */
195 std::pair<SnoopList, Cycles> snoopAll(Cycles latency) const
196 {
197 return std::make_pair(slavePorts, latency);
198 }
199 std::pair<SnoopList, Cycles> snoopSelected(const SnoopList& slave_ports,
200 Cycles latency) const
201 {
202 return std::make_pair(slave_ports, latency);
203 }
204 std::pair<SnoopList, Cycles> snoopDown(Cycles latency) const
205 {
206 SnoopList empty;
207 return std::make_pair(empty , latency);
208 }
209
226 std::pair<SnoopList, Cycles> snoopAll(Cycles latency) const
227 {
228 return std::make_pair(slavePorts, latency);
229 }
230 std::pair<SnoopList, Cycles> snoopSelected(const SnoopList& slave_ports,
231 Cycles latency) const
232 {
233 return std::make_pair(slave_ports, latency);
234 }
235 std::pair<SnoopList, Cycles> snoopDown(Cycles latency) const
236 {
237 SnoopList empty;
238 return std::make_pair(empty , latency);
239 }
240
210 virtual void regStats();
211
212 protected:
213 typedef uint64_t SnoopMask;
214 /**
215 * Per cache line item tracking a bitmask of SlavePorts who have an
216 * outstanding request to this line (requested) or already share a cache line
217 * with this address (holder).
218 */
219 struct SnoopItem {
220 SnoopMask requested;
221 SnoopMask holder;
222 };
223 /**
241 /**
224 * HashMap of SnoopItems indexed by line address
225 */
226 typedef m5::hash_map<Addr, SnoopItem> SnoopFilterCache;
227
228 /**
229 * Convert a single port to a corresponding, one-hot bitmask
230 * @param port SlavePort that should be converted.
231 * @return One-hot bitmask corresponding to the port.
232 */
233 SnoopMask portToMask(const SlavePort& port) const;
234 /**
235 * Converts a bitmask of ports into the corresponing list of ports
236 * @param ports SnoopMask of the requested ports
237 * @return SnoopList containing all the requested SlavePorts
238 */
239 SnoopList maskToPortList(SnoopMask ports) const;
240
241 private:
242
243 /**
244 * Removes snoop filter items which have no requesters and no holders.
245 */
246 void eraseIfNullEntry(SnoopFilterCache::iterator& sf_it);
242 * Convert a single port to a corresponding, one-hot bitmask
243 * @param port SlavePort that should be converted.
244 * @return One-hot bitmask corresponding to the port.
245 */
246 SnoopMask portToMask(const SlavePort& port) const;
247 /**
248 * Converts a bitmask of ports into the corresponing list of ports
249 * @param ports SnoopMask of the requested ports
250 * @return SnoopList containing all the requested SlavePorts
251 */
252 SnoopList maskToPortList(SnoopMask ports) const;
253
254 private:
255
256 /**
257 * Removes snoop filter items which have no requesters and no holders.
258 */
259 void eraseIfNullEntry(SnoopFilterCache::iterator& sf_it);
260
247 /** Simple hash set of cached addresses. */
248 SnoopFilterCache cachedLocations;
249 /**
250 * Iterator used to store the result from lookupRequest until we
251 * call finishRequest.
252 */
253 SnoopFilterCache::iterator reqLookupResult;
254 /**

--- 36 unchanged lines hidden (view full) ---

291SnoopFilter::maskToPortList(SnoopMask port_mask) const
292{
293 SnoopList res;
294 for (const auto& p : slavePorts)
295 if (port_mask & portToMask(*p))
296 res.push_back(p);
297 return res;
298}
261 /** Simple hash set of cached addresses. */
262 SnoopFilterCache cachedLocations;
263 /**
264 * Iterator used to store the result from lookupRequest until we
265 * call finishRequest.
266 */
267 SnoopFilterCache::iterator reqLookupResult;
268 /**

--- 36 unchanged lines hidden (view full) ---

305SnoopFilter::maskToPortList(SnoopMask port_mask) const
306{
307 SnoopList res;
308 for (const auto& p : slavePorts)
309 if (port_mask & portToMask(*p))
310 res.push_back(p);
311 return res;
312}
313
299#endif // __MEM_SNOOP_FILTER_HH__
314#endif // __MEM_SNOOP_FILTER_HH__