Skip to content

Commit

Permalink
FreeBSD: Optimize large kstat outputs
Browse files Browse the repository at this point in the history
- Use sbuf_new_for_sysctl() to reduce double-buffering on sysctl
output.
- Use much faster sbuf_cat() instead of sbuf_printf("%s").

Together it reduces `sysctl kstat.zfs.misc.dbufs` time from minutes
to seconds, making dbufstat almost usable.

Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Alexander Motin <[email protected]>
Sponsored by: iXsystems, Inc.
Closes #15495
  • Loading branch information
amotin authored Nov 7, 2023
1 parent e36ff84 commit 58398cb
Showing 1 changed file with 16 additions and 22 deletions.
38 changes: 16 additions & 22 deletions module/os/freebsd/spl/spl_kstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,45 +187,40 @@ kstat_sysctl_dataset_string(SYSCTL_HANDLER_ARGS)
static int
kstat_sysctl_io(SYSCTL_HANDLER_ARGS)
{
struct sbuf *sb;
struct sbuf sb;
kstat_t *ksp = arg1;
kstat_io_t *kip = ksp->ks_data;
int rc;

sb = sbuf_new_auto();
if (sb == NULL)
return (ENOMEM);
sbuf_new_for_sysctl(&sb, NULL, 0, req);

/* Update the aggsums before reading */
(void) ksp->ks_update(ksp, KSTAT_READ);

/* though wlentime & friends are signed, they will never be negative */
sbuf_printf(sb,
sbuf_printf(&sb,
"%-8llu %-8llu %-8u %-8u %-8llu %-8llu "
"%-8llu %-8llu %-8llu %-8llu %-8u %-8u\n",
kip->nread, kip->nwritten,
kip->reads, kip->writes,
kip->wtime, kip->wlentime, kip->wlastupdate,
kip->rtime, kip->rlentime, kip->rlastupdate,
kip->wcnt, kip->rcnt);
rc = sbuf_finish(sb);
if (rc == 0)
rc = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb));
sbuf_delete(sb);
rc = sbuf_finish(&sb);
sbuf_delete(&sb);
return (rc);
}

static int
kstat_sysctl_raw(SYSCTL_HANDLER_ARGS)
{
struct sbuf *sb;
struct sbuf sb;
void *data;
kstat_t *ksp = arg1;
void *(*addr_op)(kstat_t *ksp, loff_t index);
int n, has_header, rc = 0;

sb = sbuf_new_auto();
if (sb == NULL)
return (ENOMEM);
sbuf_new_for_sysctl(&sb, NULL, PAGE_SIZE, req);

if (ksp->ks_raw_ops.addr)
addr_op = ksp->ks_raw_ops.addr;
Expand Down Expand Up @@ -258,8 +253,10 @@ kstat_sysctl_raw(SYSCTL_HANDLER_ARGS)
if (has_header) {
if (rc == ENOMEM && !kstat_resize_raw(ksp))
goto restart_headers;
if (rc == 0)
sbuf_printf(sb, "\n%s", ksp->ks_raw_buf);
if (rc == 0) {
sbuf_cat(&sb, "\n");
sbuf_cat(&sb, ksp->ks_raw_buf);
}
}

while ((data = addr_op(ksp, n)) != NULL) {
Expand All @@ -270,22 +267,19 @@ kstat_sysctl_raw(SYSCTL_HANDLER_ARGS)
if (rc == ENOMEM && !kstat_resize_raw(ksp))
goto restart;
if (rc == 0)
sbuf_printf(sb, "%s", ksp->ks_raw_buf);
sbuf_cat(&sb, ksp->ks_raw_buf);

} else {
ASSERT3U(ksp->ks_ndata, ==, 1);
sbuf_hexdump(sb, ksp->ks_data,
sbuf_hexdump(&sb, ksp->ks_data,
ksp->ks_data_size, NULL, 0);
}
n++;
}
free(ksp->ks_raw_buf, M_TEMP);
mutex_exit(ksp->ks_lock);
sbuf_trim(sb);
rc = sbuf_finish(sb);
if (rc == 0)
rc = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb));
sbuf_delete(sb);
rc = sbuf_finish(&sb);
sbuf_delete(&sb);
return (rc);
}

Expand Down

0 comments on commit 58398cb

Please sign in to comment.