928e8ad47d
This patch introduces 3 new histograms per metaslab. These histograms track segments that have made it to the metaslab's space map histogram (and are part of the spacemap) but have not yet reached the ms_allocatable tree on loaded metaslab's because these metaslab's are currently syncing and haven't gone through metaslab_sync_done() yet. The histograms help when we decide whether to load an unloaded metaslab in-order to allocate from it. When calculating the weight of an unloaded metaslab traditionally, we look at the highest bucket of its spacemap's histogram. The problem is that we are not guaranteed to be able to allocated that segment when we load the metaslab because it may still be at the freeing, freed, or defer trees. The new histograms are used when we try to calculate an unloaded metaslab's weight to deal with this issue by removing segments that have would not be in the allocatable tree at runtime. Note, that this method of dealing with this is not completely accurate as adjacent segments are not always consolidated in the space map histogram of a metaslab. In addition and to make things deterministic, we always reset the weight of unloaded metaslabs based on their space map weight (instead of doing that on a need basis). Thus, every time a metaslab is loaded and its weight is reset again (from the weight based on its space map to the one based on its allocatable range tree) we expect (and assert) that this change in weight can only get better if it doesn't stay the same. Reviewed by: Paul Dagnelie <pcd@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed by: Matt Ahrens <mahrens@delphix.com> Signed-off-by: Serapheim Dimitropoulos <serapheim@delphix.com> Closes #8358
129 lines
4.6 KiB
C
129 lines
4.6 KiB
C
/*
|
|
* CDDL HEADER START
|
|
*
|
|
* The contents of this file are subject to the terms of the
|
|
* Common Development and Distribution License (the "License").
|
|
* You may not use this file except in compliance with the License.
|
|
*
|
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
* or http://www.opensolaris.org/os/licensing.
|
|
* See the License for the specific language governing permissions
|
|
* and limitations under the License.
|
|
*
|
|
* When distributing Covered Code, include this CDDL HEADER in each
|
|
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
* If applicable, add the following below this CDDL HEADER, with the
|
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
*
|
|
* CDDL HEADER END
|
|
*/
|
|
/*
|
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
|
* Copyright (c) 2011, 2018 by Delphix. All rights reserved.
|
|
* Copyright (c) 2017, Intel Corporation.
|
|
*/
|
|
|
|
#ifndef _SYS_METASLAB_H
|
|
#define _SYS_METASLAB_H
|
|
|
|
#include <sys/spa.h>
|
|
#include <sys/space_map.h>
|
|
#include <sys/txg.h>
|
|
#include <sys/zio.h>
|
|
#include <sys/avl.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
typedef struct metaslab_ops {
|
|
uint64_t (*msop_alloc)(metaslab_t *, uint64_t);
|
|
} metaslab_ops_t;
|
|
|
|
|
|
extern metaslab_ops_t *zfs_metaslab_ops;
|
|
|
|
int metaslab_init(metaslab_group_t *, uint64_t, uint64_t, uint64_t,
|
|
metaslab_t **);
|
|
void metaslab_fini(metaslab_t *);
|
|
|
|
int metaslab_load(metaslab_t *);
|
|
void metaslab_unload(metaslab_t *);
|
|
|
|
uint64_t metaslab_allocated_space(metaslab_t *);
|
|
|
|
void metaslab_sync(metaslab_t *, uint64_t);
|
|
void metaslab_sync_done(metaslab_t *, uint64_t);
|
|
void metaslab_sync_reassess(metaslab_group_t *);
|
|
uint64_t metaslab_block_maxsize(metaslab_t *);
|
|
|
|
/*
|
|
* metaslab alloc flags
|
|
*/
|
|
#define METASLAB_HINTBP_FAVOR 0x0
|
|
#define METASLAB_HINTBP_AVOID 0x1
|
|
#define METASLAB_GANG_HEADER 0x2
|
|
#define METASLAB_GANG_CHILD 0x4
|
|
#define METASLAB_ASYNC_ALLOC 0x8
|
|
#define METASLAB_DONT_THROTTLE 0x10
|
|
#define METASLAB_MUST_RESERVE 0x20
|
|
#define METASLAB_FASTWRITE 0x40
|
|
|
|
int metaslab_alloc(spa_t *, metaslab_class_t *, uint64_t,
|
|
blkptr_t *, int, uint64_t, blkptr_t *, int, zio_alloc_list_t *, zio_t *,
|
|
int);
|
|
int metaslab_alloc_dva(spa_t *, metaslab_class_t *, uint64_t,
|
|
dva_t *, int, dva_t *, uint64_t, int, zio_alloc_list_t *, int);
|
|
void metaslab_free(spa_t *, const blkptr_t *, uint64_t, boolean_t);
|
|
void metaslab_free_concrete(vdev_t *, uint64_t, uint64_t, boolean_t);
|
|
void metaslab_free_dva(spa_t *, const dva_t *, boolean_t);
|
|
void metaslab_free_impl_cb(uint64_t, vdev_t *, uint64_t, uint64_t, void *);
|
|
void metaslab_unalloc_dva(spa_t *, const dva_t *, uint64_t);
|
|
int metaslab_claim(spa_t *, const blkptr_t *, uint64_t);
|
|
int metaslab_claim_impl(vdev_t *, uint64_t, uint64_t, uint64_t);
|
|
void metaslab_check_free(spa_t *, const blkptr_t *);
|
|
void metaslab_fastwrite_mark(spa_t *, const blkptr_t *);
|
|
void metaslab_fastwrite_unmark(spa_t *, const blkptr_t *);
|
|
|
|
void metaslab_alloc_trace_init(void);
|
|
void metaslab_alloc_trace_fini(void);
|
|
void metaslab_trace_init(zio_alloc_list_t *);
|
|
void metaslab_trace_fini(zio_alloc_list_t *);
|
|
|
|
metaslab_class_t *metaslab_class_create(spa_t *, metaslab_ops_t *);
|
|
void metaslab_class_destroy(metaslab_class_t *);
|
|
int metaslab_class_validate(metaslab_class_t *);
|
|
void metaslab_class_histogram_verify(metaslab_class_t *);
|
|
uint64_t metaslab_class_fragmentation(metaslab_class_t *);
|
|
uint64_t metaslab_class_expandable_space(metaslab_class_t *);
|
|
boolean_t metaslab_class_throttle_reserve(metaslab_class_t *, int, int,
|
|
zio_t *, int);
|
|
void metaslab_class_throttle_unreserve(metaslab_class_t *, int, int, zio_t *);
|
|
|
|
uint64_t metaslab_class_get_alloc(metaslab_class_t *);
|
|
uint64_t metaslab_class_get_space(metaslab_class_t *);
|
|
uint64_t metaslab_class_get_dspace(metaslab_class_t *);
|
|
uint64_t metaslab_class_get_deferred(metaslab_class_t *);
|
|
|
|
metaslab_group_t *metaslab_group_create(metaslab_class_t *, vdev_t *, int);
|
|
void metaslab_group_destroy(metaslab_group_t *);
|
|
void metaslab_group_activate(metaslab_group_t *);
|
|
void metaslab_group_passivate(metaslab_group_t *);
|
|
boolean_t metaslab_group_initialized(metaslab_group_t *);
|
|
uint64_t metaslab_group_get_space(metaslab_group_t *);
|
|
void metaslab_group_histogram_verify(metaslab_group_t *);
|
|
uint64_t metaslab_group_fragmentation(metaslab_group_t *);
|
|
void metaslab_group_histogram_remove(metaslab_group_t *, metaslab_t *);
|
|
void metaslab_group_alloc_decrement(spa_t *, uint64_t, void *, int, int,
|
|
boolean_t);
|
|
void metaslab_group_alloc_verify(spa_t *, const blkptr_t *, void *, int);
|
|
void metaslab_recalculate_weight_and_sort(metaslab_t *);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _SYS_METASLAB_H */
|