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:
parent
b18e19a892
commit
8567eb37d9
@ -127,15 +127,6 @@ static unsigned optimize_object_size(unsigned obj_size)
|
|||||||
return new_obj_size * RTE_MEMPOOL_ALIGN;
|
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
|
static void
|
||||||
mempool_add_elem(struct rte_mempool *mp, void *obj, phys_addr_t physaddr)
|
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);
|
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 */
|
/* call obj_cb() for each mempool element */
|
||||||
uint32_t
|
uint32_t
|
||||||
rte_mempool_obj_iter(struct rte_mempool *mp,
|
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;
|
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
|
* Calculate how much memory would be actually required with the
|
||||||
* given memory footprint to store required number of elements.
|
* given memory footprint to store required number of elements.
|
||||||
*/
|
*/
|
||||||
ssize_t
|
ssize_t
|
||||||
rte_mempool_xmem_usage(void *vaddr, uint32_t elt_num, size_t total_elt_sz,
|
rte_mempool_xmem_usage(__rte_unused void *vaddr, uint32_t elt_num,
|
||||||
const phys_addr_t paddr[], uint32_t pg_num, uint32_t pg_shift)
|
size_t total_elt_sz, const phys_addr_t paddr[], uint32_t pg_num,
|
||||||
|
uint32_t pg_shift)
|
||||||
{
|
{
|
||||||
uint32_t n;
|
uint32_t elt_cnt = 0;
|
||||||
uintptr_t va, uv;
|
phys_addr_t start, end;
|
||||||
size_t pg_sz, usz;
|
uint32_t paddr_idx;
|
||||||
|
size_t pg_sz = (size_t)1 << pg_shift;
|
||||||
|
|
||||||
pg_sz = (size_t)1 << pg_shift;
|
/* if paddr is NULL, assume contiguous memory */
|
||||||
va = (uintptr_t)vaddr;
|
if (paddr == NULL) {
|
||||||
uv = va;
|
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,
|
if (end - start >= total_elt_sz) {
|
||||||
paddr, pg_num, pg_shift, mempool_lelem_iter,
|
/* enough contiguous memory, add an object */
|
||||||
&uv)) != elt_num) {
|
start += total_elt_sz;
|
||||||
return -(ssize_t)n;
|
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);
|
return (size_t)paddr_idx << pg_shift;
|
||||||
usz = uv - va;
|
|
||||||
return usz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef RTE_LIBRTE_XEN_DOM0
|
#ifndef RTE_LIBRTE_XEN_DOM0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user