1fa9e406ahrens/*
2fa9e406ahrens * CDDL HEADER START
3fa9e406ahrens *
4fa9e406ahrens * The contents of this file are subject to the terms of the
51ab7f2dmaybee * Common Development and Distribution License (the "License").
61ab7f2dmaybee * You may not use this file except in compliance with the License.
7fa9e406ahrens *
8fa9e406ahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fa9e406ahrens * or http://www.opensolaris.org/os/licensing.
10fa9e406ahrens * See the License for the specific language governing permissions
11fa9e406ahrens * and limitations under the License.
12fa9e406ahrens *
13fa9e406ahrens * When distributing Covered Code, include this CDDL HEADER in each
14fa9e406ahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fa9e406ahrens * If applicable, add the following below this CDDL HEADER, with the
16fa9e406ahrens * fields enclosed by brackets "[]" replaced with your own identifying
17fa9e406ahrens * information: Portions Copyright [yyyy] [name of copyright owner]
18fa9e406ahrens *
19fa9e406ahrens * CDDL HEADER END
20fa9e406ahrens */
21fa9e406ahrens/*
22495807dMatthew Ahrens * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23fa9e406ahrens * Use is subject to license terms.
24fa9e406ahrens */
25ce636f8Matthew Ahrens/*
26b7b2590Matthew Ahrens * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
27ce636f8Matthew Ahrens */
28fa9e406ahrens
29fa9e406ahrens#ifndef _SYS_TXG_H
30fa9e406ahrens#define	_SYS_TXG_H
31fa9e406ahrens
32fa9e406ahrens#include <sys/spa.h>
33fa9e406ahrens#include <sys/zfs_context.h>
34fa9e406ahrens
35fa9e406ahrens#ifdef	__cplusplus
36fa9e406ahrensextern "C" {
37fa9e406ahrens#endif
38fa9e406ahrens
39fa9e406ahrens#define	TXG_CONCURRENT_STATES	3	/* open, quiescing, syncing	*/
40fa9e406ahrens#define	TXG_SIZE		4		/* next power of 2	*/
41fa9e406ahrens#define	TXG_MASK		(TXG_SIZE - 1)	/* mask for size	*/
42084fd14Brian Behlendorf#define	TXG_INITIAL		TXG_SIZE	/* initial txg		*/
43fa9e406ahrens#define	TXG_IDX			(txg & TXG_MASK)
44fa9e406ahrens
45468c413Tim Haley/* Number of txgs worth of frees we defer adding to in-core spacemaps */
46468c413Tim Haley#define	TXG_DEFER_SIZE		2
47468c413Tim Haley
48fa9e406ahrenstypedef struct tx_cpu tx_cpu_t;
49fa9e406ahrens
50fa9e406ahrenstypedef struct txg_handle {
51fa9e406ahrens	tx_cpu_t	*th_cpu;
52fa9e406ahrens	uint64_t	th_txg;
53fa9e406ahrens} txg_handle_t;
54fa9e406ahrens
55fa9e406ahrenstypedef struct txg_node {
56fa9e406ahrens	struct txg_node	*tn_next[TXG_SIZE];
57fa9e406ahrens	uint8_t		tn_member[TXG_SIZE];
58fa9e406ahrens} txg_node_t;
59fa9e406ahrens
60fa9e406ahrenstypedef struct txg_list {
61fa9e406ahrens	kmutex_t	tl_lock;
62fa9e406ahrens	size_t		tl_offset;
63b7b2590Matthew Ahrens	spa_t		*tl_spa;
64fa9e406ahrens	txg_node_t	*tl_head[TXG_SIZE];
65fa9e406ahrens} txg_list_t;
66fa9e406ahrens
67fa9e406ahrensstruct dsl_pool;
68fa9e406ahrens
69fa9e406ahrensextern void txg_init(struct dsl_pool *dp, uint64_t txg);
70fa9e406ahrensextern void txg_fini(struct dsl_pool *dp);
71fa9e406ahrensextern void txg_sync_start(struct dsl_pool *dp);
72fa9e406ahrensextern void txg_sync_stop(struct dsl_pool *dp);
73fa9e406ahrensextern uint64_t txg_hold_open(struct dsl_pool *dp, txg_handle_t *txghp);
74fa9e406ahrensextern void txg_rele_to_quiesce(txg_handle_t *txghp);
75fa9e406ahrensextern void txg_rele_to_sync(txg_handle_t *txghp);
76d20e665Ricardo M. Correiaextern void txg_register_callbacks(txg_handle_t *txghp, list_t *tx_callbacks);
77fa9e406ahrens
780689f76Adam Leventhalextern void txg_delay(struct dsl_pool *dp, uint64_t txg, hrtime_t delta,
790689f76Adam Leventhal    hrtime_t resolution);
8069962b5Matthew Ahrensextern void txg_kick(struct dsl_pool *dp);
811ab7f2dmaybee
821ab7f2dmaybee/*
83fa9e406ahrens * Wait until the given transaction group has finished syncing.
84fa9e406ahrens * Try to make this happen as soon as possible (eg. kick off any
85fa9e406ahrens * necessary syncs immediately).  If txg==0, wait for the currently open
86fa9e406ahrens * txg to finish syncing.
87fa9e406ahrens */
88fa9e406ahrensextern void txg_wait_synced(struct dsl_pool *dp, uint64_t txg);
89fa9e406ahrens
90fa9e406ahrens/*
91d0cb1fbDon Brady * Wait as above. Returns true if the thread was signaled while waiting.
92d0cb1fbDon Brady */
93d0cb1fbDon Bradyextern boolean_t txg_wait_synced_sig(struct dsl_pool *dp, uint64_t txg);
94d0cb1fbDon Brady
95d0cb1fbDon Brady/*
96fa9e406ahrens * Wait until the given transaction group, or one after it, is
97fa9e406ahrens * the open transaction group.  Try to make this happen as soon
98084fd14Brian Behlendorf * as possible (eg. kick off any necessary syncs immediately) when
99084fd14Brian Behlendorf * should_quiesce is set.  If txg == 0, wait for the next open txg.
100fa9e406ahrens */
101084fd14Brian Behlendorfextern void txg_wait_open(struct dsl_pool *dp, uint64_t txg,
102084fd14Brian Behlendorf    boolean_t should_quiesce);
103fa9e406ahrens
104fa9e406ahrens/*
105fa9e406ahrens * Returns TRUE if we are "backed up" waiting for the syncing
106fa9e406ahrens * transaction to complete; otherwise returns FALSE.
107fa9e406ahrens */
108088f389ahrensextern boolean_t txg_stalled(struct dsl_pool *dp);
109088f389ahrens
110088f389ahrens/* returns TRUE if someone is waiting for the next txg to sync */
111088f389ahrensextern boolean_t txg_sync_waiting(struct dsl_pool *dp);
112fa9e406ahrens
113b7b2590Matthew Ahrensextern void txg_verify(spa_t *spa, uint64_t txg);
114b7b2590Matthew Ahrens
115fa9e406ahrens/*
116fa9e406ahrens * Per-txg object lists.
117fa9e406ahrens */
118fa9e406ahrens
119fa9e406ahrens#define	TXG_CLEAN(txg)	((txg) - 1)
120fa9e406ahrens
121b7b2590Matthew Ahrensextern void txg_list_create(txg_list_t *tl, spa_t *spa, size_t offset);
122fa9e406ahrensextern void txg_list_destroy(txg_list_t *tl);
123ce636f8Matthew Ahrensextern boolean_t txg_list_empty(txg_list_t *tl, uint64_t txg);
12473527f4Alex Reeceextern boolean_t txg_all_lists_empty(txg_list_t *tl);
1253b2aab1Matthew Ahrensextern boolean_t txg_list_add(txg_list_t *tl, void *p, uint64_t txg);
1263b2aab1Matthew Ahrensextern boolean_t txg_list_add_tail(txg_list_t *tl, void *p, uint64_t txg);
127fa9e406ahrensextern void *txg_list_remove(txg_list_t *tl, uint64_t txg);
128fa9e406ahrensextern void *txg_list_remove_this(txg_list_t *tl, void *p, uint64_t txg);
1293b2aab1Matthew Ahrensextern boolean_t txg_list_member(txg_list_t *tl, void *p, uint64_t txg);
130fa9e406ahrensextern void *txg_list_head(txg_list_t *tl, uint64_t txg);
131fa9e406ahrensextern void *txg_list_next(txg_list_t *tl, void *p, uint64_t txg);
132fa9e406ahrens
133fa9e406ahrens#ifdef	__cplusplus
134fa9e406ahrens}
135fa9e406ahrens#endif
136fa9e406ahrens
137fa9e406ahrens#endif	/* _SYS_TXG_H */
138