aboutsummaryrefslogtreecommitdiff
path: root/include/sys/vdev_raidz_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/sys/vdev_raidz_impl.h')
-rw-r--r--include/sys/vdev_raidz_impl.h413
1 files changed, 0 insertions, 413 deletions
diff --git a/include/sys/vdev_raidz_impl.h b/include/sys/vdev_raidz_impl.h
deleted file mode 100644
index 8c8dcfb077f6..000000000000
--- a/include/sys/vdev_raidz_impl.h
+++ /dev/null
@@ -1,413 +0,0 @@
-// SPDX-License-Identifier: CDDL-1.0
-/*
- * 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 https://opensource.org/licenses/CDDL-1.0.
- * 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) 2016 Gvozden Nešković. All rights reserved.
- */
-
-#ifndef _VDEV_RAIDZ_H
-#define _VDEV_RAIDZ_H
-
-#include <sys/types.h>
-#include <sys/debug.h>
-#include <sys/kstat.h>
-#include <sys/abd.h>
-#include <sys/vdev_impl.h>
-#include <sys/abd_impl.h>
-#include <sys/zfs_rlock.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define CODE_P (0U)
-#define CODE_Q (1U)
-#define CODE_R (2U)
-
-#define PARITY_P (1U)
-#define PARITY_PQ (2U)
-#define PARITY_PQR (3U)
-
-#define TARGET_X (0U)
-#define TARGET_Y (1U)
-#define TARGET_Z (2U)
-
-/*
- * Parity generation methods indexes
- */
-enum raidz_math_gen_op {
- RAIDZ_GEN_P = 0,
- RAIDZ_GEN_PQ,
- RAIDZ_GEN_PQR,
- RAIDZ_GEN_NUM = 3
-};
-/*
- * Data reconstruction methods indexes
- */
-enum raidz_rec_op {
- RAIDZ_REC_P = 0,
- RAIDZ_REC_Q,
- RAIDZ_REC_R,
- RAIDZ_REC_PQ,
- RAIDZ_REC_PR,
- RAIDZ_REC_QR,
- RAIDZ_REC_PQR,
- RAIDZ_REC_NUM = 7
-};
-
-extern const char *const raidz_gen_name[RAIDZ_GEN_NUM];
-extern const char *const raidz_rec_name[RAIDZ_REC_NUM];
-
-/*
- * Methods used to define raidz implementation
- *
- * @raidz_gen_f Parity generation function
- * @par1 pointer to raidz_map
- * @raidz_rec_f Data reconstruction function
- * @par1 pointer to raidz_map
- * @par2 array of reconstruction targets
- * @will_work_f Function returns TRUE if impl. is supported on the system
- * @init_impl_f Function is called once on init
- * @fini_impl_f Function is called once on fini
- */
-typedef void (*raidz_gen_f)(void *);
-typedef int (*raidz_rec_f)(void *, const int *);
-typedef boolean_t (*will_work_f)(void);
-typedef void (*init_impl_f)(void);
-typedef void (*fini_impl_f)(void);
-
-#define RAIDZ_IMPL_NAME_MAX (20)
-
-typedef struct raidz_impl_ops {
- init_impl_f init;
- fini_impl_f fini;
- raidz_gen_f gen[RAIDZ_GEN_NUM]; /* Parity generate functions */
- raidz_rec_f rec[RAIDZ_REC_NUM]; /* Data reconstruction functions */
- will_work_f is_supported; /* Support check function */
- char name[RAIDZ_IMPL_NAME_MAX]; /* Name of the implementation */
-} raidz_impl_ops_t;
-
-
-typedef struct raidz_col {
- int rc_devidx; /* child device index for I/O */
- uint32_t rc_size; /* I/O size */
- uint64_t rc_offset; /* device offset */
- abd_t rc_abdstruct; /* rc_abd probably points here */
- abd_t *rc_abd; /* I/O data */
- abd_t *rc_orig_data; /* pre-reconstruction */
- int rc_error; /* I/O error for this device */
- uint8_t rc_tried:1; /* Did we attempt this I/O column? */
- uint8_t rc_skipped:1; /* Did we skip this I/O column? */
- uint8_t rc_need_orig_restore:1; /* need to restore from orig_data? */
- uint8_t rc_force_repair:1; /* Write good data to this column */
- uint8_t rc_allow_repair:1; /* Allow repair I/O to this column */
- uint8_t rc_latency_outlier:1; /* Latency outlier for this device */
- int rc_shadow_devidx; /* for double write during expansion */
- int rc_shadow_error; /* for double write during expansion */
- uint64_t rc_shadow_offset; /* for double write during expansion */
-} raidz_col_t;
-
-typedef struct raidz_row {
- int rr_cols; /* Regular column count */
- int rr_scols; /* Count including skipped columns */
- int rr_bigcols; /* Remainder data column count */
- int rr_missingdata; /* Count of missing data devices */
- int rr_missingparity; /* Count of missing parity devices */
- int rr_firstdatacol; /* First data column/parity count */
- abd_t *rr_abd_empty; /* dRAID empty sector buffer */
- int rr_nempty; /* empty sectors included in parity */
- int rr_outlier_cnt; /* Count of latency outlier devices */
-#ifdef ZFS_DEBUG
- uint64_t rr_offset; /* Logical offset for *_io_verify() */
- uint64_t rr_size; /* Physical size for *_io_verify() */
-#endif
- raidz_col_t rr_col[]; /* Flexible array of I/O columns */
-} raidz_row_t;
-
-typedef struct raidz_map {
- boolean_t rm_ecksuminjected; /* checksum error was injected */
- int rm_nrows; /* Regular row count */
- int rm_nskip; /* RAIDZ sectors skipped for padding */
- int rm_skipstart; /* Column index of padding start */
- int rm_original_width; /* pre-expansion width of raidz vdev */
- int rm_nphys_cols; /* num entries in rm_phys_col[] */
- zfs_locked_range_t *rm_lr;
- const raidz_impl_ops_t *rm_ops; /* RAIDZ math operations */
- raidz_col_t *rm_phys_col; /* if non-NULL, read i/o aggregation */
- raidz_row_t *rm_row[]; /* flexible array of rows */
-} raidz_map_t;
-
-/*
- * Nodes in vdev_raidz_t:vd_expand_txgs.
- * Blocks with physical birth time of re_txg or later have the specified
- * logical width (until the next node).
- */
-typedef struct reflow_node {
- uint64_t re_txg;
- uint64_t re_logical_width;
- avl_node_t re_link;
-} reflow_node_t;
-
-
-#define RAIDZ_ORIGINAL_IMPL (INT_MAX)
-
-extern const raidz_impl_ops_t vdev_raidz_scalar_impl;
-extern boolean_t raidz_will_scalar_work(void);
-
-#if defined(__x86_64) && defined(HAVE_SSE2) /* only x86_64 for now */
-extern const raidz_impl_ops_t vdev_raidz_sse2_impl;
-#endif
-#if defined(__x86_64) && defined(HAVE_SSSE3) /* only x86_64 for now */
-extern const raidz_impl_ops_t vdev_raidz_ssse3_impl;
-#endif
-#if defined(__x86_64) && defined(HAVE_AVX2) /* only x86_64 for now */
-extern const raidz_impl_ops_t vdev_raidz_avx2_impl;
-#endif
-#if defined(__x86_64) && defined(HAVE_AVX512F) /* only x86_64 for now */
-extern const raidz_impl_ops_t vdev_raidz_avx512f_impl;
-#endif
-#if defined(__x86_64) && defined(HAVE_AVX512BW) /* only x86_64 for now */
-extern const raidz_impl_ops_t vdev_raidz_avx512bw_impl;
-#endif
-#if defined(__aarch64__)
-extern const raidz_impl_ops_t vdev_raidz_aarch64_neon_impl;
-extern const raidz_impl_ops_t vdev_raidz_aarch64_neonx2_impl;
-#endif
-#if defined(__powerpc__)
-extern const raidz_impl_ops_t vdev_raidz_powerpc_altivec_impl;
-#endif
-
-/*
- * Commonly used raidz_map helpers
- *
- * raidz_parity Returns parity of the RAIDZ block
- * raidz_ncols Returns number of columns the block spans
- * Note, all rows have the same number of columns.
- * raidz_nbigcols Returns number of big columns
- * raidz_col_p Returns pointer to a column
- * raidz_col_size Returns size of a column
- * raidz_big_size Returns size of big columns
- * raidz_short_size Returns size of short columns
- */
-#define raidz_parity(rm) ((rm)->rm_row[0]->rr_firstdatacol)
-#define raidz_ncols(rm) ((rm)->rm_row[0]->rr_cols)
-#define raidz_nbigcols(rm) ((rm)->rm_bigcols)
-#define raidz_col_p(rm, c) ((rm)->rm_col + (c))
-#define raidz_col_size(rm, c) ((rm)->rm_col[c].rc_size)
-#define raidz_big_size(rm) (raidz_col_size(rm, CODE_P))
-#define raidz_short_size(rm) (raidz_col_size(rm, raidz_ncols(rm)-1))
-
-/*
- * Macro defines an RAIDZ parity generation method
- *
- * @code parity the function produce
- * @impl name of the implementation
- */
-#define _RAIDZ_GEN_WRAP(code, impl) \
-static void \
-impl ## _gen_ ## code(void *rrp) \
-{ \
- raidz_row_t *rr = (raidz_row_t *)rrp; \
- raidz_generate_## code ## _impl(rr); \
-}
-
-/*
- * Macro defines an RAIDZ data reconstruction method
- *
- * @code parity the function produce
- * @impl name of the implementation
- */
-#define _RAIDZ_REC_WRAP(code, impl) \
-static int \
-impl ## _rec_ ## code(void *rrp, const int *tgtidx) \
-{ \
- raidz_row_t *rr = (raidz_row_t *)rrp; \
- return (raidz_reconstruct_## code ## _impl(rr, tgtidx)); \
-}
-
-/*
- * Define all gen methods for an implementation
- *
- * @impl name of the implementation
- */
-#define DEFINE_GEN_METHODS(impl) \
- _RAIDZ_GEN_WRAP(p, impl); \
- _RAIDZ_GEN_WRAP(pq, impl); \
- _RAIDZ_GEN_WRAP(pqr, impl)
-
-/*
- * Define all rec functions for an implementation
- *
- * @impl name of the implementation
- */
-#define DEFINE_REC_METHODS(impl) \
- _RAIDZ_REC_WRAP(p, impl); \
- _RAIDZ_REC_WRAP(q, impl); \
- _RAIDZ_REC_WRAP(r, impl); \
- _RAIDZ_REC_WRAP(pq, impl); \
- _RAIDZ_REC_WRAP(pr, impl); \
- _RAIDZ_REC_WRAP(qr, impl); \
- _RAIDZ_REC_WRAP(pqr, impl)
-
-#define RAIDZ_GEN_METHODS(impl) \
-{ \
- [RAIDZ_GEN_P] = & impl ## _gen_p, \
- [RAIDZ_GEN_PQ] = & impl ## _gen_pq, \
- [RAIDZ_GEN_PQR] = & impl ## _gen_pqr \
-}
-
-#define RAIDZ_REC_METHODS(impl) \
-{ \
- [RAIDZ_REC_P] = & impl ## _rec_p, \
- [RAIDZ_REC_Q] = & impl ## _rec_q, \
- [RAIDZ_REC_R] = & impl ## _rec_r, \
- [RAIDZ_REC_PQ] = & impl ## _rec_pq, \
- [RAIDZ_REC_PR] = & impl ## _rec_pr, \
- [RAIDZ_REC_QR] = & impl ## _rec_qr, \
- [RAIDZ_REC_PQR] = & impl ## _rec_pqr \
-}
-
-
-typedef struct raidz_impl_kstat {
- uint64_t gen[RAIDZ_GEN_NUM]; /* gen method speed B/s */
- uint64_t rec[RAIDZ_REC_NUM]; /* rec method speed B/s */
-} raidz_impl_kstat_t;
-
-/*
- * Enumerate various multiplication constants
- * used in reconstruction methods
- */
-typedef enum raidz_mul_info {
- /* Reconstruct Q */
- MUL_Q_X = 0,
- /* Reconstruct R */
- MUL_R_X = 0,
- /* Reconstruct PQ */
- MUL_PQ_X = 0,
- MUL_PQ_Y = 1,
- /* Reconstruct PR */
- MUL_PR_X = 0,
- MUL_PR_Y = 1,
- /* Reconstruct QR */
- MUL_QR_XQ = 0,
- MUL_QR_X = 1,
- MUL_QR_YQ = 2,
- MUL_QR_Y = 3,
- /* Reconstruct PQR */
- MUL_PQR_XP = 0,
- MUL_PQR_XQ = 1,
- MUL_PQR_XR = 2,
- MUL_PQR_YU = 3,
- MUL_PQR_YP = 4,
- MUL_PQR_YQ = 5,
-
- MUL_CNT = 6
-} raidz_mul_info_t;
-
-/*
- * Powers of 2 in the Galois field.
- */
-extern const uint8_t vdev_raidz_pow2[256] __attribute__((aligned(256)));
-/* Logs of 2 in the Galois field defined above. */
-extern const uint8_t vdev_raidz_log2[256] __attribute__((aligned(256)));
-
-/*
- * Multiply a given number by 2 raised to the given power.
- */
-static inline uint8_t
-vdev_raidz_exp2(const uint8_t a, const unsigned exp)
-{
- if (a == 0)
- return (0);
-
- return (vdev_raidz_pow2[(exp + (unsigned)vdev_raidz_log2[a]) % 255]);
-}
-
-/*
- * Galois Field operations.
- *
- * gf_exp2 - computes 2 raised to the given power
- * gf_exp4 - computes 4 raised to the given power
- * gf_mul - multiplication
- * gf_div - division
- * gf_inv - multiplicative inverse
- */
-typedef unsigned gf_t;
-typedef unsigned gf_log_t;
-
-static inline gf_t
-gf_mul(const gf_t a, const gf_t b)
-{
- gf_log_t logsum;
-
- if (a == 0 || b == 0)
- return (0);
-
- logsum = (gf_log_t)vdev_raidz_log2[a] + (gf_log_t)vdev_raidz_log2[b];
-
- return ((gf_t)vdev_raidz_pow2[logsum % 255]);
-}
-
-static inline gf_t
-gf_div(const gf_t a, const gf_t b)
-{
- gf_log_t logsum;
-
- ASSERT3U(b, >, 0);
- if (a == 0)
- return (0);
-
- logsum = (gf_log_t)255 + (gf_log_t)vdev_raidz_log2[a] -
- (gf_log_t)vdev_raidz_log2[b];
-
- return ((gf_t)vdev_raidz_pow2[logsum % 255]);
-}
-
-static inline gf_t
-gf_inv(const gf_t a)
-{
- gf_log_t logsum;
-
- ASSERT3U(a, >, 0);
-
- logsum = (gf_log_t)255 - (gf_log_t)vdev_raidz_log2[a];
-
- return ((gf_t)vdev_raidz_pow2[logsum]);
-}
-
-static inline gf_t
-gf_exp2(gf_log_t exp)
-{
- return (vdev_raidz_pow2[exp % 255]);
-}
-
-static inline gf_t
-gf_exp4(gf_log_t exp)
-{
- ASSERT3U(exp, <=, 255);
- return ((gf_t)vdev_raidz_pow2[(2 * exp) % 255]);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _VDEV_RAIDZ_H */