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