aboutsummaryrefslogtreecommitdiff
path: root/slof
diff options
context:
space:
mode:
authorThomas Huth <thuth@redhat.com>2016-09-05 11:28:23 +0200
committerAlexey Kardashevskiy <aik@ozlabs.ru>2016-09-14 15:47:50 +1000
commit73a13725a0b8a5e2d3974fc5da27d596e143e3d3 (patch)
tree3f999c532bf21c1caf916d945529161a7a69d300 /slof
parent87744e739d09d3b9b12754b15634f0ad1dd0a481 (diff)
downloadSLOF-73a13725a0b8a5e2d3974fc5da27d596e143e3d3.zip
SLOF-73a13725a0b8a5e2d3974fc5da27d596e143e3d3.tar.gz
SLOF-73a13725a0b8a5e2d3974fc5da27d596e143e3d3.tar.bz2
Improve SLOF_alloc_mem_aligned()
When loading a file via the spapr-vlan network interface, SLOF currently leaks quite a lot of memory, about 12kB each time. This happens mainly because veth_init() uses for example SLOF_alloc_mem_aligned(8192, 4096) and similar calls to get the memory, but the space for the additional alignment is never returned anymore later. An easy way to ease this situation is to improve SLOF_alloc_mem_aligned() a little bit. We normally get memory from SLOF_alloc_mem() which is aligned pretty well already, thanks to the buddy allocator in SLOF. So we can try to first get a memory block with the exact size first, and only do the alignment dance if the first allocation was not aligned yet. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Diffstat (limited to 'slof')
-rw-r--r--slof/helpers.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/slof/helpers.c b/slof/helpers.c
index 48c34a6..b049141 100644
--- a/slof/helpers.c
+++ b/slof/helpers.c
@@ -69,9 +69,14 @@ void *SLOF_alloc_mem(long size)
void *SLOF_alloc_mem_aligned(long size, long align)
{
- unsigned long addr = (unsigned long)SLOF_alloc_mem(size + align - 1);
- addr = addr + align - 1;
- addr = addr & ~(align - 1);
+ unsigned long addr = (unsigned long)SLOF_alloc_mem(size);
+
+ if (addr % align) {
+ SLOF_free_mem((void *)addr, size);
+ addr = (unsigned long)SLOF_alloc_mem(size + align - 1);
+ addr = addr + align - 1;
+ addr = addr & ~(align - 1);
+ }
return (void *)addr;
}