Author: mav
Date: Sat Oct  3 07:28:52 2015
New Revision: 288548
URL: https://svnweb.freebsd.org/changeset/base/288548

Log:
  MFC r286574: 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:
  stable/10/sys/cddl/compat/opensolaris/sys/kstat.h
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cddl/compat/opensolaris/sys/kstat.h
==============================================================================
--- stable/10/sys/cddl/compat/opensolaris/sys/kstat.h   Sat Oct  3 07:27:58 
2015        (r288547)
+++ stable/10/sys/cddl/compat/opensolaris/sys/kstat.h   Sat Oct  3 07:28:52 
2015        (r288548)
@@ -35,12 +35,17 @@
 
 #define        KSTAT_FLAG_VIRTUAL      0x01
 
+#define        KSTAT_READ      0
+#define        KSTAT_WRITE     1
+
 typedef struct kstat {
        void    *ks_data;
        u_int    ks_ndata;
 #ifdef _KERNEL
        struct sysctl_ctx_list ks_sysctl_ctx;
        struct sysctl_oid *ks_sysctl_root;
+       int             (*ks_update)(struct kstat *, int); /* dynamic update */
+       void            *ks_private;    /* arbitrary provider-private data */
 #endif
 } kstat_t;
 

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c      Sat Oct 
 3 07:27:58 2015        (r288547)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c      Sat Oct 
 3 07:28:52 2015        (r288548)
@@ -387,9 +387,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;
@@ -472,7 +600,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 },
@@ -1730,6 +1874,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;
@@ -1741,7 +1888,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);
 }
 
@@ -1754,6 +1903,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;
@@ -1765,10 +1917,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);
 }
@@ -2009,12 +2164,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)) {
@@ -3099,6 +3253,20 @@ arc_reclaim_thread(void *dummy __unused)
                }
 #endif
 
+               /*
+                * 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,
@@ -3236,12 +3404,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;
        }
@@ -3268,12 +3435,11 @@ arc_get_data_buf(arc_buf_t *buf)
        if ((buf->b_data = arc_evict(state, 0, 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);
        }
@@ -4434,6 +4600,48 @@ arc_memory_throttle(uint64_t reserve, ui
        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_tempreserve_clear(uint64_t reserve)
 {
@@ -4657,6 +4865,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: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h  Sat Oct 
 3 07:27:58 2015        (r288547)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h  Sat Oct 
 3 07:28:52 2015        (r288548)
@@ -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-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to