Rev 3206 | Rev 3208 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3206 | Rev 3207 | ||
---|---|---|---|
Line 198... | Line 198... | ||
198 | interrupts_restore(ipl); |
198 | interrupts_restore(ipl); |
199 | 199 | ||
200 | return i; |
200 | return i; |
201 | } |
201 | } |
202 | 202 | ||
203 | /** |
- | |
204 | * Try to find a zone where can we find the frame. |
203 | /** Try to find a zone where can we find the frame. |
205 | * |
204 | * |
206 | * Assume interrupts are disabled. |
205 | * Assume interrupts are disabled. |
207 | * |
206 | * |
208 | * @param frame Frame number contained in zone. |
207 | * @param frame Frame number contained in zone. |
209 | * @param pzone If not null, it is used as zone hint. Zone index is |
208 | * @param pzone If not null, it is used as zone hint. Zone index is |
Line 235... | Line 234... | ||
235 | spinlock_unlock(&z->lock); |
234 | spinlock_unlock(&z->lock); |
236 | 235 | ||
237 | i++; |
236 | i++; |
238 | if (i >= zones.count) |
237 | if (i >= zones.count) |
239 | i = 0; |
238 | i = 0; |
240 | } while(i != hint); |
239 | } while (i != hint); |
241 | 240 | ||
242 | spinlock_unlock(&zones.lock); |
241 | spinlock_unlock(&zones.lock); |
243 | return NULL; |
242 | return NULL; |
244 | } |
243 | } |
245 | 244 | ||
Line 252... | Line 251... | ||
252 | /** Find and lock zone that can allocate order frames. |
251 | /** Find and lock zone that can allocate order frames. |
253 | * |
252 | * |
254 | * Assume interrupts are disabled. |
253 | * Assume interrupts are disabled. |
255 | * |
254 | * |
256 | * @param order Size (2^order) of free space we are trying to find. |
255 | * @param order Size (2^order) of free space we are trying to find. |
- | 256 | * @param flags Required flags of the target zone. |
|
257 | * @param pzone Pointer to preferred zone or NULL, on return contains |
257 | * @param pzone Pointer to preferred zone or NULL, on return contains |
258 | * zone number. |
258 | * zone number. |
259 | */ |
259 | */ |
- | 260 | static zone_t * |
|
260 | static zone_t *find_free_zone_and_lock(uint8_t order, unsigned int *pzone) |
261 | find_free_zone_and_lock(uint8_t order, int flags, unsigned int *pzone) |
261 | { |
262 | { |
262 | unsigned int i; |
263 | unsigned int i; |
263 | zone_t *z; |
264 | zone_t *z; |
264 | unsigned int hint = pzone ? *pzone : 0; |
265 | unsigned int hint = pzone ? *pzone : 0; |
265 | 266 | ||
- | 267 | /* Mask off flags that are not applicable. */ |
|
- | 268 | flags &= FRAME_LOW_16_GiB; |
|
- | 269 | ||
266 | spinlock_lock(&zones.lock); |
270 | spinlock_lock(&zones.lock); |
267 | if (hint >= zones.count) |
271 | if (hint >= zones.count) |
268 | hint = 0; |
272 | hint = 0; |
269 | i = hint; |
273 | i = hint; |
270 | do { |
274 | do { |
271 | z = zones.info[i]; |
275 | z = zones.info[i]; |
272 | 276 | ||
273 | spinlock_lock(&z->lock); |
277 | spinlock_lock(&z->lock); |
274 | 278 | ||
- | 279 | /* |
|
- | 280 | * Check whether the zone meets the search criteria. |
|
- | 281 | */ |
|
- | 282 | if ((z->flags & flags) == flags) { |
|
- | 283 | /* |
|
275 | /* Check if the zone has 2^order frames area available */ |
284 | * Check if the zone has 2^order frames area available. |
- | 285 | */ |
|
276 | if (zone_can_alloc(z, order)) { |
286 | if (zone_can_alloc(z, order)) { |
277 | spinlock_unlock(&zones.lock); |
287 | spinlock_unlock(&zones.lock); |
278 | if (pzone) |
288 | if (pzone) |
279 | *pzone = i; |
289 | *pzone = i; |
280 | return z; |
290 | return z; |
- | 291 | } |
|
281 | } |
292 | } |
282 | spinlock_unlock(&z->lock); |
293 | spinlock_unlock(&z->lock); |
283 | if (++i >= zones.count) |
294 | if (++i >= zones.count) |
284 | i = 0; |
295 | i = 0; |
285 | } while(i != hint); |
296 | } while (i != hint); |
286 | spinlock_unlock(&zones.lock); |
297 | spinlock_unlock(&zones.lock); |
287 | return NULL; |
298 | return NULL; |
288 | } |
299 | } |
289 | 300 | ||
290 | /**************************/ |
301 | /**************************/ |
Line 808... | Line 819... | ||
808 | uint8_t max_order; |
819 | uint8_t max_order; |
809 | 820 | ||
810 | spinlock_initialize(&z->lock, "zone_lock"); |
821 | spinlock_initialize(&z->lock, "zone_lock"); |
811 | z->base = start; |
822 | z->base = start; |
812 | z->count = count; |
823 | z->count = count; |
- | 824 | ||
- | 825 | /* Mask off flags that are calculated automatically. */ |
|
- | 826 | flags &= ~FRAME_LOW_16_GiB; |
|
- | 827 | /* Determine calculated flags. */ |
|
- | 828 | if (z->base + count < (1ULL << (34 - FRAME_WIDTH))) /* 16 GiB */ |
|
- | 829 | flags |= FRAME_LOW_16_GiB; |
|
- | 830 | ||
813 | z->flags = flags; |
831 | z->flags = flags; |
- | 832 | ||
814 | z->free_count = count; |
833 | z->free_count = count; |
815 | z->busy_count = 0; |
834 | z->busy_count = 0; |
816 | 835 | ||
817 | /* |
836 | /* |
818 | * Compute order for buddy system, initialize |
837 | * Compute order for buddy system, initialize |
Line 980... | Line 999... | ||
980 | ipl = interrupts_disable(); |
999 | ipl = interrupts_disable(); |
981 | 1000 | ||
982 | /* |
1001 | /* |
983 | * First, find suitable frame zone. |
1002 | * First, find suitable frame zone. |
984 | */ |
1003 | */ |
985 | zone = find_free_zone_and_lock(order, pzone); |
1004 | zone = find_free_zone_and_lock(order, flags, pzone); |
986 | 1005 | ||
987 | /* If no memory, reclaim some slab memory, |
1006 | /* If no memory, reclaim some slab memory, |
988 | if it does not help, reclaim all */ |
1007 | if it does not help, reclaim all */ |
989 | if (!zone && !(flags & FRAME_NO_RECLAIM)) { |
1008 | if (!zone && !(flags & FRAME_NO_RECLAIM)) { |
990 | freed = slab_reclaim(0); |
1009 | freed = slab_reclaim(0); |
991 | if (freed) |
1010 | if (freed) |
992 | zone = find_free_zone_and_lock(order, pzone); |
1011 | zone = find_free_zone_and_lock(order, flags, pzone); |
993 | if (!zone) { |
1012 | if (!zone) { |
994 | freed = slab_reclaim(SLAB_RECLAIM_ALL); |
1013 | freed = slab_reclaim(SLAB_RECLAIM_ALL); |
995 | if (freed) |
1014 | if (freed) |
996 | zone = find_free_zone_and_lock(order, pzone); |
1015 | zone = find_free_zone_and_lock(order, flags, |
- | 1016 | pzone); |
|
997 | } |
1017 | } |
998 | } |
1018 | } |
999 | if (!zone) { |
1019 | if (!zone) { |
1000 | /* |
1020 | /* |
1001 | * Sleep until some frames are available again. |
1021 | * Sleep until some frames are available again. |