Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 250981
b: refs/heads/master
c: 3c8f370
h: refs/heads/master
i:
  250979: b500566
v: v3
  • Loading branch information
Jean-Christophe PLAGNIOL-VILLARD authored and Linus Torvalds committed May 25, 2011
1 parent 385185a commit a4911ff
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6aae6e0304d33e537298867dafb2703ec58c2e4f
refs/heads/master: 3c8f370ded3483b27f1218ff0051fcf0c7a2facd
22 changes: 21 additions & 1 deletion trunk/include/linux/genalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,33 @@ struct gen_pool {
struct gen_pool_chunk {
spinlock_t lock;
struct list_head next_chunk; /* next chunk in pool */
phys_addr_t phys_addr; /* physical starting address of memory chunk */
unsigned long start_addr; /* starting address of memory chunk */
unsigned long end_addr; /* ending address of memory chunk */
unsigned long bits[0]; /* bitmap for allocating memory chunk */
};

extern struct gen_pool *gen_pool_create(int, int);
extern int gen_pool_add(struct gen_pool *, unsigned long, size_t, int);
extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long);
extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t,
size_t, int);
/**
* gen_pool_add - add a new chunk of special memory to the pool
* @pool: pool to add new memory chunk to
* @addr: starting address of memory chunk to add to pool
* @size: size in bytes of the memory chunk to add to pool
* @nid: node id of the node the chunk structure and bitmap should be
* allocated on, or -1
*
* Add a new chunk of special memory to the specified pool.
*
* Returns 0 on success or a -ve errno on failure.
*/
static inline int gen_pool_add(struct gen_pool *pool, unsigned long addr,
size_t size, int nid)
{
return gen_pool_add_virt(pool, addr, -1, size, nid);
}
extern void gen_pool_destroy(struct gen_pool *);
extern unsigned long gen_pool_alloc(struct gen_pool *, size_t);
extern void gen_pool_free(struct gen_pool *, unsigned long, size_t);
Expand Down
45 changes: 37 additions & 8 deletions trunk/lib/genalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,20 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid)
EXPORT_SYMBOL(gen_pool_create);

/**
* gen_pool_add - add a new chunk of special memory to the pool
* gen_pool_add_virt - add a new chunk of special memory to the pool
* @pool: pool to add new memory chunk to
* @addr: starting address of memory chunk to add to pool
* @virt: virtual starting address of memory chunk to add to pool
* @phys: physical starting address of memory chunk to add to pool
* @size: size in bytes of the memory chunk to add to pool
* @nid: node id of the node the chunk structure and bitmap should be
* allocated on, or -1
*
* Add a new chunk of special memory to the specified pool.
*
* Returns 0 on success or a -ve errno on failure.
*/
int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
int nid)
int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phys,
size_t size, int nid)
{
struct gen_pool_chunk *chunk;
int nbits = size >> pool->min_alloc_order;
Expand All @@ -58,19 +61,45 @@ int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,

chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid);
if (unlikely(chunk == NULL))
return -1;
return -ENOMEM;

spin_lock_init(&chunk->lock);
chunk->start_addr = addr;
chunk->end_addr = addr + size;
chunk->phys_addr = phys;
chunk->start_addr = virt;
chunk->end_addr = virt + size;

write_lock(&pool->lock);
list_add(&chunk->next_chunk, &pool->chunks);
write_unlock(&pool->lock);

return 0;
}
EXPORT_SYMBOL(gen_pool_add);
EXPORT_SYMBOL(gen_pool_add_virt);

/**
* gen_pool_virt_to_phys - return the physical address of memory
* @pool: pool to allocate from
* @addr: starting address of memory
*
* Returns the physical address on success, or -1 on error.
*/
phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long addr)
{
struct list_head *_chunk;
struct gen_pool_chunk *chunk;

read_lock(&pool->lock);
list_for_each(_chunk, &pool->chunks) {
chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);

if (addr >= chunk->start_addr && addr < chunk->end_addr)
return chunk->phys_addr + addr - chunk->start_addr;
}
read_unlock(&pool->lock);

return -1;
}
EXPORT_SYMBOL(gen_pool_virt_to_phys);

/**
* gen_pool_destroy - destroy a special memory pool
Expand Down

0 comments on commit a4911ff

Please sign in to comment.