Changeset 086a600 in mainline


Ignore:
Timestamp:
2006-02-02T23:54:42Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fb10289b
Parents:
4a5b2b0e
Message:

Debugged slab allocator. It currently supports per-CPU cache on 1 cpu.

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • generic/src/mm/frame.c

    r4a5b2b0e r086a600  
    116116        zone_t *zone = NULL;
    117117        frame_t *frame = NULL;
     118        int freed;
    118119        __address v;
    119120       
     
    136137                /* If no memory, reclaim some slab memory,
    137138                   if it does not help, reclaim all */
    138                 if (!zone && !(flags & FRAME_NO_RECLAIM))
    139                         if (slab_reclaim(0) || slab_reclaim(SLAB_RECLAIM_ALL))
     139                if (!zone && !(flags & FRAME_NO_RECLAIM)) {
     140                        spinlock_unlock(&zone_head_lock);
     141                        freed = slab_reclaim(0);
     142                        spinlock_lock(&zone_head_lock);
     143                        if (freed)
    140144                                zone = find_free_zone(order);
     145                        if (!zone) {
     146                                spinlock_unlock(&zone_head_lock);
     147                                freed = slab_reclaim(SLAB_RECLAIM_ALL);
     148                                spinlock_lock(&zone_head_lock);
     149                                if (freed)
     150                                        zone = find_free_zone(order);
     151                        }
     152                }
    141153        }
    142154
  • generic/src/mm/slab.c

    r4a5b2b0e r086a600  
    7676                return NULL;
    7777        }
    78         if (! cache->flags & SLAB_CACHE_SLINSIDE) {
     78        if (! (cache->flags & SLAB_CACHE_SLINSIDE)) {
    7979                slab = malloc(sizeof(*slab)); // , flags);
    8080                if (!slab) {
     
    103103
    104104        atomic_inc(&cache->allocated_slabs);
    105 
    106105        return slab;
    107106}
     
    115114{
    116115        frame_free((__address)slab->start);
    117         if (! cache->flags & SLAB_CACHE_SLINSIDE)
     116        if (! (cache->flags & SLAB_CACHE_SLINSIDE))
    118117                free(slab);
    119118
     
    278277                /* Free current magazine and take one from list */
    279278                slab_free(&mag_cache, mag);
     279
    280280                mag = list_get_instance(cache->magazines.next,
    281281                                        slab_magazine_t,
     
    297297
    298298/**
    299  * Put object into CPU-cache magazine
     299 * Assure that the current magazine is empty, return pointer to it, or NULL if
     300 * no empty magazine available and cannot be allocated
    300301 *
    301302 * We have 2 magazines bound to processor.
     
    305306 *   allocate new, exchange last & current
    306307 *
     308 */
     309static slab_magazine_t * make_empty_current_mag(slab_cache_t *cache)
     310{
     311        slab_magazine_t *cmag,*lastmag,*newmag;
     312
     313        cmag = cache->mag_cache[CPU->id].current;
     314        lastmag = cache->mag_cache[CPU->id].last;
     315
     316        if (cmag) {
     317                if (cmag->busy < cmag->size)
     318                        return cmag;
     319                if (lastmag && lastmag->busy < lastmag->size) {
     320                        cache->mag_cache[CPU->id].last = cmag;
     321                        cache->mag_cache[CPU->id].current = lastmag;
     322                        return lastmag;
     323                }
     324        }
     325        /* current | last are full | nonexistent, allocate new */
     326        /* We do not want to sleep just because of caching */
     327        /* Especially we do not want reclaiming to start, as
     328         * this would deadlock */
     329        newmag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM);
     330        if (!newmag)
     331                return NULL;
     332        newmag->size = SLAB_MAG_SIZE;
     333        newmag->busy = 0;
     334
     335        /* Flush last to magazine list */
     336        if (lastmag)
     337                list_prepend(&lastmag->link, &cache->magazines);
     338        /* Move current as last, save new as current */
     339        cache->mag_cache[CPU->id].last = cmag; 
     340        cache->mag_cache[CPU->id].current = newmag;     
     341
     342        return newmag;
     343}
     344
     345/**
     346 * Put object into CPU-cache magazine
     347 *
    307348 * @return 0 - success, -1 - could not get memory
    308349 */
     
    312353
    313354        spinlock_lock(&cache->mag_cache[CPU->id].lock);
    314        
    315         mag = cache->mag_cache[CPU->id].current;
    316         if (!mag) {
    317                 /* We do not want to sleep just because of caching */
    318                 /* Especially we do not want reclaiming to start, as
    319                  * this would deadlock */
    320                 mag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM);
    321                 if (!mag) /* Allocation failed, give up on caching */
    322                         goto errout;
    323 
    324                 cache->mag_cache[CPU->id].current = mag;
    325                 mag->size = SLAB_MAG_SIZE;
    326                 mag->busy = 0;
    327         } else if (mag->busy == mag->size) {
    328                 /* If the last is full | empty, allocate new */
    329                 mag = cache->mag_cache[CPU->id].last;
    330                 if (!mag || mag->size == mag->busy) {
    331                         if (mag)
    332                                 list_prepend(&mag->link, &cache->magazines);
    333 
    334                         mag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM);
    335                         if (!mag)
    336                                 goto errout;
    337                        
    338                         mag->size = SLAB_MAG_SIZE;
    339                         mag->busy = 0;
    340                         cache->mag_cache[CPU->id].last = mag;
    341                 }
    342                 /* Exchange the 2 */
    343                 cache->mag_cache[CPU->id].last = cache->mag_cache[CPU->id].current;
    344                 cache->mag_cache[CPU->id].current = mag;
    345         }
     355
     356        mag = make_empty_current_mag(cache);
     357        if (!mag)
     358                goto errout;
     359       
    346360        mag->objs[mag->busy++] = obj;
    347361
     
    409423        list_initialize(&cache->magazines);
    410424        spinlock_initialize(&cache->lock, "cachelock");
    411         if (! cache->flags & SLAB_CACHE_NOMAGAZINE) {
     425        if (! (cache->flags & SLAB_CACHE_NOMAGAZINE)) {
    412426                for (i=0; i< config.cpu_count; i++)
    413427                        spinlock_initialize(&cache->mag_cache[i].lock,
     
    458472 * @param flags If contains SLAB_RECLAIM_ALL, do aggressive freeing
    459473 * @return Number of freed pages
    460  *
    461  * TODO: Add light reclaim
    462474 */
    463475static count_t _slab_reclaim(slab_cache_t *cache, int flags)
     
    494506        cur=cache->magazines.prev;
    495507
    496         while (cur!=&cache->magazines) {
     508        while (cur != &cache->magazines) {
    497509                mag = list_get_instance(cur, slab_magazine_t, link);
    498510               
    499511                cur = cur->prev;
    500                 list_remove(cur->next);
    501 //              list_remove(&mag->link);
     512                list_remove(&mag->link);
    502513                frames += magazine_destroy(cache,mag);
    503514                /* If we do not do full reclaim, break
     
    545556        ipl = interrupts_disable();
    546557       
    547         if (!cache->flags & SLAB_CACHE_NOMAGAZINE)
     558        if (!(cache->flags & SLAB_CACHE_NOMAGAZINE))
    548559                result = magazine_obj_get(cache);
    549560
  • test/mm/slab1/test.c

    r4a5b2b0e r086a600  
    3333#include <arch.h>
    3434#include <panic.h>
     35#include <memstr.h>
    3536
    3637#define VAL_COUNT   1024
     
    5152        for (i=0; i < count; i++) {
    5253                data[i] = slab_alloc(cache, 0);
     54                memsetb((__address)data[i], size, 0);
    5355        }
    5456        printf("done.\n");
     
    6264        for (i=0; i < count; i++) {
    6365                data[i] = slab_alloc(cache, 0);
     66                memsetb((__address)data[i], size, 0);
    6467        }
    6568        printf("done.\n");
     
    7578        for (i=count/2; i < count; i++) {
    7679                data[i] = slab_alloc(cache, 0);
     80                memsetb((__address)data[i], size, 0);
    7781        }
    7882        printf("done.\n");
  • test/mm/slab2/test.c

    r4a5b2b0e r086a600  
    3434#include <panic.h>
    3535#include <mm/frame.h>
     36#include <memstr.h>
    3637
    3738#define ITEM_SIZE 256
     
    6566                        break;
    6667                }
    67 
     68                memsetb((__address)data1, ITEM_SIZE, 0);
     69                memsetb((__address)data2, ITEM_SIZE, 0);
    6870                *((void **)data1) = olddata1;
    6971                *((void **)data2) = olddata2;
     
    8991                        panic("Incorrect memory size - use another test.");
    9092                }
     93                memsetb((__address)data1, ITEM_SIZE, 0);
    9194                *((void **)data1) = olddata1;
    9295                olddata1 = data1;
     
    98101                        break;
    99102                }
     103                memsetb((__address)data1, ITEM_SIZE, 0);
    100104                *((void **)data1) = olddata1;
    101105                olddata1 = data1;
    102106        }
    103107        slab_print_list();
    104        
     108        printf("Deallocating cache1...");
     109        while (olddata1) {
     110                data1 = *((void **)olddata1);
     111                slab_free(cache1, olddata1);
     112                olddata1 = data1;
     113        }
     114        printf("done.\n");
     115        slab_print_list();
     116        slab_cache_destroy(cache1);
     117        slab_cache_destroy(cache2);
    105118}
    106119
    107120void test(void)
    108121{
     122        printf("Running reclaim test .. pass1\n");
    109123        totalmemtest();
     124        printf("Running reclaim test .. pass2\n");
     125        totalmemtest();
     126        printf("Reclaim test OK.\n");
    110127}
Note: See TracChangeset for help on using the changeset viewer.