xref: /dragonfly/sys/vfs/hammer2/hammer2_ccms.h (revision f3ee5e44)
1f03672ecSMatthew Dillon /*
268b321c1SMatthew Dillon  * Copyright (c) 2006,2014-2018 The DragonFly Project.  All rights reserved.
3f03672ecSMatthew Dillon  *
4f03672ecSMatthew Dillon  * This code is derived from software contributed to The DragonFly Project
5f03672ecSMatthew Dillon  * by Matthew Dillon <dillon@backplane.com>
6f03672ecSMatthew Dillon  *
7f03672ecSMatthew Dillon  * Redistribution and use in source and binary forms, with or without
8f03672ecSMatthew Dillon  * modification, are permitted provided that the following conditions
9f03672ecSMatthew Dillon  * are met:
10f03672ecSMatthew Dillon  *
11f03672ecSMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
12f03672ecSMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
13f03672ecSMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
14f03672ecSMatthew Dillon  *    notice, this list of conditions and the following disclaimer in
15f03672ecSMatthew Dillon  *    the documentation and/or other materials provided with the
16f03672ecSMatthew Dillon  *    distribution.
17f03672ecSMatthew Dillon  * 3. Neither the name of The DragonFly Project nor the names of its
18f03672ecSMatthew Dillon  *    contributors may be used to endorse or promote products derived
19f03672ecSMatthew Dillon  *    from this software without specific, prior written permission.
20f03672ecSMatthew Dillon  *
21f03672ecSMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22f03672ecSMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23f03672ecSMatthew Dillon  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24f03672ecSMatthew Dillon  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25f03672ecSMatthew Dillon  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26f03672ecSMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27f03672ecSMatthew Dillon  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28f03672ecSMatthew Dillon  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29f03672ecSMatthew Dillon  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30f03672ecSMatthew Dillon  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31f03672ecSMatthew Dillon  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32f03672ecSMatthew Dillon  * SUCH DAMAGE.
33f03672ecSMatthew Dillon  */
3446558838SMatthew Dillon 
35f03672ecSMatthew Dillon /*
3646558838SMatthew Dillon  * CCMS - Cache Coherency Management System.
371ad77ed9SMatthew Dillon  *
3846558838SMatthew Dillon  * This subsystem can be tied into a VFS in order to supply persistent
3946558838SMatthew Dillon  * cache management state for cluster or for remote cache-coherent operations.
40f03672ecSMatthew Dillon  *
4146558838SMatthew Dillon  * Local and cluster/remote cache state is maintained in a cache-coherent
4246558838SMatthew Dillon  * fashion as well as integrated into the VFS's inode locking subsystem
4346558838SMatthew Dillon  * (as a means of avoiding deadlocks).
44f03672ecSMatthew Dillon  *
4546558838SMatthew Dillon  * To operate properly the VFS must maintain a complete directory topology
4646558838SMatthew Dillon  * leading to any given vnode/inode either open or cached by the system.
4746558838SMatthew Dillon  * The vnode/namecache subsystem does not have to implement this but the
4846558838SMatthew Dillon  * VFS (aka HAMMER2) does.
491ad77ed9SMatthew Dillon  *
5046558838SMatthew Dillon  * The filesystem embeds CCMS_CST structures in its internal inode
5146558838SMatthew Dillon  * representatino as needed and implements callback to allow CCMS to
5246558838SMatthew Dillon  * do topological recursions.
531ad77ed9SMatthew Dillon  *
5446558838SMatthew Dillon  * --
551ad77ed9SMatthew Dillon  *
5646558838SMatthew Dillon  * The CCMS_CST structures represent granted cache and local locking states.
5746558838SMatthew Dillon  * Grants can be recursively inherited, minimizing protocol overhead in
5846558838SMatthew Dillon  * situations where there are no conflicts of interest.
591ad77ed9SMatthew Dillon  *
6046558838SMatthew Dillon  * --
611ad77ed9SMatthew Dillon  *
6246558838SMatthew Dillon  * CCMS supports active front-end 'locks' on data objects utilizing the
6346558838SMatthew Dillon  * ccms_inode, key, and desired cache state.  It can grant the lock based
6446558838SMatthew Dillon  * on inherited CST state and prevents downgrading of the CST by other
6546558838SMatthew Dillon  * parties or threads while the lock is held.  The CST's arranged
6646558838SMatthew Dillon  * lock within the embedded CCMS_INODE and ref-counts the related CST.
67f03672ecSMatthew Dillon  */
68f03672ecSMatthew Dillon 
69f03672ecSMatthew Dillon #ifndef _SYS_CCMS_H_
70f03672ecSMatthew Dillon #define _SYS_CCMS_H_
71f03672ecSMatthew Dillon 
72f03672ecSMatthew Dillon #ifndef _SYS_TYPES_H_
73f03672ecSMatthew Dillon #include <sys/types.h>
74f03672ecSMatthew Dillon #endif
75f03672ecSMatthew Dillon #ifndef _SYS_PARAM_H_
76f03672ecSMatthew Dillon #include <sys/param.h>
77f03672ecSMatthew Dillon #endif
78f03672ecSMatthew Dillon #ifndef _SYS_SERIALIZE_H_
79f03672ecSMatthew Dillon #include <sys/serialize.h>
80f03672ecSMatthew Dillon #endif
81f03672ecSMatthew Dillon #ifndef _SYS_SPINLOCK_H_
82f03672ecSMatthew Dillon #include <sys/spinlock.h>
83f03672ecSMatthew Dillon #endif
84f03672ecSMatthew Dillon 
8546558838SMatthew Dillon typedef uint64_t	ccms_key_t;
8646558838SMatthew Dillon typedef uint64_t	ccms_tid_t;
871ad77ed9SMatthew Dillon typedef uint8_t		ccms_state_t;
8846558838SMatthew Dillon typedef uint8_t		ccms_type_t;
891ad77ed9SMatthew Dillon 
90f03672ecSMatthew Dillon struct ccms_cst;
91f03672ecSMatthew Dillon 
92f03672ecSMatthew Dillon /*
9346558838SMatthew Dillon  * CCMS_STATE_T - CCMS cache states.
94f03672ecSMatthew Dillon  *
951ad77ed9SMatthew Dillon  * INVALID   -	Cache state is unknown and must be acquired.
96f03672ecSMatthew Dillon  *
9746558838SMatthew Dillon  * ALLOWED   -  Cache state allows any recursive state to be acquired.
98f03672ecSMatthew Dillon  *
9994491fa0SMatthew Dillon  * SHARED    -	Cache state allows shared access.
1001ad77ed9SMatthew Dillon  *
10194491fa0SMatthew Dillon  * EXCLUSIVE -  Cache state allows exclusive access.
1021ad77ed9SMatthew Dillon  *
10346558838SMatthew Dillon  * CCMS Implements an extended MESI model.  The extensions are implemented
10446558838SMatthew Dillon  * as CCMS_TYPE_T flags.
105f03672ecSMatthew Dillon  */
1061ad77ed9SMatthew Dillon #define CCMS_STATE_INVALID	0	/* unknown cache state */
1071ad77ed9SMatthew Dillon #define CCMS_STATE_SHARED	2	/* clean, shared, read-only */
10846558838SMatthew Dillon #define CCMS_STATE_EXCLUSIVE	3	/* clean, exclusive, read-only */
109f03672ecSMatthew Dillon 
110f03672ecSMatthew Dillon /*
11146558838SMatthew Dillon  * CCMS_TYPE_T FLAGS
11246558838SMatthew Dillon  *
11346558838SMatthew Dillon  * INHERITED -  Indicates the state field was inherited and was not directly
11446558838SMatthew Dillon  *		granted by the cluster controller.
11546558838SMatthew Dillon  *
11646558838SMatthew Dillon  * MODIFIED  -  This is a type-field flag associated with an EXCLUSIVE cache
11746558838SMatthew Dillon  *		state
11846558838SMatthew Dillon  *
11946558838SMatthew Dillon  * MASTER    -  This is a type-field flag associated with an EXCLUSIVE+MODIFIED
12046558838SMatthew Dillon  *		cache state which indicates that slaves might be present
12146558838SMatthew Dillon  *		which are caching our unsynchronized state.
12246558838SMatthew Dillon  *
12346558838SMatthew Dillon  * SLAVE     -  This is a type-field flag associated with the SHARED cache
12446558838SMatthew Dillon  *		state which indicates that the data present in our memory
12546558838SMatthew Dillon  *		caches is being mastered elsewhere and has not been
12646558838SMatthew Dillon  *		synchronized (meaning no quorum protocol has been run to
12746558838SMatthew Dillon  *		sync the data yet).  Thus only the version of the data in
12846558838SMatthew Dillon  *		our memory and its originator is valid.
12946558838SMatthew Dillon  *
13046558838SMatthew Dillon  * QSLAVE    -  This indicates that the slaved data is also present in the
13146558838SMatthew Dillon  *		memory caches of a quorum of master nodes.
13246558838SMatthew Dillon  */
13346558838SMatthew Dillon #define CCMS_TYPE_INHERITED	0x01
13446558838SMatthew Dillon #define CCMS_TYPE_MODIFIED	0x02
13546558838SMatthew Dillon #define CCMS_TYPE_MASTER	0x04
13646558838SMatthew Dillon #define CCMS_TYPE_SLAVE		0x08
13746558838SMatthew Dillon #define CCMS_TYPE_QSALVE	0x10
13846558838SMatthew Dillon #define CCMS_TYPE_RECURSIVE	0x80
13946558838SMatthew Dillon 
14046558838SMatthew Dillon /*
14146558838SMatthew Dillon  * CCMS_CST - Low level locking state, persistent cache state
142f03672ecSMatthew Dillon  *
14346558838SMatthew Dillon  * Offset ranges are byte-inclusive, allowing the entire 64 bit data space
144f03672ecSMatthew Dillon  * to be represented without overflowing the edge case.  For example, a
1451ad77ed9SMatthew Dillon  * 64 byte area might be represented as (0,63).  The offsets are UNSIGNED
1461ad77ed9SMatthew Dillon  * entities.
14746558838SMatthew Dillon  *
148f3843dc2SMatthew Dillon  * High level CST locks must be obtained top-down.
149f3843dc2SMatthew Dillon  *
150f3843dc2SMatthew Dillon  * count - Negative value indicates active exclusive lock, positive value
15146558838SMatthew Dillon  *	   indicates active shared lock.
152f3843dc2SMatthew Dillon  *
153f3843dc2SMatthew Dillon  * spin  - Structural spinlock, typically just one is held at a time.
154f3843dc2SMatthew Dillon  *	   However, to complement the top-down nature of the higher level
155f3843dc2SMatthew Dillon  *	   lock we allow the spin lock to be held recursively in a bottom-up
156f3843dc2SMatthew Dillon  *	   fashion for race-to-root flags updates and lastdrop iterations.
157f03672ecSMatthew Dillon  */
158f03672ecSMatthew Dillon struct ccms_cst {
159*f3ee5e44STomohiro Kusumi 	hammer2_spin_t	spin;		/* thread spinlock */
16046558838SMatthew Dillon 	ccms_state_t	state;		/* granted or inherited state */
16146558838SMatthew Dillon 	ccms_type_t	type;		/* CST type and flags */
16246558838SMatthew Dillon 	uint8_t		unused02;
16346558838SMatthew Dillon 	uint8_t		unused03;
1641ad77ed9SMatthew Dillon 
165a0ed3c24SMatthew Dillon 	int32_t		upgrade;	/* upgrades pending */
16646558838SMatthew Dillon 	int32_t		count;		/* active shared/exclusive count */
16746558838SMatthew Dillon 	int32_t		blocked;	/* wakeup blocked on release */
16846558838SMatthew Dillon 	thread_t	td;		/* if excl lock (count < 0) */
169f03672ecSMatthew Dillon };
170f03672ecSMatthew Dillon 
1711ad77ed9SMatthew Dillon typedef struct ccms_cst		ccms_cst_t;
172f03672ecSMatthew Dillon 
173f03672ecSMatthew Dillon /*
174f03672ecSMatthew Dillon  * Kernel API
175f03672ecSMatthew Dillon  */
176f03672ecSMatthew Dillon #ifdef _KERNEL
177f03672ecSMatthew Dillon 
17894491fa0SMatthew Dillon void ccms_cst_init(ccms_cst_t *cst);
17946558838SMatthew Dillon void ccms_cst_uninit(ccms_cst_t *cst);
1801ad77ed9SMatthew Dillon 
18146558838SMatthew Dillon void ccms_thread_lock(ccms_cst_t *cst, ccms_state_t state);
18246558838SMatthew Dillon int ccms_thread_lock_nonblock(ccms_cst_t *cst, ccms_state_t state);
183476d2aadSMatthew Dillon ccms_state_t ccms_thread_lock_temp_release(ccms_cst_t *cst);
1849797e933SMatthew Dillon void ccms_thread_lock_temp_restore(ccms_cst_t *cst, ccms_state_t ostate);
185a0ed3c24SMatthew Dillon ccms_state_t ccms_thread_lock_upgrade(ccms_cst_t *cst);
1869797e933SMatthew Dillon void ccms_thread_lock_downgrade(ccms_cst_t *cst, ccms_state_t ostate);
18746558838SMatthew Dillon void ccms_thread_unlock(ccms_cst_t *cst);
188731b2a84SMatthew Dillon void ccms_thread_unlock_upgraded(ccms_cst_t *cst, ccms_state_t ostate);
189a0ed3c24SMatthew Dillon int ccms_thread_lock_owned(ccms_cst_t *cst);
190a5913bdfSMatthew Dillon void ccms_thread_lock_setown(ccms_cst_t *cst);
19146558838SMatthew Dillon 
192f03672ecSMatthew Dillon #endif
193f03672ecSMatthew Dillon 
194f03672ecSMatthew Dillon #endif
195