git: hammer2 - Fix excess chain structure allocations during bulkfree (3)

2022-03-11 Thread Matthew Dillon


commit f7a9ce16252aa547c85ff84ec40272848e5587bd
Author: Matthew Dillon 
Date:   Fri Mar 11 17:18:38 2022 -0800

hammer2 - Fix excess chain structure allocations during bulkfree (3)

* Fix excess chain structure allocations during bulkfree, AGAIN.
  This time for real.  The algorithmic change I made was not sufficient,
  because I was not backing-out the recursion all the way after hitting
  a deferral.  Instead, the code was re-recursing down another branch
  while still really deep into the tree.

  The problem was mostly triggered on the inode radix tree for filesystems
  containing many inodes (like a hundred million inodes), and would lead
  to a kmalloc panic due to memory exhaustion.

* Fixed for real this time.  When we hit the recursion limit, the code
  fully backs out of the traversal (recording its placemarkers on the way
  back up), then starts again at the deepest placemarker rather than
  the shallowest placemarker.

Summary of changes:
 sys/vfs/hammer2/hammer2_bulkfree.c | 39 --
 1 file changed, 37 insertions(+), 2 deletions(-)

http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/f7a9ce16252aa547c85ff84ec40272848e5587bd


-- 
DragonFly BSD source repository


git: hammer2 - Fix excess chain structure allocations during bulkfree (2)

2022-01-23 Thread Matthew Dillon


commit 784d105b6000afc68e4b26e8acf5b4d6a79ea1f7
Author: Matthew Dillon 
Date:   Fri Jan 14 12:55:36 2022 -0800

hammer2 - Fix excess chain structure allocations during bulkfree (2)

Try to fix this again.  The last attempt failed.  Basically the
problem is that when the depth-first traversal gets too deep, it
has to defer the node at that point by adding it to a list.

* Change the order to insert deferrals on the head instead of the
  tail in order to exhaust the most recently deferred sub-tree as
  quickly as possible (LIFO order).  We previously exhausted deferred
  sub-trees in FIFO order but this often resulted in multiple levels
  of the radix tree building up on the list, which could blow-up
  memory use.

* Once the list limit is reached (well, really 1/4 of the list limit),
  we previously continued to accumulate deferral as long as the
  relative depth was less then 3.  Unfortunately, the maximum radix
  tree table size of roughly 512 elements could cause the number
  of deferrals even after the limit was reached to be up to
  134 million chains (512 * 512 * 512).

  This is fixed by removing any depth test when the list limit is
  exhausted.

* This combination of fixes should prevent the number of deferrals
  from blowing out hammer2's kmalloc pool.  Theoretically the
  worst-case possible deferrals should now be 512 chains x max depth
  of radix tree.  A very reasonable number.

Summary of changes:
 sys/vfs/hammer2/hammer2.h  |  1 +
 sys/vfs/hammer2/hammer2_bulkfree.c | 51 --
 sys/vfs/hammer2/hammer2_vfsops.c   |  3 +++
 3 files changed, 42 insertions(+), 13 deletions(-)

http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/784d105b6000afc68e4b26e8acf5b4d6a79ea1f7


-- 
DragonFly BSD source repository


git: hammer2 - Fix excess chain structure allocations during bulkfree

2022-01-07 Thread Matthew Dillon


commit 1dddac0a529e5053f361fc4614980b4cba145a61
Author: Matthew Dillon 
Date:   Fri Jan 7 16:41:35 2022 -0800

hammer2 - Fix excess chain structure allocations during bulkfree

* On H2 filesystems with a very large number of inodes, such as
  those used for backups or which contain many snapshots (e.g.
  tens of millions of inodes), the bulkfree process may attempt
  to track more hammer2_chain structures than the kmalloc subsystem
  allows.

* This issue might also have contributed to reported lockups during
  bulkfree (if the bulkfree wound up eating too much non-pagable kernel
  memory), though the more typical outcome is a kernel panic when
  the kmalloc limit is exceeded for the pool.

* During bulkfree, H2 must control recursion depth during the scan.
  It does this by deferring deep nodes in the topology by recording
  a pointer to a referenced hammer2_chain structure on a list.
  Once the recursion backs out, H2 then processes these saved chains.
  Topologies greater than 32 nodes deep can wind up being deferred
  more than once to cover the entire depth.

  It is possible for an excessive number of chains to accumulate on the
  deferral list during the scan, each structure burning up kernel memory.

* Emplace a limit on the number of chains which can be deferred,
  vfs.hammer2.limit_saved_chains, with a reasonable default.  When
  the limit is reached, the bulkfree simply records a chain higher-up
  in the recursion instead of going deeper, thus limiting the number
  of chains that will be deferred.

  This has the effect is capping memory use during the bulkfree scan.
  The cost is slightly less scan efficiency, but it should mostly be in
  the noise.

Summary of changes:
 sys/vfs/hammer2/hammer2.h  |  1 +
 sys/vfs/hammer2/hammer2_bulkfree.c | 28 +++-
 sys/vfs/hammer2/hammer2_vfsops.c   |  5 +
 3 files changed, 33 insertions(+), 1 deletion(-)

http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/1dddac0a529e5053f361fc4614980b4cba145a61


-- 
DragonFly BSD source repository