Main Page | Directories | File List | Globals

buddy_alloc.c File Reference

#include <agnix/agnix.h>
#include <asm/bitops.h>
#include <agnix/memory.h>
#include <agnix/panic.h>
#include <agnix/console.h>

Include dependency graph for buddy_alloc.c:

Go to the source code of this file.

Defines

#define MOD_NAME   "MEM: "
#define NO_PAGE   0

Functions

void buddy_put_free_pages (struct buddy_allocator_s *buddy_alloc, u32 addr, u8 order)
page_desc_s * buddy_get_free_pages_back (struct buddy_allocator_s *buddy_alloc, u32 order, u32 cur_order)
u32 buddy_get_free_pages (struct buddy_allocator_s *buddy_alloc, u8 order)
u32 buddy_get_free_pages_wrapper (u8 order)
void buddy_put_free_pages_wrapper (u32 address, u8 order)
u32 buddy_get_free_dma_pages_wrapper (u8 order)
void buddy_put_free_dma_pages_wrapper (u32 address, u8 order)
void buddy_alloc_fn_init (void)
int buddy_alloc_areas_init (struct allocator_s *main_alloc, struct buddy_allocator_s *buddy_alloc)
void buddy_alloc_pages_init (struct allocator_s *main_alloc)
void buddy_alloc_print_units (struct buddy_allocator_s *buddy_alloc, int broadcast)
u32 buddy_alloc_free (struct buddy_allocator_s *buddy_alloc)
void __init buddy_alloc_init (void)
void buddy_alloc_print_stats (void)
void buddy_alloc_print_free (void)

Variables

buddy_allocator_s buddy_alloc_normal
buddy_allocator_s buddy_alloc_dma
allocator_s main_alloc
void(* put_free_pages_fn )(u32 addr, u8 order)
u32(* get_free_pages_fn )(u8 order)
void(* put_free_dma_pages_fn )(u32 addr, u8 order)
u32(* get_free_dma_pages_fn )(u8 order)
page_desc_s * system_pages


Define Documentation

#define MOD_NAME   "MEM: "
 

Definition at line 20 of file buddy_alloc.c.

#define NO_PAGE   0
 

Definition at line 21 of file buddy_alloc.c.


Function Documentation

int buddy_alloc_areas_init struct allocator_s *  main_alloc,
struct buddy_allocator_s *  buddy_alloc
 

Definition at line 187 of file buddy_alloc.c.

References bin_get_free_pages(), kernel_panic(), and MOD_NAME.

Referenced by buddy_alloc_init().

00188 {
00189     int i;
00190     int area_size_pages = 0;
00191     
00192     for (i = 0; i < buddy_alloc->buddy_alloc_req_areas; i++) {
00193 
00194         area_size_pages = (((main_alloc->mem_size_pages + (1 << 3) - 1) >> 4) + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
00195         if ((buddy_alloc->buddy_area[i].area_bitmap = (u32 *)bin_get_free_pages(area_size_pages)) == NULL) {
00196             kernel_panic(MOD_NAME "buddy_alloc_init() failed\n");
00197         }
00198 
00199         INIT_LIST_HEAD(&buddy_alloc->buddy_area[i].area_list);
00200         buddy_alloc->buddy_area[i].free_units = 0;      
00201     }    
00202     
00203     return 0;
00204 }

Here is the call graph for this function:

void buddy_alloc_fn_init void   ) 
 

Definition at line 179 of file buddy_alloc.c.

References buddy_get_free_dma_pages_wrapper(), buddy_get_free_pages_wrapper(), buddy_put_free_dma_pages_wrapper(), buddy_put_free_pages_wrapper(), get_free_dma_pages_fn, get_free_pages_fn, put_free_dma_pages_fn, and put_free_pages_fn.

Referenced by buddy_alloc_init().

Here is the call graph for this function:

u32 buddy_alloc_free struct buddy_allocator_s *  buddy_alloc  ) 
 

Definition at line 254 of file buddy_alloc.c.

References flags.

Referenced by buddy_alloc_print_free().

00255 {
00256     struct buddy_area_s *area;
00257     u32 page_order;
00258     u32 free;
00259     u32 flags;
00260     int i;
00261     
00262     spin_lock_irqsave(&buddy_alloc->buddy_lock, flags);
00263 
00264     free = 0;
00265     page_order = 1;
00266     for (i = 0; i < buddy_alloc->buddy_alloc_req_areas; i++) {
00267         area = &buddy_alloc->buddy_area[i];
00268         free += area->free_units * page_order;
00269         page_order <<= 1;
00270     }
00271     
00272     spin_unlock_irqrestore(&buddy_alloc->buddy_lock, flags);
00273     
00274     return free;
00275 }

