Rev 763 | Rev 765 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 763 | Rev 764 | ||
|---|---|---|---|
| Line 67... | Line 67... | ||
| 67 | slab_t *slab; |
67 | slab_t *slab; |
| 68 | size_t fsize; |
68 | size_t fsize; |
| 69 | int i; |
69 | int i; |
| 70 | zone_t *zone = NULL; |
70 | zone_t *zone = NULL; |
| 71 | int status; |
71 | int status; |
| - | 72 | frame_t *frame; |
|
| 72 | 73 | ||
| 73 | data = (void *)frame_alloc(FRAME_KA | flags, cache->order, &status, &zone); |
74 | data = (void *)frame_alloc(FRAME_KA | flags, cache->order, &status, &zone); |
| 74 | if (status != FRAME_OK) |
75 | if (status != FRAME_OK) { |
| 75 | return NULL; |
76 | return NULL; |
| 76 | 77 | } |
|
| 77 | if (! cache->flags & SLAB_CACHE_SLINSIDE) { |
78 | if (! cache->flags & SLAB_CACHE_SLINSIDE) { |
| 78 | slab = malloc(sizeof(*slab)); // , flags); |
79 | slab = malloc(sizeof(*slab)); // , flags); |
| 79 | if (!slab) { |
80 | if (!slab) { |
| 80 | frame_free((__address)data); |
81 | frame_free((__address)data); |
| 81 | return NULL; |
82 | return NULL; |
| 82 | } |
83 | } |
| 83 | } else { |
84 | } else { |
| 84 | fsize = (PAGE_SIZE << cache->order); |
85 | fsize = (PAGE_SIZE << cache->order); |
| 85 | slab = data + fsize - sizeof(*slab); |
86 | slab = data + fsize - sizeof(*slab); |
| 86 | } |
87 | } |
| 87 | 88 | ||
| 88 | /* Fill in slab structures */ |
89 | /* Fill in slab structures */ |
| 89 | /* TODO: some better way of accessing the frame */ |
90 | /* TODO: some better way of accessing the frame */ |
| 90 | for (i=0; i< (1<<cache->order); i++) { |
91 | for (i=0; i< (1<<cache->order); i++) { |
| 91 | ADDR2FRAME(zone, (__address)(data+i*PAGE_SIZE))->parent = slab; |
92 | frame = ADDR2FRAME(zone, KA2PA((__address)(data+i*PAGE_SIZE))); |
| - | 93 | frame->parent = slab; |
|
| 92 | } |
94 | } |
| 93 | 95 | ||
| 94 | slab->start = data; |
96 | slab->start = data; |
| 95 | slab->available = cache->objects; |
97 | slab->available = cache->objects; |
| 96 | slab->nextavail = 0; |
98 | slab->nextavail = 0; |
| 97 | 99 | ||
| 98 | for (i=0; i<cache->objects;i++) |
100 | for (i=0; i<cache->objects;i++) |
| 99 | *((int *) (slab->start + i*cache->size)) = i+1; |
101 | *((int *) (slab->start + i*cache->size)) = i+1; |
| - | 102 | ||
| - | 103 | atomic_inc(&cache->allocated_slabs); |
|
| - | 104 | ||
| 100 | return slab; |
105 | return slab; |
| 101 | } |
106 | } |
| 102 | 107 | ||
| 103 | /** |
108 | /** |
| 104 | * Free space associated with SLAB |
109 | * Free space associated with SLAB |
| Line 108... | Line 113... | ||
| 108 | static count_t slab_space_free(slab_cache_t *cache, slab_t *slab) |
113 | static count_t slab_space_free(slab_cache_t *cache, slab_t *slab) |
| 109 | { |
114 | { |
| 110 | frame_free((__address)slab->start); |
115 | frame_free((__address)slab->start); |
| 111 | if (! cache->flags & SLAB_CACHE_SLINSIDE) |
116 | if (! cache->flags & SLAB_CACHE_SLINSIDE) |
| 112 | free(slab); |
117 | free(slab); |
| - | 118 | ||
| - | 119 | atomic_dec(&cache->allocated_slabs); |
|
| - | 120 | ||
| 113 | return 1 << cache->order; |
121 | return 1 << cache->order; |
| 114 | } |
122 | } |
| 115 | 123 | ||
| 116 | /** Map object to slab structure */ |
124 | /** Map object to slab structure */ |
| 117 | static slab_t * obj2slab(void *obj) |
125 | static slab_t * obj2slab(void *obj) |
| Line 151... | Line 159... | ||
| 151 | 159 | ||
| 152 | /* Move it to correct list */ |
160 | /* Move it to correct list */ |
| 153 | if (slab->available == 1) { |
161 | if (slab->available == 1) { |
| 154 | /* It was in full, move to partial */ |
162 | /* It was in full, move to partial */ |
| 155 | list_remove(&slab->link); |
163 | list_remove(&slab->link); |
| 156 | list_prepend(&cache->partial_slabs, &slab->link); |
164 | list_prepend(&slab->link, &cache->partial_slabs); |
| 157 | } |
165 | } |
| 158 | if (slab->available == cache->objects) { |
166 | if (slab->available == cache->objects) { |
| 159 | /* Free associated memory */ |
167 | /* Free associated memory */ |
| 160 | list_remove(&slab->link); |
168 | list_remove(&slab->link); |
| 161 | /* Avoid deadlock */ |
169 | /* Avoid deadlock */ |
| Line 189... | Line 197... | ||
| 189 | * that's why we should get recursion at most 1-level deep |
197 | * that's why we should get recursion at most 1-level deep |
| 190 | */ |
198 | */ |
| 191 | spinlock_unlock(&cache->lock); |
199 | spinlock_unlock(&cache->lock); |
| 192 | slab = slab_space_alloc(cache, flags); |
200 | slab = slab_space_alloc(cache, flags); |
| 193 | spinlock_lock(&cache->lock); |
201 | spinlock_lock(&cache->lock); |
| 194 | if (!slab) |
202 | if (!slab) { |
| 195 | return NULL; |
203 | return NULL; |
| - | 204 | } |
|
| 196 | } else { |
205 | } else { |
| 197 | slab = list_get_instance(cache->partial_slabs.next, |
206 | slab = list_get_instance(cache->partial_slabs.next, |
| 198 | slab_t, |
207 | slab_t, |
| 199 | link); |
208 | link); |
| 200 | list_remove(&slab->link); |
209 | list_remove(&slab->link); |
| 201 | } |
210 | } |
| 202 | obj = slab->start + slab->nextavail * cache->size; |
211 | obj = slab->start + slab->nextavail * cache->size; |
| 203 | slab->nextavail = *((int *)obj); |
212 | slab->nextavail = *((int *)obj); |
| 204 | slab->available--; |
213 | slab->available--; |
| 205 | if (! slab->available) |
214 | if (! slab->available) |
| 206 | list_prepend(&cache->full_slabs, &slab->link); |
215 | list_prepend(&slab->link, &cache->full_slabs); |
| 207 | else |
216 | else |
| 208 | list_prepend(&cache->partial_slabs, &slab->link); |
217 | list_prepend(&slab->link, &cache->partial_slabs); |
| 209 | return obj; |
218 | return obj; |
| 210 | } |
219 | } |
| 211 | 220 | ||
| 212 | /**************************************/ |
221 | /**************************************/ |
| 213 | /* CPU-Cache slab functions */ |
222 | /* CPU-Cache slab functions */ |
| Line 313... | Line 322... | ||
| 313 | } else if (mag->busy == mag->size) { |
322 | } else if (mag->busy == mag->size) { |
| 314 | /* If the last is full | empty, allocate new */ |
323 | /* If the last is full | empty, allocate new */ |
| 315 | mag = cache->mag_cache[CPU->id].last; |
324 | mag = cache->mag_cache[CPU->id].last; |
| 316 | if (!mag || mag->size == mag->busy) { |
325 | if (!mag || mag->size == mag->busy) { |
| 317 | if (mag) |
326 | if (mag) |
| 318 | list_prepend(&cache->magazines, &mag->link); |
327 | list_prepend(&mag->link, &cache->magazines); |
| 319 | 328 | ||
| 320 | mag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM); |
329 | mag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM); |
| 321 | if (!mag) |
330 | if (!mag) |
| 322 | goto errout; |
331 | goto errout; |
| 323 | 332 | ||
| Line 531... | Line 540... | ||
| 531 | spinlock_lock(&cache->lock); |
540 | spinlock_lock(&cache->lock); |
| 532 | result = slab_obj_create(cache, flags); |
541 | result = slab_obj_create(cache, flags); |
| 533 | spinlock_unlock(&cache->lock); |
542 | spinlock_unlock(&cache->lock); |
| 534 | } |
543 | } |
| 535 | 544 | ||
| - | 545 | if (result) |
|
| - | 546 | atomic_inc(&cache->allocated_objs); |
|
| - | 547 | ||
| 536 | interrupts_restore(ipl); |
548 | interrupts_restore(ipl); |
| 537 | 549 | ||
| - | 550 | ||
| 538 | return result; |
551 | return result; |
| 539 | } |
552 | } |
| 540 | 553 | ||
| 541 | /** Return object to cache */ |
554 | /** Return object to cache */ |
| 542 | void slab_free(slab_cache_t *cache, void *obj) |
555 | void slab_free(slab_cache_t *cache, void *obj) |
| Line 550... | Line 563... | ||
| 550 | 563 | ||
| 551 | spinlock_lock(&cache->lock); |
564 | spinlock_lock(&cache->lock); |
| 552 | slab_obj_destroy(cache, obj, NULL); |
565 | slab_obj_destroy(cache, obj, NULL); |
| 553 | spinlock_unlock(&cache->lock); |
566 | spinlock_unlock(&cache->lock); |
| 554 | } |
567 | } |
| - | 568 | atomic_dec(&cache->allocated_objs); |
|
| 555 | interrupts_restore(ipl); |
569 | interrupts_restore(ipl); |
| 556 | } |
570 | } |
| 557 | 571 | ||
| 558 | /* Go through all caches and reclaim what is possible */ |
572 | /* Go through all caches and reclaim what is possible */ |
| 559 | count_t slab_reclaim(int flags) |
573 | count_t slab_reclaim(int flags) |
| Line 580... | Line 594... | ||
| 580 | { |
594 | { |
| 581 | slab_cache_t *cache; |
595 | slab_cache_t *cache; |
| 582 | link_t *cur; |
596 | link_t *cur; |
| 583 | 597 | ||
| 584 | spinlock_lock(&slab_cache_lock); |
598 | spinlock_lock(&slab_cache_lock); |
| 585 | printf("SLAB name\tOsize\tOrder\n"); |
599 | printf("SLAB name\tOsize\tOrder\tOcnt\tSlabs\tAllocobjs\n"); |
| 586 | for (cur = slab_cache_list.next;cur!=&slab_cache_list; cur=cur->next) { |
600 | for (cur = slab_cache_list.next;cur!=&slab_cache_list; cur=cur->next) { |
| 587 | cache = list_get_instance(cur, slab_cache_t, link); |
601 | cache = list_get_instance(cur, slab_cache_t, link); |
| 588 | printf("%s\t%d\t%d\n", cache->name, cache->size, cache->order); |
602 | printf("%s\t%d\t%d\t%d\t%d\t%d\n", cache->name, cache->size, |
| - | 603 | cache->order, cache->objects, |
|
| - | 604 | atomic_get(&cache->allocated_slabs), |
|
| - | 605 | atomic_get(&cache->allocated_objs)); |
|
| 589 | } |
606 | } |
| 590 | spinlock_unlock(&slab_cache_lock); |
607 | spinlock_unlock(&slab_cache_lock); |
| 591 | } |
608 | } |
| 592 | 609 | ||
| 593 | void slab_cache_init(void) |
610 | void slab_cache_init(void) |