Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

abd: lift ABD zero scan from zio_compress_data() to abd_cmp_zero() #16326

Merged
merged 1 commit into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/sys/abd.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ void abd_copy_from_buf_off(abd_t *, const void *, size_t, size_t);
void abd_copy_to_buf_off(void *, abd_t *, size_t, size_t);
int abd_cmp(abd_t *, abd_t *);
int abd_cmp_buf_off(abd_t *, const void *, size_t, size_t);
int abd_cmp_zero_off(abd_t *, size_t, size_t);
void abd_zero_off(abd_t *, size_t, size_t);
void abd_verify(abd_t *);

Expand Down Expand Up @@ -183,6 +184,12 @@ abd_zero(abd_t *abd, size_t size)
abd_zero_off(abd, 0, size);
}

static inline int
abd_cmp_zero(abd_t *abd, size_t size)
{
return (abd_cmp_zero_off(abd, 0, size));
}

/*
* ABD type check functions
*/
Expand Down
25 changes: 25 additions & 0 deletions module/zfs/abd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,31 @@ abd_cmp(abd_t *dabd, abd_t *sabd)
abd_cmp_cb, NULL));
}

/*
* Check if ABD content is all-zeroes.
*/
static int
abd_cmp_zero_off_cb(void *data, size_t len, void *private)
{
(void) private;

/* This function can only check whole uint64s. Enforce that. */
ASSERT0(P2PHASE(len, 8));

uint64_t *end = (uint64_t *)((char *)data + len);
for (uint64_t *word = (uint64_t *)data; word < end; word++)
if (*word != 0)
return (1);

return (0);
}

int
abd_cmp_zero_off(abd_t *abd, size_t off, size_t size)
{
return (abd_iterate_func(abd, off, size, abd_cmp_zero_off_cb, NULL));
}

/*
* Iterate over code ABDs and a data ABD and call @func_raidz_gen.
*
Expand Down
17 changes: 12 additions & 5 deletions module/zfs/zio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1854,8 +1854,13 @@ zio_write_compress(zio_t *zio)
if (compress != ZIO_COMPRESS_OFF &&
!(zio->io_flags & ZIO_FLAG_RAW_COMPRESS)) {
void *cbuf = NULL;
psize = zio_compress_data(compress, zio->io_abd, &cbuf, lsize,
zp->zp_complevel);
if (abd_cmp_zero(zio->io_abd, lsize) == 0)
psize = 0;
else if (compress == ZIO_COMPRESS_EMPTY)
psize = lsize;
else
psize = zio_compress_data(compress, zio->io_abd, &cbuf,
lsize, zp->zp_complevel);
if (psize == 0) {
compress = ZIO_COMPRESS_OFF;
} else if (psize >= lsize) {
Expand Down Expand Up @@ -1919,10 +1924,12 @@ zio_write_compress(zio_t *zio)
* receive, we must check whether the block can be compressed
* to a hole.
*/
psize = zio_compress_data(ZIO_COMPRESS_EMPTY,
zio->io_abd, NULL, lsize, zp->zp_complevel);
if (psize == 0 || psize >= lsize)
if (abd_cmp_zero(zio->io_abd, lsize) == 0) {
psize = 0;
compress = ZIO_COMPRESS_OFF;
} else {
psize = lsize;
}
} else if (zio->io_flags & ZIO_FLAG_RAW_COMPRESS &&
!(zio->io_flags & ZIO_FLAG_RAW_ENCRYPT)) {
/*
Expand Down
28 changes: 3 additions & 25 deletions module/zfs/zio_compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,6 @@ zio_compress_select(spa_t *spa, enum zio_compress child,
return (result);
}

static int
zio_compress_zeroed_cb(void *data, size_t len, void *private)
{
(void) private;

uint64_t *end = (uint64_t *)((char *)data + len);
for (uint64_t *word = (uint64_t *)data; word < end; word++)
if (*word != 0)
return (1);

return (0);
}

size_t
zio_compress_data(enum zio_compress c, abd_t *src, void **dst, size_t s_len,
uint8_t level)
Expand All @@ -132,18 +119,9 @@ zio_compress_data(enum zio_compress c, abd_t *src, void **dst, size_t s_len,
uint8_t complevel;
zio_compress_info_t *ci = &zio_compress_table[c];

ASSERT((uint_t)c < ZIO_COMPRESS_FUNCTIONS);
ASSERT((uint_t)c == ZIO_COMPRESS_EMPTY || ci->ci_compress != NULL);

/*
* If the data is all zeroes, we don't even need to allocate
* a block for it. We indicate this by returning zero size.
*/
if (abd_iterate_func(src, 0, s_len, zio_compress_zeroed_cb, NULL) == 0)
return (0);

if (c == ZIO_COMPRESS_EMPTY)
return (s_len);
ASSERT3U(c, <, ZIO_COMPRESS_FUNCTIONS);
ASSERT3U(ci->ci_compress, !=, NULL);
ASSERT3U(s_len, >, 0);

/* Compress at least 12.5% */
d_len = s_len - (s_len >> 3);
Expand Down
Loading