void __init buddy_alloc_init void   ) 
 

Definition at line 277 of file buddy_alloc.c.

References bin_put_all_free_pages(), buddy_alloc_areas_init(), buddy_alloc_dma, buddy_alloc_fn_init(), buddy_alloc_normal, buddy_alloc_pages_init(), buddy_alloc_print_units(), and main_alloc.

Referenced by memalloc_init().

Here is the call graph for this function:

void buddy_alloc_pages_init struct allocator_s *  main_alloc  ) 
 

Definition at line 206 of file buddy_alloc.c.

References bin_get_free_pages(), kernel_panic(), MOD_NAME, and system_pages.

Referenced by buddy_alloc_init().

00207 {
00208     int system_pages_size;
00209     int i;
00210     
00211     system_pages_size = ((main_alloc->mem_size_pages * sizeof(struct page_desc_s)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
00212     
00213     if ((system_pages = (struct page_desc_s *)bin_get_free_pages(system_pages_size)) == NULL) {
00214         kernel_panic(MOD_NAME "buddy_alloc_pages_init() failed\n");
00215     }    
00216     
00217     for (i = 0; i < main_alloc->mem_size_pages; i++) {
00218         system_pages[i].address_phys = (u32)(i << PAGE_SHIFT);
00219         system_pages[i].address_virt = phys_to_virt(system_pages[i].address_phys);
00220 
00221         INIT_LIST_HEAD(&system_pages[i].page_list);
00222     }
00223 }

Here is the call graph for this function:

void buddy_alloc_print_free void   ) 
 

Definition at line 296 of file buddy_alloc.c.

References buddy_alloc_dma, buddy_alloc_free(), buddy_alloc_normal, and printf().

Referenced by agnix_console_vm_free().

00297 {
00298     u32 free_dma, free_normal;
00299 
00300     free_dma    = buddy_alloc_free(&buddy_alloc_dma);
00301     printf("DMA free:     %d KB\n", free_dma << (PAGE_SHIFT - 10));
00302 
00303     free_normal = buddy_alloc_free(&buddy_alloc_normal);
00304     printf("Normal free:  %d KB\n", free_normal << (PAGE_SHIFT - 10));
00305     
00306     printf("Total free:   %d KB\n", (free_normal + free_dma) << (PAGE_SHIFT - 10));
00307 }

Here is the call graph for this function:

void buddy_alloc_print_stats void   ) 
 

Definition at line 290 of file buddy_alloc.c.

References buddy_alloc_dma, buddy_alloc_normal, and buddy_alloc_print_units().

Referenced by agnix_console_vm_stats().

Here is the call graph for this function:

void buddy_alloc_print_units struct buddy_allocator_s *  buddy_alloc,
int  broadcast
 

Definition at line 225 of file buddy_alloc.c.

References flags, MOD_NAME, printf(), and printk().

Referenced by buddy_alloc_init(), and buddy_alloc_print_stats().

00226 {
00227     struct buddy_area_s *area;
00228     int i;
00229     u32 flags;
00230     
00231     if (broadcast)
00232         printk("\n" MOD_NAME "%s free units\n", buddy_alloc->buddy_name);
00233     else
00234         printf("\n" MOD_NAME "%s free units\n", buddy_alloc->buddy_name);
00235 
00236     spin_lock_irqsave(&buddy_alloc->buddy_lock, flags);
00237 
00238     for (i = 0; i < buddy_alloc->buddy_alloc_req_areas; i++) {
00239         area = &buddy_alloc->buddy_area[i];
00240         if (broadcast)
00241             printk(MOD_NAME "\torder %02d -> %d free units\n", i, area->free_units);
00242         else
00243             printf(MOD_NAME "\torder %02d -> %d free units\n", i, area->free_units);
00244     }
00245     
00246     if (broadcast)
00247         printk("\n");
00248     else
00249         printf("\n");
00250     
00251     spin_unlock_irqrestore(&buddy_alloc->buddy_lock, flags);
00252 }

Here is the call graph for this function:

u32 buddy_get_free_dma_pages_wrapper u8  order  ) 
 

Definition at line 169 of file buddy_alloc.c.

References buddy_alloc_dma, and buddy_get_free_pages().

Referenced by buddy_alloc_fn_init().

