aboutsummaryrefslogtreecommitdiffstats
path: root/include/sys/metaslab_impl.h
diff options
context:
space:
mode:
authorGeorge Wilson <[email protected]>2014-07-19 12:19:24 -0800
committerBrian Behlendorf <[email protected]>2014-08-18 08:40:49 -0700
commitf3a7f6610f2df0217ba3b99099019417a954b673 (patch)
tree720f77d117032a585761dd5bb80e5a5694915111 /include/sys/metaslab_impl.h
parentf67d709080f3d4a247191f0d25cbedc5da103f78 (diff)
Illumos 4976-4984 - metaslab improvements
4976 zfs should only avoid writing to a failing non-redundant top-level vdev 4978 ztest fails in get_metaslab_refcount() 4979 extend free space histogram to device and pool 4980 metaslabs should have a fragmentation metric 4981 remove fragmented ops vector from block allocator 4982 space_map object should proactively upgrade when feature is enabled 4983 need to collect metaslab information via mdb 4984 device selection should use fragmentation metric Reviewed by: Matthew Ahrens <[email protected]> Reviewed by: Adam Leventhal <[email protected]> Reviewed by: Christopher Siden <[email protected]> Approved by: Garrett D'Amore <[email protected]> References: https://www.illumos.org/issues/4976 https://www.illumos.org/issues/4978 https://www.illumos.org/issues/4979 https://www.illumos.org/issues/4980 https://www.illumos.org/issues/4981 https://www.illumos.org/issues/4982 https://www.illumos.org/issues/4983 https://www.illumos.org/issues/4984 https://github.com/illumos/illumos-gate/commit/2e4c998 Notes: The "zdb -M" option has been re-tasked to display the new metaslab fragmentation metric and the new "zdb -I" option is used to control the maximum number of in-flight I/Os. The new fragmentation metric is derived from the space map histogram which has been rolled up to the vdev and pool level and is presented to the user via "zpool list". Add a number of module parameters related to the new metaslab weighting logic. Ported by: Tim Chase <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #2595
Diffstat (limited to 'include/sys/metaslab_impl.h')
-rw-r--r--include/sys/metaslab_impl.h36
1 files changed, 33 insertions, 3 deletions
diff --git a/include/sys/metaslab_impl.h b/include/sys/metaslab_impl.h
index 3cd27d75e..88bda071f 100644
--- a/include/sys/metaslab_impl.h
+++ b/include/sys/metaslab_impl.h
@@ -41,6 +41,23 @@
extern "C" {
#endif
+/*
+ * A metaslab class encompasses a category of allocatable top-level vdevs.
+ * Each top-level vdev is associated with a metaslab group which defines
+ * the allocatable region for that vdev. Examples of these categories include
+ * "normal" for data block allocations (i.e. main pool allocations) or "log"
+ * for allocations designated for intent log devices (i.e. slog devices).
+ * When a block allocation is requested from the SPA it is associated with a
+ * metaslab_class_t, and only top-level vdevs (i.e. metaslab groups) belonging
+ * to the class can be used to satisfy that request. Allocations are done
+ * by traversing the metaslab groups that are linked off of the mc_rotor field.
+ * This rotor points to the next metaslab group where allocations will be
+ * attempted. Allocating a block is a 3 step process -- select the metaslab
+ * group, select the metaslab, and then allocate the block. The metaslab
+ * class defines the low-level block allocator that will be used as the
+ * final step in allocation. These allocators are pluggable allowing each class
+ * to use a block allocator that best suits that class.
+ */
struct metaslab_class {
spa_t *mc_spa;
metaslab_group_t *mc_rotor;
@@ -51,9 +68,19 @@ struct metaslab_class {
uint64_t mc_deferred; /* total deferred frees */
uint64_t mc_space; /* total space (alloc + free) */
uint64_t mc_dspace; /* total deflated space */
+ uint64_t mc_histogram[RANGE_TREE_HISTOGRAM_SIZE];
kmutex_t mc_fastwrite_lock;
};
+/*
+ * Metaslab groups encapsulate all the allocatable regions (i.e. metaslabs)
+ * of a top-level vdev. They are linked togther to form a circular linked
+ * list and can belong to only one metaslab class. Metaslab groups may become
+ * ineligible for allocations for a number of reasons such as limited free
+ * space, fragmentation, or going offline. When this happens the allocator will
+ * simply find the next metaslab group in the linked list and attempt
+ * to allocate from that group instead.
+ */
struct metaslab_group {
kmutex_t mg_lock;
avl_tree_t mg_metaslab_tree;
@@ -67,12 +94,14 @@ struct metaslab_group {
taskq_t *mg_taskq;
metaslab_group_t *mg_prev;
metaslab_group_t *mg_next;
+ uint64_t mg_fragmentation;
+ uint64_t mg_histogram[RANGE_TREE_HISTOGRAM_SIZE];
};
/*
* This value defines the number of elements in the ms_lbas array. The value
- * of 64 was chosen as it covers to cover all power of 2 buckets up to
- * UINT64_MAX. This is the equivalent of highbit(UINT64_MAX).
+ * of 64 was chosen as it covers all power of 2 buckets up to UINT64_MAX.
+ * This is the equivalent of highbit(UINT64_MAX).
*/
#define MAX_LBAS 64
@@ -135,6 +164,7 @@ struct metaslab {
uint64_t ms_id;
uint64_t ms_start;
uint64_t ms_size;
+ uint64_t ms_fragmentation;
range_tree_t *ms_alloctree[TXG_SIZE];
range_tree_t *ms_freetree[TXG_SIZE];
@@ -142,12 +172,12 @@ struct metaslab {
range_tree_t *ms_tree;
boolean_t ms_condensing; /* condensing? */
+ boolean_t ms_condense_wanted;
boolean_t ms_loaded;
boolean_t ms_loading;
int64_t ms_deferspace; /* sum of ms_defermap[] space */
uint64_t ms_weight; /* weight vs. others in group */
- uint64_t ms_factor;
uint64_t ms_access_txg;
/*