Skip to content
Browse files

11681 abd_alloc should use scatter for >1K allocations

Portions contributed by: Jerry Jelinek <>
Reviewed by: George Melikov <>
Reviewed by: DHE <>
Reviewed by: Chunwei Chen <>
Reviewed by: Brian Behlendorf <>
Reviewed by: Don Brady <>
Reviewed by: Andy Stormont <>
Reviewed by: Andy Fiddaman <>
Approved by: Dan McDonald <>
  • Loading branch information...
ahrens authored and jjelinek committed Nov 1, 2019
1 parent e5ace29 commit 87d7b64204c06f7d85b6dfec442ff0aba82efe9a
Showing with 27 additions and 2 deletions.
  1. +27 −2 usr/src/uts/common/fs/zfs/abd.c
@@ -11,7 +11,7 @@

* Copyright (c) 2014 by Chunwei Chen. All rights reserved.
* Copyright (c) 2016 by Delphix. All rights reserved.
* Copyright (c) 2019 by Delphix. All rights reserved.

@@ -140,6 +140,30 @@ static abd_stats_t abd_stats = {
boolean_t zfs_abd_scatter_enabled = B_TRUE;

* zfs_abd_scatter_min_size is the minimum allocation size to use scatter
* ABD's. Smaller allocations will use linear ABD's which uses
* zio_[data_]buf_alloc().
* Scatter ABD's use at least one page each, so sub-page allocations waste
* some space when allocated as scatter (e.g. 2KB scatter allocation wastes
* half of each page). Using linear ABD's for small allocations means that
* they will be put on slabs which contain many allocations. This can
* improve memory efficiency, but it also makes it much harder for ARC
* evictions to actually free pages, because all the buffers on one slab need
* to be freed in order for the slab (and underlying pages) to be freed.
* Typically, 512B and 1KB kmem caches have 16 buffers per slab, so it's
* possible for them to actually waste more memory than scatter (one page per
* buf = wasting 3/4 or 7/8th; one buf per slab = wasting 15/16th).
* Spill blocks are typically 512B and are heavily used on systems running
* selinux with the default dnode size and the `xattr=sa` property set.
* By default we use linear allocations for 512B and 1KB, and scatter
* allocations for larger (1.5KB and up).
int zfs_abd_scatter_min_size = 512 * 3;

* The size of the chunks ABD allocates. Because the sizes allocated from the
* kmem_cache can't change, this tunable can only be modified at boot. Changing
@@ -277,7 +301,8 @@ abd_free_struct(abd_t *abd)
abd_t *
abd_alloc(size_t size, boolean_t is_metadata)
if (!zfs_abd_scatter_enabled)
/* see the comment above zfs_abd_scatter_min_size */
if (!zfs_abd_scatter_enabled || size < zfs_abd_scatter_min_size)
return (abd_alloc_linear(size, is_metadata));


0 comments on commit 87d7b64

Please sign in to comment.
You can’t perform that action at this time.