00170 {
00171     return buddy_get_free_pages(&buddy_alloc_dma, order);
00172 }

Here is the call graph for this function:

u32 buddy_get_free_pages struct buddy_allocator_s *  buddy_alloc,
u8  order
 

Definition at line 112 of file buddy_alloc.c.

References buddy_get_free_pages_back(), flags, and printk().

Referenced by buddy_get_free_dma_pages_wrapper(), and buddy_get_free_pages_wrapper().

00113 {
00114     struct buddy_area_s *area = &buddy_alloc->buddy_area[order];
00115     struct page_desc_s *page_desc = NULL;
00116     u32 cur_order;
00117     u32 flags;
00118     u8  *ptr;
00119     int i;
00120         
00121     spin_lock_irqsave(&buddy_alloc->buddy_lock, flags);
00122 
00123     for (cur_order = order; cur_order < buddy_alloc->buddy_alloc_req_areas; cur_order++) {
00124 
00125         if (!list_empty(&area->area_list)) {
00126             if (cur_order == order) {
00127                 page_desc = list_entry(area->area_list.next, struct page_desc_s, page_list);
00128                 change_bit(virt_to_page(page_desc->address_virt) >> (order + 1), area->area_bitmap);
00129                 list_del(area->area_list.next);
00130                 area->free_units--;
00131             } else {
00132                 page_desc = buddy_get_free_pages_back(buddy_alloc, order, cur_order);
00133             }    
00134             
00135             break;
00136         }
00137         area++;
00138     }
00139     
00140     spin_unlock_irqrestore(&buddy_alloc->buddy_lock, flags);
00141 
00142     if (cur_order == buddy_alloc->buddy_alloc_req_areas)
00143         return 0;
00144 
00145     if (page_desc->address_virt < 0xc0000000) {
00146         printk("address < 0xc0000000\n");
00147         for (i = 0; i < 1000000000; i++);
00148     }
00149 
00150     ptr = (u8 *)page_desc->address_virt;
00151     
00152     for (i = 0; i < PAGE_SIZE; i++) {
00153         ptr[i] = 0;
00154     }
00155         
00156     return page_desc->address_virt;
00157 }

Here is the call graph for this function:

struct page_desc_s* buddy_get_free_pages_back struct buddy_allocator_s *  buddy_alloc,
u32  order,
u32  cur_order
 

Definition at line 79 of file buddy_alloc.c.

References system_pages.

Referenced by buddy_get_free_pages().

00080 {
00081     struct buddy_area_s *area = &buddy_alloc->buddy_area[cur_order];
00082     struct page_desc_s *page_desc = NULL;
00083     u32 page_idx;
00084     u32 page_half_idx;
00085     u32 back_order;
00086     u32 area_size;
00087 
00088     page_desc = list_entry(area->area_list.next, struct page_desc_s, page_list);
00089     page_idx  = virt_to_page(page_desc->address_virt);
00090     list_del(area->area_list.next);
00091     change_bit(page_idx >> (cur_order + 1), area->area_bitmap);
00092     area->free_units--;
00093 
00094     for (back_order = cur_order - 1; back_order >= order; back_order--) {
00095         area = &buddy_alloc->buddy_area[back_order];
00096         area_size = 1 << back_order;
00097         page_idx  = virt_to_page(page_desc->address_virt);
00098         page_half_idx = page_idx + area_size;
00099         list_add(&page_desc->page_list, &area->area_list);
00100         area->free_units++;
00101 
00102         change_bit(page_idx >> (back_order + 1), area->area_bitmap);
00103         page_desc = &system_pages[page_half_idx];
00104         
00105         if (back_order == order)
00106             break;
00107     }   
00108         
00109     return page_desc;
00110 }

u32 buddy_get_free_pages_wrapper u8  order  ) 
 

Definition at line 159 of file buddy_alloc.c.

References buddy_alloc_normal, and buddy_get_free_pages().

Referenced by buddy_alloc_fn_init().

00160 {
00161     return buddy_get_free_pages(&buddy_alloc_normal, order);
00162 }

Here is the call graph for this function:

void buddy_put_free_dma_pages_wrapper u32  address,
u8  order
 

Definition at line 174 of file buddy_alloc.c.

References buddy_alloc_dma, and buddy_put_free_pages().

Referenced by buddy_alloc_fn_init().

00175 {
00176     return buddy_put_free_pages(&buddy_alloc_dma, address, order);
00177 }

Here is the call graph for this function:

void buddy_put_free_pages struct buddy_allocator_s *  buddy_alloc,
u32  addr,
u8  order
 

