Commit Graph

13 Commits

Author SHA1 Message Date
Willy Tarreau
a885f6dc65 MEDIUM: memory: improve pool_refill_alloc() to pass a refill count
Till now this function would only allocate one entry at a time. But with
dynamic buffers we'll like to allocate the number of missing entries to
properly refill the pool.

Let's modify it to take a minimum amount of available entries. This means
that when we know we need at least a number of available entries, we can
ask to allocate all of them at once. It also ensures that we don't move
the pointers back and forth between the caller and the pool, and that we
don't call pool_gc2() for each failed malloc. Instead, it's called only
once and the malloc is only allowed to fail once.
2014-12-24 23:47:31 +01:00
Willy Tarreau
0262241e26 MINOR: memory: cut pool allocator in 3 layers
pool_alloc2() used to pick the entry from the pool, fall back to
pool_refill_alloc(), and to perform the poisonning itself, which
pool_refill_alloc() was also doing. While this led to optimal
code size, it imposes memory poisonning on the buffers as well,
which is extremely slow on large buffers.

This patch cuts the allocator in 3 layers :
  - a layer to pick the first entry from the pool without falling back to
    pool_refill_alloc() : pool_get_first()
  - a layer to allocate a dirty area by falling back to pool_refill_alloc()
    but never performing the poisonning : pool_alloc_dirty()
  - pool_alloc2() which calls the latter and optionally poisons the area

No functional changes were made.
2014-12-24 23:47:31 +01:00
Willy Tarreau
57767b8032 BUG/MEDIUM: memory: fix freeing logic in pool_gc2()
There's a long-standing bug in pool_gc2(). It tries to protect the pool
against releasing of too many entries but the formula is wrong as it
compares allocated to minavail instead of (allocated-used) to minavail.
Under memory contention, it ends up releasing more than what is granted
by minavail and causes trouble to the dynamic buffer allocator.

This bug is in fact major by itself, but since minavail has never been
used till now, there is no impact at least in mainline. A backport to
1.5 is desired anyway in case any future backport or out-of-tree patch
relies on this.
2014-12-23 11:22:57 +01:00
Willy Tarreau
12833bbca5 MINOR: cli: add the new "show pools" command
show pools
  Dump the status of internal memory pools. This is useful to track memory
  usage when suspecting a memory leak for example. It does exactly the same
  as the SIGQUIT when running in foreground except that it does not flush
  the pools.
2014-01-28 16:50:35 +01:00
Willy Tarreau
6e0644339f MEDIUM: memory: add the ability to poison memory at run time
From time to time, some bugs are discovered that are caused by non-initialized
memory areas. It happens that most platforms return a zero-filled area upon
first malloc() thus hiding potential bugs. This patch also replaces malloc()
in pools with calloc() to ensure that all platforms exhibit the same behaviour
upon startup. In order to catch these bugs more easily, add a -dM command line
flag to enable memory poisonning. Optionally, passing -dM<byte> forces the
poisonning byte to <byte>.
2012-05-08 21:28:16 +02:00
Willy Tarreau
b7f9d126e2 [MEDIUM] ensure we don't recursively call pool_gc2()
A race condition exists in the hot reconfiguration code. It is
theorically possible that the second signal is sent during a free()
in the first list, which can cause crashes or freezes (the later
have been observed). Just set up a counter to ensure we do not
recurse.
2009-04-21 02:17:45 +02:00
Willy Tarreau
1772ece025 [MINOR] fix several printf formats and missing arguments
Last patch revealed a number of mistakes in printf-like calls, mostly int/long
mismatches, and a few missing arguments.
2009-04-03 14:49:12 +02:00
Krzysztof Piotr Oledzki
a643baf091 [MEDIUM] Fix memory freeing at exit
New functions implemented:
 - deinit_pollers: called at the end of deinit())
 - prune_acl: called via list_for_each_entry_safe

Add missing pool_destroy2 calls:
 - p->hdr_idx_pool
 - pool2_tree64

Implement all task stopping:
 - health-check: needs new "struct task" in the struct server
 - queue processing: queue_mgt
 - appsess_refresh: appsession_refresh

before (idle system):
==6079== LEAK SUMMARY:
==6079==    definitely lost: 1,112 bytes in 75 blocks.
==6079==    indirectly lost: 53,356 bytes in 2,090 blocks.
==6079==      possibly lost: 52 bytes in 1 blocks.
==6079==    still reachable: 150,996 bytes in 504 blocks.
==6079==         suppressed: 0 bytes in 0 blocks.

after (idle system):
==6945== LEAK SUMMARY:
==6945==    definitely lost: 7,644 bytes in 137 blocks.
==6945==    indirectly lost: 9,913 bytes in 587 blocks.
==6945==      possibly lost: 0 bytes in 0 blocks.
==6945==    still reachable: 0 bytes in 0 blocks.
==6945==         suppressed: 0 bytes in 0 blocks.

before (running system for ~2m):
==9343== LEAK SUMMARY:
==9343==    definitely lost: 1,112 bytes in 75 blocks.
==9343==    indirectly lost: 54,199 bytes in 2,122 blocks.
==9343==      possibly lost: 52 bytes in 1 blocks.
==9343==    still reachable: 151,128 bytes in 509 blocks.
==9343==         suppressed: 0 bytes in 0 blocks.

after (running system for ~2m):
==11616== LEAK SUMMARY:
==11616==    definitely lost: 7,644 bytes in 137 blocks.
==11616==    indirectly lost: 9,981 bytes in 591 blocks.
==11616==      possibly lost: 0 bytes in 0 blocks.
==11616==    still reachable: 4 bytes in 1 blocks.
==11616==         suppressed: 0 bytes in 0 blocks.

Still not perfect but significant improvement.
2008-05-30 07:07:19 +02:00
Willy Tarreau
dae4aa8c4a [BUG] fix segfault at exit when using captures
since pools v2, the way pools were destroyed at exit is incorrect
because it ought to account for users of those pools before freeing
them. This test also ensures there is no double free.
2007-06-16 23:19:53 +02:00
Willy Tarreau
4d2d098ea3 [MAJOR] call garbage collector when doing soft stop
When we're interrupted by another instance, it is very likely
that the other one will need some memory. Now we know how to
free what is not used, so let's do it.

Also only free non-null pointers. Previously, pool_destroy()
did implicitly check for this case which was incidentely
needed.
2007-05-14 00:39:29 +02:00
Willy Tarreau
7dcd46d471 [MEDIUM] enhance behaviour of mempools v2
- keep the number of users of each pool
- call the garbage collector on out of memory conditions
- sort the pools by size for faster creation
- force the alignment size to 16 bytes instead of 4*sizeof(void *)
2007-05-14 00:16:13 +02:00
Willy Tarreau
e6ce59deb7 [MEDIUM] add new memory management functions
Implement pool_destroy2, pool_flush2, pool_gc2. It is safe to call
pool_gc2 to free whatever memory possible.
2007-05-13 19:38:49 +02:00
Willy Tarreau
50e608d721 [MEDIUM] implement memory pools version 2
The new pools know about their size and usage. Malloc is not used
anymore, instead a dedicated function to refill the entries is used.
2007-05-13 18:26:08 +02:00