diff options
| author | George Wilson <george.wilson@delphix.com> | 2016-07-13 14:31:56 -0700 |
|---|---|---|
| committer | Matthew Ahrens <mahrens@delphix.com> | 2016-07-14 11:55:57 -0700 |
| commit | dcbf3bd6a1f1360fc1afcee9e22c6dcff7844bf2 (patch) | |
| tree | a4098fece7aa93244ddc9d2acfd8c9529e878a81 /usr/src/cmd | |
| parent | a5dce49383b67bfd3a81999460d579f53a67c029 (diff) | |
| download | illumos-joyent-dcbf3bd6a1f1360fc1afcee9e22c6dcff7844bf2.tar.gz | |
6950 ARC should cache compressed data
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Don Brady <don.brady@intel.com>
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src/cmd')
| -rw-r--r-- | usr/src/cmd/mdb/common/mdb/mdb_ctf.c | 20 | ||||
| -rw-r--r-- | usr/src/cmd/mdb/common/mdb/mdb_ctf.h | 3 | ||||
| -rw-r--r-- | usr/src/cmd/mdb/common/modules/conf/mapfile-extern | 3 | ||||
| -rw-r--r-- | usr/src/cmd/mdb/common/modules/zfs/zfs.c | 429 | ||||
| -rw-r--r-- | usr/src/cmd/zdb/zdb.c | 2 | ||||
| -rw-r--r-- | usr/src/cmd/ztest/ztest.c | 7 |
6 files changed, 459 insertions, 5 deletions
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c index 66a8b009a3..8b8b72fd53 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ /* - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013, 2015 by Delphix. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ @@ -910,6 +910,24 @@ mdb_ctf_offsetof_by_name(const char *type, const char *member) return (off); } +ssize_t +mdb_ctf_sizeof_by_name(const char *type) +{ + mdb_ctf_id_t id; + ssize_t size; + + if (mdb_ctf_lookup_by_name(type, &id) == -1) { + mdb_warn("couldn't find type %s", type); + return (-1); + } + + if ((size = mdb_ctf_type_size(id)) == -1) { + mdb_warn("couldn't determine type size of %s", type); + return (-1); + } + + return (size); +} /*ARGSUSED*/ static int diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ctf.h b/usr/src/cmd/mdb/common/mdb/mdb_ctf.h index 85e60494d0..21f27d782b 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_ctf.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_ctf.h @@ -23,7 +23,7 @@ * Use is subject to license terms. */ /* - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2013, 2015 by Delphix. All rights reserved. * Copyright (c) 2015, Joyent, Inc. */ @@ -136,6 +136,7 @@ extern int mdb_ctf_member_info(mdb_ctf_id_t, const char *, extern int mdb_ctf_offsetof(mdb_ctf_id_t, const char *, ulong_t *); extern int mdb_ctf_num_members(mdb_ctf_id_t); extern int mdb_ctf_offsetof_by_name(const char *, const char *); +extern ssize_t mdb_ctf_sizeof_by_name(const char *); extern ssize_t mdb_ctf_offset_to_name(mdb_ctf_id_t, ulong_t, char *, size_t, int, mdb_ctf_id_t *, ulong_t *); diff --git a/usr/src/cmd/mdb/common/modules/conf/mapfile-extern b/usr/src/cmd/mdb/common/modules/conf/mapfile-extern index 2491a7a8d5..73de8f1e41 100644 --- a/usr/src/cmd/mdb/common/modules/conf/mapfile-extern +++ b/usr/src/cmd/mdb/common/modules/conf/mapfile-extern @@ -1,6 +1,6 @@ # # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright (c) 2013 by Delphix. All rights reserved. +# Copyright (c) 2013, 2015 by Delphix. All rights reserved. # # CDDL HEADER START # @@ -67,6 +67,7 @@ SYMBOL_SCOPE { mdb_ctf_module_lookup { FLAGS = EXTERN }; mdb_ctf_offsetof { FLAGS = EXTERN }; mdb_ctf_offsetof_by_name { FLAGS = EXTERN }; + mdb_ctf_sizeof_by_name { FLAGS = EXTERN }; mdb_ctf_readsym { FLAGS = EXTERN }; mdb_ctf_type_cmp { FLAGS = EXTERN }; mdb_ctf_type_invalidate { FLAGS = EXTERN }; diff --git a/usr/src/cmd/mdb/common/modules/zfs/zfs.c b/usr/src/cmd/mdb/common/modules/zfs/zfs.c index 697349b020..12f26d382c 100644 --- a/usr/src/cmd/mdb/common/modules/zfs/zfs.c +++ b/usr/src/cmd/mdb/common/modules/zfs/zfs.c @@ -42,6 +42,7 @@ #include <ctype.h> #include <sys/zfs_acl.h> #include <sys/sa_impl.h> +#include <sys/multilist.h> #ifdef _KERNEL #define ZFS_OBJ_NAME "zfs" @@ -973,6 +974,7 @@ arc_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) "mfu_ghost_evictable_metadata", "evict_l2_cached", "evict_l2_eligible", "evict_l2_ineligible", "l2_read_bytes", "l2_write_bytes", "l2_size", "l2_asize", "l2_hdr_size", + "compressed_size", "uncompressed_size", "overhead_size", NULL }; @@ -1655,7 +1657,6 @@ metaslab_walk_step(mdb_walk_state_t *wsp) return (wsp->walk_callback(msp, &ms, wsp->walk_cbdata)); } -/* ARGSUSED */ static int metaslab_walk_init(mdb_walk_state_t *wsp) { @@ -2183,6 +2184,69 @@ zio_state(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (mdb_pwalk_dcmd("zio_root", "zio", argc, argv, addr)); } +typedef struct mdb_multilist { + uint64_t ml_num_sublists; + uintptr_t ml_sublists; +} mdb_multilist_t; + +typedef struct multilist_walk_data { + uint64_t mwd_idx; + mdb_multilist_t mwd_ml; +} multilist_walk_data_t; + +/* ARGSUSED */ +static int +multilist_print_cb(uintptr_t addr, const void *unknown, void *arg) +{ + mdb_printf("%#lr\n", addr); + return (WALK_NEXT); +} + +static int +multilist_walk_step(mdb_walk_state_t *wsp) +{ + multilist_walk_data_t *mwd = wsp->walk_data; + + if (mwd->mwd_idx >= mwd->mwd_ml.ml_num_sublists) + return (WALK_DONE); + + wsp->walk_addr = mwd->mwd_ml.ml_sublists + + mdb_ctf_sizeof_by_name("multilist_sublist_t") * mwd->mwd_idx + + mdb_ctf_offsetof_by_name("multilist_sublist_t", "mls_list"); + + mdb_pwalk("list", multilist_print_cb, (void*)NULL, wsp->walk_addr); + mwd->mwd_idx++; + + return (WALK_NEXT); +} + +static int +multilist_walk_init(mdb_walk_state_t *wsp) +{ + multilist_walk_data_t *mwd; + + if (wsp->walk_addr == NULL) { + mdb_warn("must supply address of multilist_t\n"); + return (WALK_ERR); + } + + mwd = mdb_zalloc(sizeof (multilist_walk_data_t), UM_SLEEP | UM_GC); + if (mdb_ctf_vread(&mwd->mwd_ml, "multilist_t", "mdb_multilist_t", + wsp->walk_addr, 0) == -1) { + return (WALK_ERR); + } + + if (mwd->mwd_ml.ml_num_sublists == 0 || + mwd->mwd_ml.ml_sublists == NULL) { + mdb_warn("invalid or uninitialized multilist at %#lx\n", + wsp->walk_addr); + return (WALK_ERR); + } + + wsp->walk_data = mwd; + return (WALK_NEXT); +} + typedef struct txg_list_walk_data { uintptr_t lw_head[TXG_SIZE]; int lw_txgoff; @@ -3269,6 +3333,359 @@ rrwlock(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (DCMD_OK); } +typedef struct mdb_arc_buf_hdr_t { + uint16_t b_psize; + uint16_t b_lsize; + struct { + uint32_t b_bufcnt; + uintptr_t b_state; + uintptr_t b_pdata; + } b_l1hdr; +} mdb_arc_buf_hdr_t; + +enum arc_cflags { + ARC_CFLAG_VERBOSE = 1 << 0, + ARC_CFLAG_ANON = 1 << 1, + ARC_CFLAG_MRU = 1 << 2, + ARC_CFLAG_MFU = 1 << 3, + ARC_CFLAG_BUFS = 1 << 4, +}; + +typedef struct arc_compression_stats_data { + GElf_Sym anon_sym; /* ARC_anon symbol */ + GElf_Sym mru_sym; /* ARC_mru symbol */ + GElf_Sym mrug_sym; /* ARC_mru_ghost symbol */ + GElf_Sym mfu_sym; /* ARC_mfu symbol */ + GElf_Sym mfug_sym; /* ARC_mfu_ghost symbol */ + GElf_Sym l2c_sym; /* ARC_l2c_only symbol */ + uint64_t *anon_c_hist; /* histogram of compressed sizes in anon */ + uint64_t *anon_u_hist; /* histogram of uncompressed sizes in anon */ + uint64_t *anon_bufs; /* histogram of buffer counts in anon state */ + uint64_t *mru_c_hist; /* histogram of compressed sizes in mru */ + uint64_t *mru_u_hist; /* histogram of uncompressed sizes in mru */ + uint64_t *mru_bufs; /* histogram of buffer counts in mru */ + uint64_t *mfu_c_hist; /* histogram of compressed sizes in mfu */ + uint64_t *mfu_u_hist; /* histogram of uncompressed sizes in mfu */ + uint64_t *mfu_bufs; /* histogram of buffer counts in mfu */ + uint64_t *all_c_hist; /* histogram of compressed anon + mru + mfu */ + uint64_t *all_u_hist; /* histogram of uncompressed anon + mru + mfu */ + uint64_t *all_bufs; /* histogram of buffer counts in all states */ + int arc_cflags; /* arc compression flags, specified by user */ + int hist_nbuckets; /* number of buckets in each histogram */ +} arc_compression_stats_data_t; + +int +highbit64(uint64_t i) +{ + int h = 1; + + if (i == 0) + return (0); + if (i & 0xffffffff00000000ULL) { + h += 32; i >>= 32; + } + if (i & 0xffff0000) { + h += 16; i >>= 16; + } + if (i & 0xff00) { + h += 8; i >>= 8; + } + if (i & 0xf0) { + h += 4; i >>= 4; + } + if (i & 0xc) { + h += 2; i >>= 2; + } + if (i & 0x2) { + h += 1; + } + return (h); +} + +/* ARGSUSED */ +static int +arc_compression_stats_cb(uintptr_t addr, const void *unknown, void *arg) +{ + arc_compression_stats_data_t *data = arg; + mdb_arc_buf_hdr_t hdr; + int cbucket, ubucket, bufcnt; + + if (mdb_ctf_vread(&hdr, "arc_buf_hdr_t", "mdb_arc_buf_hdr_t", + addr, 0) == -1) { + return (WALK_ERR); + } + + /* + * Headers in the ghost states, or the l2c_only state don't have + * arc buffers linked off of them. Thus, their compressed size + * is meaningless, so we skip these from the stats. + */ + if (hdr.b_l1hdr.b_state == data->mrug_sym.st_value || + hdr.b_l1hdr.b_state == data->mfug_sym.st_value || + hdr.b_l1hdr.b_state == data->l2c_sym.st_value) { + return (WALK_NEXT); + } + + /* + * The physical size (compressed) and logical size + * (uncompressed) are in units of SPA_MINBLOCKSIZE. By default, + * we use the log2 of this value (rounded down to the nearest + * integer) to determine the bucket to assign this header to. + * Thus, the histogram is logarithmic with respect to the size + * of the header. For example, the following is a mapping of the + * bucket numbers and the range of header sizes they correspond to: + * + * 0: 0 byte headers + * 1: 512 byte headers + * 2: [1024 - 2048) byte headers + * 3: [2048 - 4096) byte headers + * 4: [4096 - 8192) byte headers + * 5: [8192 - 16394) byte headers + * 6: [16384 - 32768) byte headers + * 7: [32768 - 65536) byte headers + * 8: [65536 - 131072) byte headers + * 9: 131072 byte headers + * + * If the ARC_CFLAG_VERBOSE flag was specified, we use the + * physical and logical sizes directly. Thus, the histogram will + * no longer be logarithmic; instead it will be linear with + * respect to the size of the header. The following is a mapping + * of the first many bucket numbers and the header size they + * correspond to: + * + * 0: 0 byte headers + * 1: 512 byte headers + * 2: 1024 byte headers + * 3: 1536 byte headers + * 4: 2048 byte headers + * 5: 2560 byte headers + * 6: 3072 byte headers + * + * And so on. Keep in mind that a range of sizes isn't used in + * the case of linear scale because the headers can only + * increment or decrement in sizes of 512 bytes. So, it's not + * possible for a header to be sized in between whats listed + * above. + * + * Also, the above mapping values were calculated assuming a + * SPA_MINBLOCKSHIFT of 512 bytes and a SPA_MAXBLOCKSIZE of 128K. + */ + + if (data->arc_cflags & ARC_CFLAG_VERBOSE) { + cbucket = hdr.b_psize; + ubucket = hdr.b_lsize; + } else { + cbucket = highbit64(hdr.b_psize); + ubucket = highbit64(hdr.b_lsize); + } + + bufcnt = hdr.b_l1hdr.b_bufcnt; + if (bufcnt >= data->hist_nbuckets) + bufcnt = data->hist_nbuckets - 1; + + /* Ensure we stay within the bounds of the histogram array */ + ASSERT3U(cbucket, <, data->hist_nbuckets); + ASSERT3U(ubucket, <, data->hist_nbuckets); + + if (hdr.b_l1hdr.b_state == data->anon_sym.st_value) { + data->anon_c_hist[cbucket]++; + data->anon_u_hist[ubucket]++; + data->anon_bufs[bufcnt]++; + } else if (hdr.b_l1hdr.b_state == data->mru_sym.st_value) { + data->mru_c_hist[cbucket]++; + data->mru_u_hist[ubucket]++; + data->mru_bufs[bufcnt]++; + } else if (hdr.b_l1hdr.b_state == data->mfu_sym.st_value) { + data->mfu_c_hist[cbucket]++; + data->mfu_u_hist[ubucket]++; + data->mfu_bufs[bufcnt]++; + } + + data->all_c_hist[cbucket]++; + data->all_u_hist[ubucket]++; + data->all_bufs[bufcnt]++; + + return (WALK_NEXT); +} + +/* ARGSUSED */ +static int +arc_compression_stats(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + arc_compression_stats_data_t data = { 0 }; + unsigned int max_shifted = SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; + unsigned int hist_size; + char range[32]; + int rc = DCMD_OK; + + if (mdb_getopts(argc, argv, + 'v', MDB_OPT_SETBITS, ARC_CFLAG_VERBOSE, &data.arc_cflags, + 'a', MDB_OPT_SETBITS, ARC_CFLAG_ANON, &data.arc_cflags, + 'b', MDB_OPT_SETBITS, ARC_CFLAG_BUFS, &data.arc_cflags, + 'r', MDB_OPT_SETBITS, ARC_CFLAG_MRU, &data.arc_cflags, + 'f', MDB_OPT_SETBITS, ARC_CFLAG_MFU, &data.arc_cflags) != argc) + return (DCMD_USAGE); + + if (mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_anon", &data.anon_sym) || + mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_mru", &data.mru_sym) || + mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_mru_ghost", &data.mrug_sym) || + mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_mfu", &data.mfu_sym) || + mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_mfu_ghost", &data.mfug_sym) || + mdb_lookup_by_obj(ZFS_OBJ_NAME, "ARC_l2c_only", &data.l2c_sym)) { + mdb_warn("can't find arc state symbol"); + return (DCMD_ERR); + } + + /* + * Determine the maximum expected size for any header, and use + * this to determine the number of buckets needed for each + * histogram. If ARC_CFLAG_VERBOSE is specified, this value is + * used directly; otherwise the log2 of the maximum size is + * used. Thus, if using a log2 scale there's a maximum of 10 + * possible buckets, while the linear scale (when using + * ARC_CFLAG_VERBOSE) has a maximum of 257 buckets. + */ + if (data.arc_cflags & ARC_CFLAG_VERBOSE) + data.hist_nbuckets = max_shifted + 1; + else + data.hist_nbuckets = highbit64(max_shifted) + 1; + + hist_size = sizeof (uint64_t) * data.hist_nbuckets; + + data.anon_c_hist = mdb_zalloc(hist_size, UM_SLEEP); + data.anon_u_hist = mdb_zalloc(hist_size, UM_SLEEP); + data.anon_bufs = mdb_zalloc(hist_size, UM_SLEEP); + + data.mru_c_hist = mdb_zalloc(hist_size, UM_SLEEP); + data.mru_u_hist = mdb_zalloc(hist_size, UM_SLEEP); + data.mru_bufs = mdb_zalloc(hist_size, UM_SLEEP); + + data.mfu_c_hist = mdb_zalloc(hist_size, UM_SLEEP); + data.mfu_u_hist = mdb_zalloc(hist_size, UM_SLEEP); + data.mfu_bufs = mdb_zalloc(hist_size, UM_SLEEP); + + data.all_c_hist = mdb_zalloc(hist_size, UM_SLEEP); + data.all_u_hist = mdb_zalloc(hist_size, UM_SLEEP); + data.all_bufs = mdb_zalloc(hist_size, UM_SLEEP); + + if (mdb_walk("arc_buf_hdr_t_full", arc_compression_stats_cb, + &data) != 0) { + mdb_warn("can't walk arc_buf_hdr's"); + rc = DCMD_ERR; + goto out; + } + + if (data.arc_cflags & ARC_CFLAG_VERBOSE) { + rc = mdb_snprintf(range, sizeof (range), + "[n*%llu, (n+1)*%llu)", SPA_MINBLOCKSIZE, + SPA_MINBLOCKSIZE); + } else { + rc = mdb_snprintf(range, sizeof (range), + "[2^(n-1)*%llu, 2^n*%llu)", SPA_MINBLOCKSIZE, + SPA_MINBLOCKSIZE); + } + + if (rc < 0) { + /* snprintf failed, abort the dcmd */ + rc = DCMD_ERR; + goto out; + } else { + /* snprintf succeeded above, reset return code */ + rc = DCMD_OK; + } + + if (data.arc_cflags & ARC_CFLAG_ANON) { + if (data.arc_cflags & ARC_CFLAG_BUFS) { + mdb_printf("Histogram of the number of anon buffers " + "that are associated with an arc hdr.\n"); + dump_histogram(data.anon_bufs, data.hist_nbuckets, 0); + mdb_printf("\n"); + } + mdb_printf("Histogram of compressed anon buffers.\n" + "Each bucket represents buffers of size: %s.\n", range); + dump_histogram(data.anon_c_hist, data.hist_nbuckets, 0); + mdb_printf("\n"); + + mdb_printf("Histogram of uncompressed anon buffers.\n" + "Each bucket represents buffers of size: %s.\n", range); + dump_histogram(data.anon_u_hist, data.hist_nbuckets, 0); + mdb_printf("\n"); + } + + if (data.arc_cflags & ARC_CFLAG_MRU) { + if (data.arc_cflags & ARC_CFLAG_BUFS) { + mdb_printf("Histogram of the number of mru buffers " + "that are associated with an arc hdr.\n"); + dump_histogram(data.mru_bufs, data.hist_nbuckets, 0); + mdb_printf("\n"); + } + mdb_printf("Histogram of compressed mru buffers.\n" + "Each bucket represents buffers of size: %s.\n", range); + dump_histogram(data.mru_c_hist, data.hist_nbuckets, 0); + mdb_printf("\n"); + + mdb_printf("Histogram of uncompressed mru buffers.\n" + "Each bucket represents buffers of size: %s.\n", range); + dump_histogram(data.mru_u_hist, data.hist_nbuckets, 0); + mdb_printf("\n"); + } + + if (data.arc_cflags & ARC_CFLAG_MFU) { + if (data.arc_cflags & ARC_CFLAG_BUFS) { + mdb_printf("Histogram of the number of mfu buffers " + "that are associated with an arc hdr.\n"); + dump_histogram(data.mfu_bufs, data.hist_nbuckets, 0); + mdb_printf("\n"); + } + + mdb_printf("Histogram of compressed mfu buffers.\n" + "Each bucket represents buffers of size: %s.\n", range); + dump_histogram(data.mfu_c_hist, data.hist_nbuckets, 0); + mdb_printf("\n"); + + mdb_printf("Histogram of uncompressed mfu buffers.\n" + "Each bucket represents buffers of size: %s.\n", range); + dump_histogram(data.mfu_u_hist, data.hist_nbuckets, 0); + mdb_printf("\n"); + } + + if (data.arc_cflags & ARC_CFLAG_BUFS) { + mdb_printf("Histogram of all buffers that " + "are associated with an arc hdr.\n"); + dump_histogram(data.all_bufs, data.hist_nbuckets, 0); + mdb_printf("\n"); + } + + mdb_printf("Histogram of all compressed buffers.\n" + "Each bucket represents buffers of size: %s.\n", range); + dump_histogram(data.all_c_hist, data.hist_nbuckets, 0); + mdb_printf("\n"); + + mdb_printf("Histogram of all uncompressed buffers.\n" + "Each bucket represents buffers of size: %s.\n", range); + dump_histogram(data.all_u_hist, data.hist_nbuckets, 0); + +out: + mdb_free(data.anon_c_hist, hist_size); + mdb_free(data.anon_u_hist, hist_size); + mdb_free(data.anon_bufs, hist_size); + + mdb_free(data.mru_c_hist, hist_size); + mdb_free(data.mru_u_hist, hist_size); + mdb_free(data.mru_bufs, hist_size); + + mdb_free(data.mfu_c_hist, hist_size); + mdb_free(data.mfu_u_hist, hist_size); + mdb_free(data.mfu_bufs, hist_size); + + mdb_free(data.all_c_hist, hist_size); + mdb_free(data.all_u_hist, hist_size); + mdb_free(data.all_bufs, hist_size); + + return (rc); +} + /* * MDB module linkage information: * @@ -3339,6 +3756,14 @@ static const mdb_dcmd_t dcmds[] = { "print zfs debug log", dbgmsg}, { "rrwlock", ":", "print rrwlock_t, including readers", rrwlock}, + { "arc_compression_stats", ":[-vabrf]\n" + "\t-v verbose, display a linearly scaled histogram\n" + "\t-a display ARC_anon state statistics individually\n" + "\t-r display ARC_mru state statistics individually\n" + "\t-f display ARC_mfu state statistics individually\n" + "\t-b display histogram of buffer counts\n", + "print a histogram of compressed arc buffer sizes", + arc_compression_stats}, { NULL } }; @@ -3364,6 +3789,8 @@ static const mdb_walker_t walkers[] = { spa_walk_init, spa_walk_step, NULL }, { "metaslab", "given a spa_t *, walk all metaslab_t structures", metaslab_walk_init, metaslab_walk_step, NULL }, + { "multilist", "given a multilist_t *, walk all list_t structures", + multilist_walk_init, multilist_walk_step, NULL }, { "zfs_acl_node", "given a zfs_acl_t, walk all zfs_acl_nodes", zfs_acl_node_walk_init, zfs_acl_node_walk_step, NULL }, { "zfs_acl_node_aces", "given a zfs_acl_node_t, walk all ACEs", diff --git a/usr/src/cmd/zdb/zdb.c b/usr/src/cmd/zdb/zdb.c index 812453b826..deef7b4084 100644 --- a/usr/src/cmd/zdb/zdb.c +++ b/usr/src/cmd/zdb/zdb.c @@ -1264,7 +1264,7 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp, } if (!err) ASSERT3U(fill, ==, BP_GET_FILL(bp)); - (void) arc_buf_remove_ref(buf, &buf); + arc_buf_destroy(buf, &buf); } return (err); diff --git a/usr/src/cmd/ztest/ztest.c b/usr/src/cmd/ztest/ztest.c index a3800f60ce..b21d61d3a7 100644 --- a/usr/src/cmd/ztest/ztest.c +++ b/usr/src/cmd/ztest/ztest.c @@ -187,6 +187,7 @@ extern uint64_t metaslab_gang_bang; extern uint64_t metaslab_df_alloc_threshold; extern uint64_t zfs_deadman_synctime_ms; extern int metaslab_preload_limit; +extern boolean_t zfs_compressed_arc_enabled; static ztest_shared_opts_t *ztest_shared_opts; static ztest_shared_opts_t ztest_opts; @@ -5378,6 +5379,12 @@ ztest_resume_thread(void *arg) if (spa_suspended(spa)) ztest_resume(spa); (void) poll(NULL, 0, 100); + + /* + * Periodically change the zfs_compressed_arc_enabled setting. + */ + if (ztest_random(10) == 0) + zfs_compressed_arc_enabled = ztest_random(2); } return (NULL); } |
