Author: delphij
Date: Tue Jan 20 20:10:03 2015
New Revision: 277427
URL: https://svnweb.freebsd.org/changeset/base/277427

Log:
  5445 Add more visibility via arcstats; specifically arc_state_t stats and 
differentiate between "data" and "metadata"
  Reviewed by: Basil Crow <basil.c...@delphix.com>
  Reviewed by: George Wilson <george.wil...@delphix.com>
  Reviewed by: Matthew Ahrens <mahr...@delphix.com>
  Reviewed by: Bayard Bell <bayard.b...@nexenta.com>
  Approved by: Robert Mustacchi <r...@joyent.com>
  Author: Prakash Surya <prakash.su...@delphix.com>
  
  illumos/illumos-gate@4076b1bf41cfd9f968a33ed54a7ae76d9e996fe8

Modified:
  vendor-sys/illumos/dist/uts/common/fs/zfs/arc.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/sys/arc.h

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/arc.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/arc.c     Tue Jan 20 20:08:50 
2015        (r277426)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/arc.c     Tue Jan 20 20:10:03 
2015        (r277427)
@@ -299,9 +299,137 @@ typedef struct arc_stats {
        kstat_named_t arcstat_c_min;
        kstat_named_t arcstat_c_max;
        kstat_named_t arcstat_size;
+       /*
+        * Number of bytes consumed by internal ARC structures necessary
+        * for tracking purposes; these structures are not actually
+        * backed by ARC buffers. This includes arc_buf_hdr_t structures
+        * (allocated via arc_buf_hdr_t_full and arc_buf_hdr_t_l2only
+        * caches), and arc_buf_t structures (allocated via arc_buf_t
+        * cache).
+        */
        kstat_named_t arcstat_hdr_size;
+       /*
+        * Number of bytes consumed by ARC buffers of type equal to
+        * ARC_BUFC_DATA. This is generally consumed by buffers backing
+        * on disk user data (e.g. plain file contents).
+        */
        kstat_named_t arcstat_data_size;
+       /*
+        * Number of bytes consumed by ARC buffers of type equal to
+        * ARC_BUFC_METADATA. This is generally consumed by buffers
+        * backing on disk data that is used for internal ZFS
+        * structures (e.g. ZAP, dnode, indirect blocks, etc).
+        */
+       kstat_named_t arcstat_metadata_size;
+       /*
+        * Number of bytes consumed by various buffers and structures
+        * not actually backed with ARC buffers. This includes bonus
+        * buffers (allocated directly via zio_buf_* functions),
+        * dmu_buf_impl_t structures (allocated via dmu_buf_impl_t
+        * cache), and dnode_t structures (allocated via dnode_t cache).
+        */
        kstat_named_t arcstat_other_size;
+       /*
+        * Total number of bytes consumed by ARC buffers residing in the
+        * arc_anon state. This includes *all* buffers in the arc_anon
+        * state; e.g. data, metadata, evictable, and unevictable buffers
+        * are all included in this value.
+        */
+       kstat_named_t arcstat_anon_size;
+       /*
+        * Number of bytes consumed by ARC buffers that meet the
+        * following criteria: backing buffers of type ARC_BUFC_DATA,
+        * residing in the arc_anon state, and are eligible for eviction
+        * (e.g. have no outstanding holds on the buffer).
+        */
+       kstat_named_t arcstat_anon_evictable_data;
+       /*
+        * Number of bytes consumed by ARC buffers that meet the
+        * following criteria: backing buffers of type ARC_BUFC_METADATA,
+        * residing in the arc_anon state, and are eligible for eviction
+        * (e.g. have no outstanding holds on the buffer).
+        */
+       kstat_named_t arcstat_anon_evictable_metadata;
+       /*
+        * Total number of bytes consumed by ARC buffers residing in the
+        * arc_mru state. This includes *all* buffers in the arc_mru
+        * state; e.g. data, metadata, evictable, and unevictable buffers
+        * are all included in this value.
+        */
+       kstat_named_t arcstat_mru_size;
+       /*
+        * Number of bytes consumed by ARC buffers that meet the
+        * following criteria: backing buffers of type ARC_BUFC_DATA,
+        * residing in the arc_mru state, and are eligible for eviction
+        * (e.g. have no outstanding holds on the buffer).
+        */
+       kstat_named_t arcstat_mru_evictable_data;
+       /*
+        * Number of bytes consumed by ARC buffers that meet the
+        * following criteria: backing buffers of type ARC_BUFC_METADATA,
+        * residing in the arc_mru state, and are eligible for eviction
+        * (e.g. have no outstanding holds on the buffer).
+        */
+       kstat_named_t arcstat_mru_evictable_metadata;
+       /*
+        * Total number of bytes that *would have been* consumed by ARC
+        * buffers in the arc_mru_ghost state. The key thing to note
+        * here, is the fact that this size doesn't actually indicate
+        * RAM consumption. The ghost lists only consist of headers and
+        * don't actually have ARC buffers linked off of these headers.
+        * Thus, *if* the headers had associated ARC buffers, these
+        * buffers *would have* consumed this number of bytes.
+        */
+       kstat_named_t arcstat_mru_ghost_size;
+       /*
+        * Number of bytes that *would have been* consumed by ARC
+        * buffers that are eligible for eviction, of type
+        * ARC_BUFC_DATA, and linked off the arc_mru_ghost state.
+        */
+       kstat_named_t arcstat_mru_ghost_evictable_data;
+       /*
+        * Number of bytes that *would have been* consumed by ARC
+        * buffers that are eligible for eviction, of type
+        * ARC_BUFC_METADATA, and linked off the arc_mru_ghost state.
+        */
+       kstat_named_t arcstat_mru_ghost_evictable_metadata;
+       /*
+        * Total number of bytes consumed by ARC buffers residing in the
+        * arc_mfu state. This includes *all* buffers in the arc_mfu
+        * state; e.g. data, metadata, evictable, and unevictable buffers
+        * are all included in this value.
+        */
+       kstat_named_t arcstat_mfu_size;
+       /*
+        * Number of bytes consumed by ARC buffers that are eligible for
+        * eviction, of type ARC_BUFC_DATA, and reside in the arc_mfu
+        * state.
+        */
+       kstat_named_t arcstat_mfu_evictable_data;
+       /*
+        * Number of bytes consumed by ARC buffers that are eligible for
+        * eviction, of type ARC_BUFC_METADATA, and reside in the
+        * arc_mfu state.
+        */
+       kstat_named_t arcstat_mfu_evictable_metadata;
+       /*
+        * Total number of bytes that *would have been* consumed by ARC
+        * buffers in the arc_mfu_ghost state. See the comment above
+        * arcstat_mru_ghost_size for more details.
+        */
+       kstat_named_t arcstat_mfu_ghost_size;
+       /*
+        * Number of bytes that *would have been* consumed by ARC
+        * buffers that are eligible for eviction, of type
+        * ARC_BUFC_DATA, and linked off the arc_mfu_ghost state.
+        */
+       kstat_named_t arcstat_mfu_ghost_evictable_data;
+       /*
+        * Number of bytes that *would have been* consumed by ARC
+        * buffers that are eligible for eviction, of type
+        * ARC_BUFC_METADATA, and linked off the arc_mru_ghost state.
+        */
+       kstat_named_t arcstat_mfu_ghost_evictable_metadata;
        kstat_named_t arcstat_l2_hits;
        kstat_named_t arcstat_l2_misses;
        kstat_named_t arcstat_l2_feeds;
@@ -369,7 +497,23 @@ static arc_stats_t arc_stats = {
        { "size",                       KSTAT_DATA_UINT64 },
        { "hdr_size",                   KSTAT_DATA_UINT64 },
        { "data_size",                  KSTAT_DATA_UINT64 },
+       { "metadata_size",              KSTAT_DATA_UINT64 },
        { "other_size",                 KSTAT_DATA_UINT64 },
+       { "anon_size",                  KSTAT_DATA_UINT64 },
+       { "anon_evictable_data",        KSTAT_DATA_UINT64 },
+       { "anon_evictable_metadata",    KSTAT_DATA_UINT64 },
+       { "mru_size",                   KSTAT_DATA_UINT64 },
+       { "mru_evictable_data",         KSTAT_DATA_UINT64 },
+       { "mru_evictable_metadata",     KSTAT_DATA_UINT64 },
+       { "mru_ghost_size",             KSTAT_DATA_UINT64 },
+       { "mru_ghost_evictable_data",   KSTAT_DATA_UINT64 },
+       { "mru_ghost_evictable_metadata", KSTAT_DATA_UINT64 },
+       { "mfu_size",                   KSTAT_DATA_UINT64 },
+       { "mfu_evictable_data",         KSTAT_DATA_UINT64 },
+       { "mfu_evictable_metadata",     KSTAT_DATA_UINT64 },
+       { "mfu_ghost_size",             KSTAT_DATA_UINT64 },
+       { "mfu_ghost_evictable_data",   KSTAT_DATA_UINT64 },
+       { "mfu_ghost_evictable_metadata", KSTAT_DATA_UINT64 },
        { "l2_hits",                    KSTAT_DATA_UINT64 },
        { "l2_misses",                  KSTAT_DATA_UINT64 },
        { "l2_feeds",                   KSTAT_DATA_UINT64 },
@@ -1500,6 +1644,9 @@ arc_space_consume(uint64_t space, arc_sp
        case ARC_SPACE_DATA:
                ARCSTAT_INCR(arcstat_data_size, space);
                break;
+       case ARC_SPACE_META:
+               ARCSTAT_INCR(arcstat_metadata_size, space);
+               break;
        case ARC_SPACE_OTHER:
                ARCSTAT_INCR(arcstat_other_size, space);
                break;
@@ -1511,7 +1658,9 @@ arc_space_consume(uint64_t space, arc_sp
                break;
        }
 
-       ARCSTAT_INCR(arcstat_meta_used, space);
+       if (type != ARC_SPACE_DATA)
+               ARCSTAT_INCR(arcstat_meta_used, space);
+
        atomic_add_64(&arc_size, space);
 }
 
@@ -1524,6 +1673,9 @@ arc_space_return(uint64_t space, arc_spa
        case ARC_SPACE_DATA:
                ARCSTAT_INCR(arcstat_data_size, -space);
                break;
+       case ARC_SPACE_META:
+               ARCSTAT_INCR(arcstat_metadata_size, -space);
+               break;
        case ARC_SPACE_OTHER:
                ARCSTAT_INCR(arcstat_other_size, -space);
                break;
@@ -1535,10 +1687,13 @@ arc_space_return(uint64_t space, arc_spa
                break;
        }
 
-       ASSERT(arc_meta_used >= space);
-       if (arc_meta_max < arc_meta_used)
-               arc_meta_max = arc_meta_used;
-       ARCSTAT_INCR(arcstat_meta_used, -space);
+       if (type != ARC_SPACE_DATA) {
+               ASSERT(arc_meta_used >= space);
+               if (arc_meta_max < arc_meta_used)
+                       arc_meta_max = arc_meta_used;
+               ARCSTAT_INCR(arcstat_meta_used, -space);
+       }
+
        ASSERT(arc_size >= space);
        atomic_add_64(&arc_size, -space);
 }
@@ -1744,12 +1899,11 @@ arc_buf_destroy(arc_buf_t *buf, boolean_
                if (!recycle) {
                        if (type == ARC_BUFC_METADATA) {
                                arc_buf_data_free(buf, zio_buf_free);
-                               arc_space_return(size, ARC_SPACE_DATA);
+                               arc_space_return(size, ARC_SPACE_META);
                        } else {
                                ASSERT(type == ARC_BUFC_DATA);
                                arc_buf_data_free(buf, zio_data_buf_free);
-                               ARCSTAT_INCR(arcstat_data_size, -size);
-                               atomic_add_64(&arc_size, -size);
+                               arc_space_return(size, ARC_SPACE_DATA);
                        }
                }
                if (list_link_active(&buf->b_hdr->b_l1hdr.b_arc_node)) {
@@ -2742,6 +2896,20 @@ arc_reclaim_thread(void)
                if (arc_eviction_list != NULL)
                        arc_do_user_evicts();
 
+               /*
+                * This is necessary in order for the mdb ::arc dcmd to
+                * show up to date information. Since the ::arc command
+                * does not call the kstat's update function, without
+                * this call, the command may show stale stats for the
+                * anon, mru, mru_ghost, mfu, and mfu_ghost lists. Even
+                * with this change, the data might be up to 1 second
+                * out of date; but that should suffice. The arc_state_t
+                * structures can be queried directly if more accurate
+                * information is needed.
+                */
+               if (arc_ksp != NULL)
+                       arc_ksp->ks_update(arc_ksp, KSTAT_READ);
+
                /* block until needed, or one second, whichever is shorter */
                CALLB_CPR_SAFE_BEGIN(&cpr);
                (void) cv_timedwait(&arc_reclaim_thr_cv,
@@ -2878,12 +3046,11 @@ arc_get_data_buf(arc_buf_t *buf)
        if (!arc_evict_needed(type)) {
                if (type == ARC_BUFC_METADATA) {
                        buf->b_data = zio_buf_alloc(size);
-                       arc_space_consume(size, ARC_SPACE_DATA);
+                       arc_space_consume(size, ARC_SPACE_META);
                } else {
                        ASSERT(type == ARC_BUFC_DATA);
                        buf->b_data = zio_data_buf_alloc(size);
-                       ARCSTAT_INCR(arcstat_data_size, size);
-                       atomic_add_64(&arc_size, size);
+                       arc_space_consume(size, ARC_SPACE_DATA);
                }
                goto out;
        }
@@ -2910,12 +3077,11 @@ arc_get_data_buf(arc_buf_t *buf)
        if ((buf->b_data = arc_evict(state, NULL, size, TRUE, type)) == NULL) {
                if (type == ARC_BUFC_METADATA) {
                        buf->b_data = zio_buf_alloc(size);
-                       arc_space_consume(size, ARC_SPACE_DATA);
+                       arc_space_consume(size, ARC_SPACE_META);
                } else {
                        ASSERT(type == ARC_BUFC_DATA);
                        buf->b_data = zio_data_buf_alloc(size);
-                       ARCSTAT_INCR(arcstat_data_size, size);
-                       atomic_add_64(&arc_size, size);
+                       arc_space_consume(size, ARC_SPACE_DATA);
                }
                ARCSTAT_BUMP(arcstat_recycle_miss);
        }
@@ -4115,6 +4281,48 @@ arc_tempreserve_space(uint64_t reserve, 
        return (0);
 }
 
+static void
+arc_kstat_update_state(arc_state_t *state, kstat_named_t *size,
+    kstat_named_t *evict_data, kstat_named_t *evict_metadata)
+{
+       size->value.ui64 = state->arcs_size;
+       evict_data->value.ui64 = state->arcs_lsize[ARC_BUFC_DATA];
+       evict_metadata->value.ui64 = state->arcs_lsize[ARC_BUFC_METADATA];
+}
+
+static int
+arc_kstat_update(kstat_t *ksp, int rw)
+{
+       arc_stats_t *as = ksp->ks_data;
+
+       if (rw == KSTAT_WRITE) {
+               return (EACCES);
+       } else {
+               arc_kstat_update_state(arc_anon,
+                   &as->arcstat_anon_size,
+                   &as->arcstat_anon_evictable_data,
+                   &as->arcstat_anon_evictable_metadata);
+               arc_kstat_update_state(arc_mru,
+                   &as->arcstat_mru_size,
+                   &as->arcstat_mru_evictable_data,
+                   &as->arcstat_mru_evictable_metadata);
+               arc_kstat_update_state(arc_mru_ghost,
+                   &as->arcstat_mru_ghost_size,
+                   &as->arcstat_mru_ghost_evictable_data,
+                   &as->arcstat_mru_ghost_evictable_metadata);
+               arc_kstat_update_state(arc_mfu,
+                   &as->arcstat_mfu_size,
+                   &as->arcstat_mfu_evictable_data,
+                   &as->arcstat_mfu_evictable_metadata);
+               arc_kstat_update_state(arc_mfu_ghost,
+                   &as->arcstat_mfu_ghost_size,
+                   &as->arcstat_mfu_ghost_evictable_data,
+                   &as->arcstat_mfu_ghost_evictable_metadata);
+       }
+
+       return (0);
+}
+
 void
 arc_init(void)
 {
@@ -4261,6 +4469,7 @@ arc_init(void)
 
        if (arc_ksp != NULL) {
                arc_ksp->ks_data = &arc_stats;
+               arc_ksp->ks_update = arc_kstat_update;
                kstat_install(arc_ksp);
        }
 

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/sys/arc.h
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/sys/arc.h Tue Jan 20 20:08:50 
2015        (r277426)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/sys/arc.h Tue Jan 20 20:10:03 
2015        (r277427)
@@ -115,6 +115,7 @@ typedef enum arc_buf_contents {
  */
 typedef enum arc_space_type {
        ARC_SPACE_DATA,
+       ARC_SPACE_META,
        ARC_SPACE_HDRS,
        ARC_SPACE_L2HDRS,
        ARC_SPACE_OTHER,
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to