Definition at line 40 of file buddy_alloc.c.

References flags, and system_pages.

Referenced by buddy_put_free_dma_pages_wrapper(), and buddy_put_free_pages_wrapper().

00041 {
00042     u8 start_order;
00043     u32 bitmap_idx;
00044     struct buddy_area_s *area = &buddy_alloc->buddy_area[order];
00045     struct page_desc_s *page_desc;
00046     struct page_desc_s *page_buddy_desc;
00047     u32 page_idx = virt_to_page(addr);
00048     u32 page_buddy_idx;
00049     u32 page_mask;
00050     u32 flags;
00051 
00052     spin_lock_irqsave(&buddy_alloc->buddy_lock, flags);
00053 
00054     page_mask  = (~0UL) << order;
00055     for (start_order = order; start_order < buddy_alloc->buddy_alloc_req_areas; start_order++) {
00056         bitmap_idx = page_idx >> (start_order + 1);
00057 
00058         if (!test_and_change_bit(bitmap_idx, area->area_bitmap)) {
00059             break;
00060         }
00061         
00062         page_buddy_idx  = page_idx ^ (1 + ~page_mask);
00063         page_buddy_desc = &system_pages[page_buddy_idx];
00064         list_del(&page_buddy_desc->page_list);
00065         area->free_units--;
00066         
00067         area++;
00068         page_mask <<= 1;
00069         page_idx &= page_mask;
00070     }
00071 
00072     page_desc = &system_pages[page_idx];
00073     list_add(&page_desc->page_list, &area->area_list);
00074     area->free_units++;
00075     
00076     spin_unlock_irqrestore(&buddy_alloc->buddy_lock, flags);
00077 }

void buddy_put_free_pages_wrapper u32  address,
u8  order
 

Definition at line 164 of file buddy_alloc.c.

References buddy_alloc_normal, and buddy_put_free_pages().

Referenced by buddy_alloc_fn_init().

00165 {
00166     return buddy_put_free_pages(&buddy_alloc_normal, address, order);
00167 }

Here is the call graph for this function:


Variable Documentation

struct buddy_allocator_s buddy_alloc_dma
 

Initial value:

 {
    .buddy_name                 = "DMA area buddy allocator",
    .buddy_alloc_req_areas      = BUDDY_ALLOC_DMA_AREAS 
}

Definition at line 28 of file buddy_alloc.c.

Referenced by buddy_alloc_init(), buddy_alloc_print_free(), buddy_alloc_print_stats(), buddy_get_free_dma_pages_wrapper(), and buddy_put_free_dma_pages_wrapper().

struct buddy_allocator_s buddy_alloc_normal
 

Initial value:

 {
    .buddy_name                 = "Normal area buddy allocator",
    .buddy_alloc_req_areas      = BUDDY_ALLOC_NORMAL_AREAS 
}

Definition at line 23 of file buddy_alloc.c.

Referenced by buddy_alloc_init(), buddy_alloc_print_free(), buddy_alloc_print_stats(), buddy_get_free_pages_wrapper(), and buddy_put_free_pages_wrapper().

u32(* get_free_dma_pages_fn)(u8 order)
 

Definition at line 33 of file alloc.c.

Referenced by buddy_alloc_fn_init(), and get_free_dma_pages().

u32(* get_free_pages_fn)(u8 order)
 

Definition at line 31 of file alloc.c.

Referenced by bin_alloc_fn_init(), buddy_alloc_fn_init(), and get_free_pages().

struct allocator_s main_alloc
 

Definition at line 35 of file alloc.c.

Referenced by _bin_get_free_pages(), bin_alloc_init(), bin_free_pages(), bin_put_all_free_pages(), bin_reserve_pages(), bin_reserve_system_pages(), and buddy_alloc_init().

void(* put_free_dma_pages_fn)(u32 addr, u8 order)
 

Definition at line 32 of file alloc.c.

Referenced by buddy_alloc_fn_init(), and put_free_dma_pages().

void(* put_free_pages_fn)(u32 addr, u8 order)
 

Definition at line 30 of file alloc.c.

Referenced by bin_alloc_fn_init(), buddy_alloc_fn_init(), and put_free_pages().

struct page_desc_s* system_pages
 

Definition at line 38 of file buddy_alloc.c.

Referenced by buddy_alloc_pages_init(), buddy_get_free_pages_back(), and buddy_put_free_pages().

Dokumentacje wygenerowano programem Doxygen 1.4.2 dla projektu Agnix