Changeset a294ad0 in mainline


Ignore:
Timestamp:
2006-02-02T14:00:32Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2d43f3e
Parents:
758e065
Message:

Currently not-working SLAB allocator.

  • slightly changed interface to frame_alloc, allow zone preference
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • arch/ia64/src/mm/page.c

    r758e065 ra294ad0  
    9090         * Allocate VHPT and invalidate all its entries.
    9191         */
    92         page_ht = (pte_t *) frame_alloc(FRAME_KA, VHPT_WIDTH - FRAME_WIDTH, NULL);
     92        page_ht = (pte_t *) frame_alloc(FRAME_KA, VHPT_WIDTH - FRAME_WIDTH, NULL, NULL);
    9393        memsetb((__address) page_ht, VHPT_SIZE, 0);
    9494        ht_invalidate_all();   
  • genarch/src/mm/as_ht.c

    r758e065 ra294ad0  
    5454{
    5555        if (!page_ht) {
    56                 page_ht = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC, HT_WIDTH - FRAME_WIDTH, NULL);
     56                page_ht = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC, HT_WIDTH - FRAME_WIDTH, NULL, NULL);
    5757                memsetb((__address) page_ht, HT_SIZE, 0);
    5858        }
  • genarch/src/mm/as_pt.c

    r758e065 ra294ad0  
    5757        ipl_t ipl;
    5858
    59         dst_ptl0 = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC, ONE_FRAME, NULL);
     59        dst_ptl0 = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC, ONE_FRAME, NULL, NULL);
    6060
    6161        if (flags & FLAG_AS_KERNEL) {
  • genarch/src/mm/page_pt.c

    r758e065 ra294ad0  
    6666
    6767        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
    68                 newpt = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
     68                newpt = frame_alloc(FRAME_KA, ONE_FRAME, NULL, NULL);
    6969                memsetb(newpt, PAGE_SIZE, 0);
    7070                SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
     
    7575
    7676        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
    77                 newpt = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
     77                newpt = frame_alloc(FRAME_KA, ONE_FRAME, NULL, NULL);
    7878                memsetb(newpt, PAGE_SIZE, 0);
    7979                SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
     
    8484
    8585        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
    86                 newpt = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
     86                newpt = frame_alloc(FRAME_KA, ONE_FRAME, NULL, NULL);
    8787                memsetb(newpt, PAGE_SIZE, 0);
    8888                SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
  • generic/include/mm/frame.h

    r758e065 ra294ad0  
    4040#define ONE_FRAME       0
    4141
    42 #define FRAME_KA                1       /* skip frames conflicting with user address space */
    43 #define FRAME_PANIC             2       /* panic on failure */
    44 #define FRAME_ATOMIC            4       /* do not panic and do not sleep on failure */
     42#define FRAME_KA                0x1     /* skip frames conflicting with user address space */
     43#define FRAME_PANIC             0x2     /* panic on failure */
     44#define FRAME_ATOMIC            0x4     /* do not panic and do not sleep on failure */
     45#define FRAME_NO_RECLAIM        0x8     /* Do not start reclaiming when no free memory */
    4546
    4647#define FRAME_OK                0       /* frame_alloc return status */
     
    7980        __u8 buddy_order;       /**< buddy system block order */
    8081        link_t buddy_link;      /**< link to the next free block inside one order */
    81         slab_slab_t *slab;      /**< If allocated by slab, this points there */
     82        void *parent;           /**< If allocated by slab, this points there */
    8283};
    8384
     
    101102extern void frame_initialize(frame_t *frame, zone_t *zone);
    102103
    103 __address frame_alloc(int flags, __u8 order, int * status);
     104__address frame_alloc(int flags, __u8 order, int * status, zone_t **pzone);
    104105extern void frame_free(__address addr);
    105106
     
    115116__u8 zone_buddy_get_order(buddy_system_t *b, link_t * block);
    116117void zone_buddy_mark_busy(buddy_system_t *b, link_t * block);
     118extern frame_t * frame_addr2frame(__address addr);
    117119
    118120/*
  • generic/include/mm/slab.h

    r758e065 ra294ad0  
    11/*
    2  * Copyright (C) 2005 Ondrej Palkovsky
     2 * Copyright (C) 2006 Ondrej Palkovsky
    33 * All rights reserved.
    44 *
     
    3939#define SLAB_INSIDE_SIZE   (PAGE_SIZE / 6)
    4040
    41 /* slab_alloc constants */
    42 #define SLAB_ATOMIC       0x1 /**< Do not sleep when no free memory,
    43                                    may return NULL */
    44 #define SLAB_NO_RECLAIM   0x2 /**< Do not try to call slab_reclaim, if no
    45                                  free memory is found - avoid deadlock */
     41/** Maximum wasted space we allow for cache */
     42#define SLAB_MAX_BADNESS(cache)   ((PAGE_SIZE << (cache)->order) / 4)
    4643
    4744/* slab_reclaim constants */
     
    5552typedef struct {
    5653        link_t link;
    57         count_t busy;
    58         count_t size;
    59         void *objs[0];
     54        count_t busy;  /**< Count of full slots in magazine */
     55        count_t size;  /**< Number of slots in magazine */
     56        void *objs[0]; /**< Slots in magazine */
    6057}slab_magazine_t;
    6158
     
    6663        link_t link;
    6764        /* Configuration */
    68         size_t size;
    69         size_t align;
     65        size_t size;      /**< Size of SLAB position - align_up(sizeof(obj)) */
    7066        int (*constructor)(void *obj, int kmflag);
    7167        void (*destructor)(void *obj);
    72         int flags;
     68        int flags;        /**< Flags changing behaviour of cache */
    7369
    7470        /* Computed values */
    75         int pages;
    76         int objects;
     71        __u8 order;        /**< Order of frames to be allocated */
     72        int objects;      /**< Number of objects that fit in */
    7773
    7874        /* Statistics */
    7975
    8076        /* Slabs */
    81         link_t full_slabs;
    82         link_t partial_slabs;
     77        link_t full_slabs;     /**< List of full slabs */
     78        link_t partial_slabs;  /**< List of partial slabs */
    8379        /* Magazines  */
    84         link_t magazines;
    85         /* CPU cache */
     80        link_t magazines;      /**< List o full magazines */
     81
     82        /** CPU cache */
    8683        struct {
    8784                slab_magazine_t *current;
     
    9188}slab_cache_t;
    9289
    93 typedef struct {
    94         slab_cache_t *cache; /**< Pointer to parent cache */
    95         void *start;       /**< Start address of first available item */
    96         count_t available; /**< Count of available items in this slab */
    97         index_t nextavail; /**< The index of next available item */
    98 }slab_slab_t;
     90extern slab_cache_t * slab_cache_create(char *name,
     91                                        size_t size,
     92                                        size_t align,
     93                                        int (*constructor)(void *obj, int kmflag),
     94                                        void (*destructor)(void *obj),
     95                                        int flags);
     96extern void slab_cache_destroy(slab_cache_t *cache);
    9997
    100 
    101 slab_cache_t * slab_cache_create(char *name,
    102                                  size_t size,
    103                                  size_t align,
    104                                  int (*constructor)(void *obj, int kmflag),
    105                                  void (*destructor)(void *obj),
    106                                  int flags);
    107 void slab_cache_destroy(slab_cache_t *cache);
    108 
    109 void * slab_alloc(slab_cache_t *cache, int flags);
    110 void slab_free(slab_cache_t *cache, void *obj);
    111 count_t slab_reclaim(int flags);
     98extern void * slab_alloc(slab_cache_t *cache, int flags);
     99extern void slab_free(slab_cache_t *cache, void *obj);
     100extern count_t slab_reclaim(int flags);
    112101
    113102/** Initialize SLAB subsytem */
    114 void slab_cache_init(void);
     103extern void slab_cache_init(void);
    115104
    116105/* KConsole debug */
    117 void slab_print_list(void);
     106extern void slab_print_list(void);
    118107
    119108#endif
  • generic/src/cpu/cpu.c

    r758e065 ra294ad0  
    6262
    6363                for (i=0; i < config.cpu_count; i++) {
    64                         cpus[i].stack = (__u8 *) frame_alloc(FRAME_KA | FRAME_PANIC, ONE_FRAME, NULL);
     64                        cpus[i].stack = (__u8 *) frame_alloc(FRAME_KA | FRAME_PANIC, ONE_FRAME, NULL, NULL);
    6565                       
    6666                        cpus[i].id = i;
  • generic/src/mm/as.c

    r758e065 ra294ad0  
    254254         *   the different causes
    255255         */
    256         frame = frame_alloc(0, ONE_FRAME, NULL);
     256        frame = frame_alloc(0, ONE_FRAME, NULL, NULL);
    257257        memsetb(PA2KA(frame), FRAME_SIZE, 0);
    258258       
  • generic/src/mm/frame.c

    r758e065 ra294ad0  
    7777}
    7878
     79/**
     80 * Find AND LOCK zone that can allocate order frames
     81 *
     82 * Assume zone_head_lock is locked.
     83 */
     84static zone_t * find_free_zone(__u8 order)
     85{
     86        link_t *cur;
     87        zone_t *z;
     88
     89        for (cur = zone_head.next; cur != &zone_head;cur = cur->next) {
     90                z = list_get_instance(cur, zone_t, link);
     91               
     92                spinlock_lock(&z->lock);
     93               
     94                /* Check if the zone has 2^order frames area available  */
     95                if (buddy_system_can_alloc(z->buddy_system, order))
     96                        return z;
     97               
     98                spinlock_unlock(&z->lock);
     99        }
     100        return NULL;
     101}
     102
    79103/** Allocate power-of-two frames of physical memory.
    80104 *
    81105 * @param flags Flags for host zone selection and address processing.
    82106 * @param order Allocate exactly 2^order frames.
     107 * @param pzone Pointer to preferred zone pointer, on output it changes
     108 *              to the zone that the frame was really allocated to
    83109 *
    84110 * @return Allocated frame.
    85111 */
    86 __address frame_alloc(int flags, __u8 order, int * status)
     112__address frame_alloc(int flags, __u8 order, int * status, zone_t **pzone)
    87113{
    88114        ipl_t ipl;
    89         link_t *cur, *tmp;
    90         zone_t *z;
     115        link_t *tmp;
    91116        zone_t *zone = NULL;
    92117        frame_t *frame = NULL;
     
    100125         * First, find suitable frame zone.
    101126         */
    102         for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
    103                 z = list_get_instance(cur, zone_t, link);
    104                
    105                 spinlock_lock(&z->lock);
    106 
    107                 /* Check if the zone has 2^order frames area available  */
    108                 if (buddy_system_can_alloc(z->buddy_system, order)) {
    109                         zone = z;
    110                         break;
    111                 }
    112                
    113                 spinlock_unlock(&z->lock);
    114         }
    115        
     127        if (pzone && *pzone) {
     128                spinlock_lock(&(*pzone)->lock);
     129                if (!buddy_system_can_alloc((*pzone)->buddy_system, order))
     130                        spinlock_unlock(&(*pzone)->lock);
     131                else
     132                        zone = *pzone;
     133        }
     134        if (!zone) {
     135                zone = find_free_zone(order);
     136                /* If no memory, reclaim some slab memory,
     137                   if it does not help, reclaim all */
     138                if (!zone && !(flags & FRAME_NO_RECLAIM))
     139                        if (slab_reclaim(0) || slab_reclaim(SLAB_RECLAIM_ALL))
     140                                zone = find_free_zone(order);
     141        }
     142
    116143        if (!zone) {
    117144                if (flags & FRAME_PANIC)
     
    162189                *status = FRAME_OK;
    163190        }
     191        if (pzone)
     192                *pzone = zone;
    164193        return v;
    165194}
    166195
    167 /** Free a frame.
    168  *
    169  * Find respective frame structrue for supplied addr.
    170  * Decrement frame reference count.
    171  * If it drops to zero, move the frame structure to free list.
    172  *
    173  * @param addr Address of the frame to be freed. It must be a multiple of FRAME_SIZE.
    174  */
    175 void frame_free(__address addr)
    176 {
    177         ipl_t ipl;
     196/** Convert address to zone pointer
     197 *
     198 * Assume zone_head_lock is held
     199 *
     200 * @param addr Physical address
     201 * @param lock If true, lock the zone
     202 */
     203static zone_t * addr2zone(__address addr, int lock)
     204{
    178205        link_t *cur;
    179         zone_t *z;
    180         zone_t *zone = NULL;
    181         frame_t *frame;
    182         int order;
    183        
    184         ASSERT(addr % FRAME_SIZE == 0);
    185        
    186         ipl = interrupts_disable();
    187         spinlock_lock(&zone_head_lock);
    188        
    189         /*
    190          * First, find host frame zone for addr.
    191          */
     206        zone_t *z = NULL;
     207
    192208        for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
    193209                z = list_get_instance(cur, zone_t, link);
    194210               
    195211                spinlock_lock(&z->lock);
    196                
    197                 if (IS_KA(addr))
    198                         addr = KA2PA(addr);
    199212               
    200213                /*
     
    202215                 */
    203216                if ((addr >= z->base) && (addr <= z->base + (z->free_count + z->busy_count) * FRAME_SIZE)) {
    204                         zone = z;
    205                         break;
     217                        if (!lock)
     218                                spinlock_unlock(&z->lock);
     219                        return z;
    206220                }
    207221
    208222                spinlock_unlock(&z->lock);
    209223        }
    210        
    211         ASSERT(zone != NULL);
     224
     225        panic("Cannot find addr2zone: 0x%X", addr);
     226}
     227
     228/** Return frame_t structure corresponding to address
     229 *
     230 *
     231 */
     232frame_t * frame_addr2frame(__address addr)
     233{
     234        ipl_t ipl;
     235        frame_t *frame;
     236        zone_t *zone;
     237
     238        if (IS_KA(addr))
     239                addr = KA2PA(addr);
     240
     241        /* Disable interrupts to avoid deadlocks with interrupt handlers */
     242        ipl = interrupts_disable();
     243        spinlock_lock(&zone_head_lock);
     244       
     245        zone = addr2zone(addr,0);
     246        frame = ADDR2FRAME(zone, addr);
     247
     248        spinlock_unlock(&zone_head_lock);
     249        interrupts_restore(ipl);
     250
     251        return frame;
     252}
     253
     254
     255/** Free a frame.
     256 *
     257 * Find respective frame structrue for supplied addr.
     258 * Decrement frame reference count.
     259 * If it drops to zero, move the frame structure to free list.
     260 *
     261 * @param addr Address of the frame to be freed. It must be a multiple of FRAME_SIZE.
     262 */
     263void frame_free(__address addr)
     264{
     265        ipl_t ipl;
     266        zone_t *zone;
     267        frame_t *frame;
     268        int order;
     269       
     270        ASSERT(addr % FRAME_SIZE == 0);
     271       
     272        if (IS_KA(addr))
     273                addr = KA2PA(addr);
     274
     275        ipl = interrupts_disable();
     276        spinlock_lock(&zone_head_lock);
     277       
     278        /*
     279         * First, find host frame zone for addr.
     280         */
     281        zone = addr2zone(addr, 1); /* This locks the zone automatically */
    212282       
    213283        frame = ADDR2FRAME(zone, addr);
  • generic/src/mm/slab.c

    r758e065 ra294ad0  
    3333#include <align.h>
    3434#include <mm/heap.h>
     35#include <mm/frame.h>
    3536#include <config.h>
    3637#include <print.h>
    3738#include <arch.h>
    3839#include <panic.h>
     40#include <debug.h>
    3941
    4042SPINLOCK_INITIALIZE(slab_cache_lock);
     
    4345slab_cache_t mag_cache;
    4446
     47
     48typedef struct {
     49        slab_cache_t *cache; /**< Pointer to parent cache */
     50        link_t link;       /* List of full/partial slabs */
     51        void *start;       /**< Start address of first available item */
     52        count_t available; /**< Count of available items in this slab */
     53        index_t nextavail; /**< The index of next available item */
     54}slab_t;
     55
    4556/**************************************/
    46 /* SLAB low level functions */
     57/* SLAB allocation functions          */
     58
     59/**
     60 * Allocate frames for slab space and initialize
     61 *
     62 * TODO: Change slab_t allocation to slab_alloc(????), malloc with flags!!
     63 */
     64static slab_t * slab_space_alloc(slab_cache_t *cache, int flags)
     65{
     66        void *data;
     67        slab_t *slab;
     68        size_t fsize;
     69        int i;
     70        zone_t *zone = NULL;
     71        int status;
     72
     73        data = (void *)frame_alloc(FRAME_KA | flags, cache->order, &status, &zone);
     74        if (status != FRAME_OK)
     75                return NULL;
     76
     77        if (! cache->flags & SLAB_CACHE_SLINSIDE) {
     78                slab = malloc(sizeof(*slab)); // , flags);
     79                if (!slab) {
     80                        frame_free((__address)data);
     81                        return NULL;
     82                }
     83        } else {
     84                fsize = (PAGE_SIZE << cache->order);
     85                slab = data + fsize - sizeof(*slab);
     86        }
     87
     88        /* Fill in slab structures */
     89        /* TODO: some better way of accessing the frame, although
     90         * the optimizer might optimize the division out :-/ */
     91        for (i=0; i< (1<<cache->order); i++) {
     92                ADDR2FRAME(zone, (__address)(data+i*PAGE_SIZE))->parent = slab;
     93        }
     94
     95        slab->start = data;
     96        slab->available = cache->objects;
     97        slab->nextavail = 0;
     98
     99        for (i=0; i<cache->objects;i++)
     100                *((int *) (slab->start + i*cache->size)) = i+1;
     101        return slab;
     102}
     103
     104/**
     105 * Free space associated with SLAB
     106 *
     107 * @return number of freed frames
     108 */
     109static count_t slab_space_free(slab_cache_t *cache, slab_t *slab)
     110{
     111        frame_free((__address)slab->start);
     112        if (! cache->flags & SLAB_CACHE_SLINSIDE)
     113                free(slab);
     114        return 1 << cache->order;
     115}
     116
     117/** Map object to slab structure */
     118static slab_t * obj2slab(void *obj)
     119{
     120        frame_t *frame;
     121
     122        frame = frame_addr2frame((__address)obj);
     123        return (slab_t *)frame->parent;
     124}
     125
     126/**************************************/
     127/* SLAB functions */
    47128
    48129
     
    50131 * Return object to slab and call a destructor
    51132 *
     133 * Assume the cache->lock is held;
     134 *
     135 * @param slab If the caller knows directly slab of the object, otherwise NULL
     136 *
    52137 * @return Number of freed pages
    53138 */
    54 static count_t slab_obj_destroy(slab_cache_t *cache, void *obj)
    55 {
    56         return 0;
    57 }
    58 
     139static count_t slab_obj_destroy(slab_cache_t *cache, void *obj,
     140                                slab_t *slab)
     141{
     142        count_t frames = 0;
     143
     144        if (!slab)
     145                slab = obj2slab(obj);
     146
     147        spinlock_lock(cache->lock);
     148
     149        *((int *)obj) = slab->nextavail;
     150        slab->nextavail = (obj - slab->start)/cache->size;
     151        slab->available++;
     152
     153        /* Move it to correct list */
     154        if (slab->available == 1) {
     155                /* It was in full, move to partial */
     156                list_remove(&slab->link);
     157                list_prepend(&cache->partial_slabs, &slab->link);
     158        }
     159        if (slab->available == cache->objects) {
     160                /* Free associated memory */
     161                list_remove(&slab->link);
     162                /* Avoid deadlock */
     163                spinlock_unlock(&cache->lock);
     164                frames = slab_space_free(cache, slab);
     165                spinlock_lock(&cache->lock);
     166        }
     167
     168        spinlock_unlock(cache->lock);
     169
     170        return frames;
     171}
    59172
    60173/**
    61174 * Take new object from slab or create new if needed
    62175 *
     176 * Assume cache->lock is held.
     177 *
    63178 * @return Object address or null
    64179 */
    65180static void * slab_obj_create(slab_cache_t *cache, int flags)
    66181{
    67         return NULL;
     182        slab_t *slab;
     183        void *obj;
     184
     185        if (list_empty(&cache->partial_slabs)) {
     186                /* Allow recursion and reclaiming
     187                 * - this should work, as the SLAB control structures
     188                 *   are small and do not need to allocte with anything
     189                 *   other ten frame_alloc when they are allocating,
     190                 *   that's why we should get recursion at most 1-level deep
     191                 */
     192                spinlock_unlock(&cache->lock);
     193                slab = slab_space_alloc(cache, flags);
     194                spinlock_lock(&cache->lock);
     195                if (!slab)
     196                        return NULL;
     197        } else {
     198                slab = list_get_instance(cache->partial_slabs.next,
     199                                         slab_t,
     200                                         link);
     201                list_remove(&slab->link);
     202        }
     203        obj = slab->start + slab->nextavail * cache->size;
     204        slab->nextavail = *((int *)obj);
     205        slab->available--;
     206        if (! slab->available)
     207                list_prepend(&cache->full_slabs, &slab->link);
     208        else
     209                list_prepend(&cache->partial_slabs, &slab->link);
     210        return obj;
    68211}
    69212
     
    74217 * Free all objects in magazine and free memory associated with magazine
    75218 *
    76  * Assume cpu->lock is locked
     219 * Assume mag_cache[cpu].lock is locked
    77220 *
    78221 * @return Number of freed pages
     
    85228
    86229        for (i=0;i < mag->busy; i++)
    87                 frames += slab_obj_destroy(cache, mag->objs[i]);
     230                frames += slab_obj_destroy(cache, mag->objs[i], NULL);
    88231       
    89232        slab_free(&mag_cache, mag);
     
    116259                        goto gotit;
    117260                }
    118                 /* If still not busy, exchange current with some frome
     261                /* If still not busy, exchange current with some from
    119262                 * other full magazines */
    120263                spinlock_lock(&cache->lock);
     
    162305                /* Especially we do not want reclaiming to start, as
    163306                 * this would deadlock */
    164                 mag = slab_alloc(&mag_cache, SLAB_ATOMIC | SLAB_NO_RECLAIM);
     307                mag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM);
    165308                if (!mag) /* Allocation failed, give up on caching */
    166309                        goto errout;
     
    176319                                list_prepend(&cache->magazines, &mag->link);
    177320
    178                         mag = slab_alloc(&mag_cache, SLAB_ATOMIC | SLAB_NO_RECLAIM);
     321                        mag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM);
    179322                        if (!mag)
    180323                                goto errout;
     
    199342
    200343/**************************************/
    201 /* Top level SLAB functions */
     344/* SLAB CACHE functions */
     345
     346/** Return number of objects that fit in certain cache size */
     347static int comp_objects(slab_cache_t *cache)
     348{
     349        if (cache->flags & SLAB_CACHE_SLINSIDE)
     350                return ((PAGE_SIZE << cache->order) - sizeof(slab_t)) / cache->size;
     351        else
     352                return (PAGE_SIZE << cache->order) / cache->size;
     353}
     354
     355/** Return wasted space in slab */
     356static int badness(slab_cache_t *cache)
     357{
     358        int objects;
     359        int ssize;
     360
     361        objects = comp_objects(cache);
     362        ssize = PAGE_SIZE << cache->order;
     363        if (cache->flags & SLAB_CACHE_SLINSIDE)
     364                ssize -= sizeof(slab_t);
     365        return ssize - objects*cache->size;
     366}
    202367
    203368/** Initialize allocated memory as a slab cache */
     
    215380        memsetb((__address)cache, sizeof(*cache), 0);
    216381        cache->name = name;
    217         cache->align = align;
    218 
    219         cache->size = ALIGN_UP(size, align);
     382
     383        if (align)
     384                size = ALIGN_UP(size, align);
     385        cache->size = size;
    220386
    221387        cache->constructor = constructor;
     
    237403                cache->flags |= SLAB_CACHE_SLINSIDE;
    238404
    239        
     405        /* Minimum slab order */
     406        cache->order = (cache->size / PAGE_SIZE) + 1;
     407               
     408        while (badness(cache) > SLAB_MAX_BADNESS(cache)) {
     409                cache->order += 1;
     410        }
     411
     412        cache->objects = comp_objects(cache);
    240413
    241414        spinlock_lock(&slab_cache_lock);
     
    267440 * @param flags If contains SLAB_RECLAIM_ALL, do aggressive freeing
    268441 * @return Number of freed pages
     442 *
     443 * TODO: Add light reclaim
    269444 */
    270445static count_t _slab_reclaim(slab_cache_t *cache, int flags)
     
    284459       
    285460        if (flags & SLAB_RECLAIM_ALL) {
     461                /* Aggressive memfree */
     462
    286463                /* Destroy CPU magazines */
    287464                for (i=0; i<config.cpu_count; i++) {
     
    296473                        cache->mag_cache[i].last = NULL;
    297474                }
    298                 /* Destroy full magazines */
    299                 cur=cache->magazines.next;
    300                 while (cur!=&cache->magazines) {
    301                         mag = list_get_instance(cur, slab_magazine_t, link);
    302                        
    303                         cur = cur->next;
    304                         list_remove(cur->prev);
    305                         frames += magazine_destroy(cache,mag);
    306                 }
     475        }
     476        /* Destroy full magazines */
     477        cur=cache->magazines.prev;
     478        while (cur!=&cache->magazines) {
     479                mag = list_get_instance(cur, slab_magazine_t, link);
     480               
     481                cur = cur->prev;
     482                list_remove(cur->next);
     483                frames += magazine_destroy(cache,mag);
     484                /* If we do not do full reclaim, break
     485                 * as soon as something is freed */
     486                if (!(flags & SLAB_RECLAIM_ALL) && frames)
     487                        break;
    307488        }
    308489       
     
    348529                result = magazine_obj_get(cache);
    349530
    350         if (!result)
     531        if (!result) {
     532                spinlock_lock(&cache->lock);
    351533                result = slab_obj_create(cache, flags);
     534                spinlock_unlock(&cache->lock);
     535        }
    352536
    353537        interrupts_restore(ipl);
     
    363547        ipl = interrupts_disable();
    364548
    365         if (cache->flags & SLAB_CACHE_NOMAGAZINE)
    366                 slab_obj_destroy(cache, obj);
    367         else {
    368                 if (magazine_obj_put(cache, obj)) /* If magazine put failed */
    369                         slab_obj_destroy(cache, obj);
     549        if ((cache->flags & SLAB_CACHE_NOMAGAZINE) \
     550            || magazine_obj_put(cache, obj)) {
     551               
     552                spinlock_lock(&cache->lock);
     553                slab_obj_destroy(cache, obj, NULL);
     554                spinlock_unlock(&cache->lock);
    370555        }
    371556        interrupts_restore(ipl);
     
    399584
    400585        spinlock_lock(&slab_cache_lock);
    401         printf("SLAB name\tObj size\n");
     586        printf("SLAB name\tOsize\tOrder\n");
    402587        for (cur = slab_cache_list.next;cur!=&slab_cache_list; cur=cur->next) {
    403588                cache = list_get_instance(cur, slab_cache_t, link);
    404                 printf("%s\t%d\n", cache->name, cache->size);
     589                printf("%s\t%d\t%d\n", cache->name, cache->size, cache->order);
    405590        }
    406591        spinlock_unlock(&slab_cache_lock);
  • generic/src/proc/thread.c

    r758e065 ra294ad0  
    174174                spinlock_initialize(&t->lock, "thread_t_lock");
    175175       
    176                 frame_ks = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
     176                frame_ks = frame_alloc(FRAME_KA, ONE_FRAME, NULL, NULL);
    177177                if (THREAD_USER_STACK & flags) {
    178                         frame_us = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
     178                        frame_us = frame_alloc(FRAME_KA, ONE_FRAME, NULL,NULL);
    179179                }
    180180
  • test/mm/falloc1/test.c

    r758e065 ra294ad0  
    5656                        allocated = 0;
    5757                        for (i = 0; i < MAX_FRAMES >> order; i++) {
    58                                 frames[allocated] = frame_alloc(FRAME_ATOMIC | FRAME_KA, order, &status);
     58                                frames[allocated] = frame_alloc(FRAME_ATOMIC | FRAME_KA, order, &status, NULL);
    5959                               
    6060                                if (ALIGN_UP(frames[allocated], FRAME_SIZE << order) != frames[allocated]) {
  • test/mm/falloc2/test.c

    r758e065 ra294ad0  
    6464                        allocated = 0;
    6565                        for (i = 0; i < (MAX_FRAMES >> order); i++) {
    66                                 frames[allocated] = frame_alloc(FRAME_ATOMIC | FRAME_KA, order, &status);
     66                                frames[allocated] = frame_alloc(FRAME_ATOMIC | FRAME_KA, order, &status, NULL);
    6767                                if (status == 0) {
    6868                                        memsetb(frames[allocated], FRAME_SIZE << order, val);
  • test/mm/mapping1/test.c

    r758e065 ra294ad0  
    4848        printf("Memory management test mapping #1\n");
    4949
    50         frame0 = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
    51         frame1 = frame_alloc(FRAME_KA, ONE_FRAME, NULL);       
     50        frame0 = frame_alloc(FRAME_KA, ONE_FRAME, NULL, NULL);
     51        frame1 = frame_alloc(FRAME_KA, ONE_FRAME, NULL, NULL); 
    5252
    5353        printf("Writing %L to physical address %P.\n", VALUE0, KA2PA(frame0));
  • test/mm/slab1/test.c

    r758e065 ra294ad0  
    2929#include <test.h>
    3030#include <mm/slab.h>
     31#include <print.h>
     32
     33#define VAL_SIZE    128
     34#define VAL_COUNT   1024
     35
     36void * data[16384];
    3137
    3238void test(void)
    3339{
    34         slab_cache_create("test_cache", 10, 0, NULL, NULL, 0);
     40        slab_cache_t *cache;
     41        int i;
     42       
     43
     44        printf("Creating cache.\n");
     45        cache = slab_cache_create("test_cache", VAL_SIZE, 0, NULL, NULL, SLAB_CACHE_NOMAGAZINE);
     46        slab_print_list();
     47        printf("Destroying cache.\n");
     48        slab_cache_destroy(cache);
     49
     50        printf("Creating cache.\n");
     51        cache = slab_cache_create("test_cache", VAL_SIZE, 0, NULL, NULL,
     52                                  SLAB_CACHE_NOMAGAZINE);
     53       
     54        printf("Allocating %d items...", VAL_COUNT);
     55        for (i=0; i < VAL_COUNT; i++) {
     56                data[i] = slab_alloc(cache, 0);
     57        }
     58        printf("done.\n");
     59        printf("Freeing %d items...", VAL_COUNT);
     60        for (i=0; i < VAL_COUNT; i++) {
     61                slab_free(cache, data[i]);
     62        }
     63        printf("done.\n");
    3564}
Note: See TracChangeset for help on using the changeset viewer.