mempool: simplify memory usage calculation

This commit simplifies rte_mempool_xmem_usage().

Since previous commit, the function rte_mempool_xmem_usage() is
now the last user of rte_mempool_obj_mem_iter(). This complex
code can now be moved inside the function. We can get rid of the
callback and do some simplification to make the code more readable.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
This commit is contained in:
Olivier Matz 2016-05-18 13:04:38 +02:00 committed by Thomas Monjalon
parent b18e19a892
commit 8567eb37d9

View File

@ -127,15 +127,6 @@ static unsigned optimize_object_size(unsigned obj_size)
return new_obj_size * RTE_MEMPOOL_ALIGN;
}
/**
* A mempool object iterator callback function.
*/
typedef void (*rte_mempool_obj_iter_t)(void * /*obj_iter_arg*/,
void * /*obj_start*/,
void * /*obj_end*/,
uint32_t /*obj_index */,
phys_addr_t /*physaddr*/);
static void
mempool_add_elem(struct rte_mempool *mp, void *obj, phys_addr_t physaddr)
{
@ -159,75 +150,6 @@ mempool_add_elem(struct rte_mempool *mp, void *obj, phys_addr_t physaddr)
rte_ring_sp_enqueue(mp->ring, obj);
}
/* Iterate through objects at the given address
*
* Given the pointer to the memory, and its topology in physical memory
* (the physical addresses table), iterate through the "elt_num" objects
* of size "elt_sz" aligned at "align". For each object in this memory
* chunk, invoke a callback. It returns the effective number of objects
* in this memory.
*/
static uint32_t
rte_mempool_obj_mem_iter(void *vaddr, uint32_t elt_num, size_t total_elt_sz,
size_t align, const phys_addr_t paddr[], uint32_t pg_num,
uint32_t pg_shift, rte_mempool_obj_iter_t obj_iter, void *obj_iter_arg)
{
uint32_t i, j, k;
uint32_t pgn, pgf;
uintptr_t end, start, va;
uintptr_t pg_sz;
phys_addr_t physaddr;
pg_sz = (uintptr_t)1 << pg_shift;
va = (uintptr_t)vaddr;
i = 0;
j = 0;
while (i != elt_num && j != pg_num) {
start = RTE_ALIGN_CEIL(va, align);
end = start + total_elt_sz;
/* index of the first page for the next element. */
pgf = (end >> pg_shift) - (start >> pg_shift);
/* index of the last page for the current element. */
pgn = ((end - 1) >> pg_shift) - (start >> pg_shift);
pgn += j;
/* do we have enough space left for the element. */
if (pgn >= pg_num)
break;
for (k = j;
k != pgn &&
paddr[k] + pg_sz == paddr[k + 1];
k++)
;
/*
* if next pgn chunks of memory physically continuous,
* use it to create next element.
* otherwise, just skip that chunk unused.
*/
if (k == pgn) {
physaddr = paddr[k] + (start & (pg_sz - 1));
if (obj_iter != NULL)
obj_iter(obj_iter_arg, (void *)start,
(void *)end, i, physaddr);
va = end;
j += pgf;
i++;
} else {
va = RTE_ALIGN_CEIL((va + 1), pg_sz);
j++;
}
}
return i;
}
/* call obj_cb() for each mempool element */
uint32_t
rte_mempool_obj_iter(struct rte_mempool *mp,
@ -345,41 +267,53 @@ rte_mempool_xmem_size(uint32_t elt_num, size_t total_elt_sz, uint32_t pg_shift)
return sz;
}
/* Callback used by rte_mempool_xmem_usage(): it sets the opaque
* argument to the end of the object.
*/
static void
mempool_lelem_iter(void *arg, __rte_unused void *start, void *end,
__rte_unused uint32_t idx, __rte_unused phys_addr_t physaddr)
{
*(uintptr_t *)arg = (uintptr_t)end;
}
/*
* Calculate how much memory would be actually required with the
* given memory footprint to store required number of elements.
*/
ssize_t
rte_mempool_xmem_usage(void *vaddr, uint32_t elt_num, size_t total_elt_sz,
const phys_addr_t paddr[], uint32_t pg_num, uint32_t pg_shift)
rte_mempool_xmem_usage(__rte_unused void *vaddr, uint32_t elt_num,
size_t total_elt_sz, const phys_addr_t paddr[], uint32_t pg_num,
uint32_t pg_shift)
{
uint32_t n;
uintptr_t va, uv;
size_t pg_sz, usz;
uint32_t elt_cnt = 0;
phys_addr_t start, end;
uint32_t paddr_idx;
size_t pg_sz = (size_t)1 << pg_shift;
pg_sz = (size_t)1 << pg_shift;
va = (uintptr_t)vaddr;
uv = va;
/* if paddr is NULL, assume contiguous memory */
if (paddr == NULL) {
start = 0;
end = pg_sz * pg_num;
paddr_idx = pg_num;
} else {
start = paddr[0];
end = paddr[0] + pg_sz;
paddr_idx = 1;
}
while (elt_cnt < elt_num) {
if ((n = rte_mempool_obj_mem_iter(vaddr, elt_num, total_elt_sz, 1,
paddr, pg_num, pg_shift, mempool_lelem_iter,
&uv)) != elt_num) {
return -(ssize_t)n;
if (end - start >= total_elt_sz) {
/* enough contiguous memory, add an object */
start += total_elt_sz;
elt_cnt++;
} else if (paddr_idx < pg_num) {
/* no room to store one obj, add a page */
if (end == paddr[paddr_idx]) {
end += pg_sz;
} else {
start = paddr[paddr_idx];
end = paddr[paddr_idx] + pg_sz;
}
paddr_idx++;
} else {
/* no more page, return how many elements fit */
return -(size_t)elt_cnt;
}
}
uv = RTE_ALIGN_CEIL(uv, pg_sz);
usz = uv - va;
return usz;
return (size_t)paddr_idx << pg_shift;
}
#ifndef RTE_LIBRTE_XEN_DOM0