1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2014 by Chunwei Chen. All rights reserved. 23 * Copyright (c) 2016, 2019 by Delphix. All rights reserved. 24 */ 25 26 #ifndef _ABD_IMPL_H 27 #define _ABD_IMPL_H 28 29 #include <sys/abd.h> 30 #include <sys/wmsum.h> 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 typedef enum abd_stats_op { 37 ABDSTAT_INCR, /* Increase abdstat values */ 38 ABDSTAT_DECR /* Decrease abdstat values */ 39 } abd_stats_op_t; 40 41 struct scatterlist; /* forward declaration */ 42 43 struct abd_iter { 44 /* public interface */ 45 void *iter_mapaddr; /* addr corresponding to iter_pos */ 46 size_t iter_mapsize; /* length of data valid at mapaddr */ 47 48 /* private */ 49 abd_t *iter_abd; /* ABD being iterated through */ 50 size_t iter_pos; 51 size_t iter_offset; /* offset in current sg/abd_buf, */ 52 /* abd_offset included */ 53 struct scatterlist *iter_sg; /* current sg */ 54 }; 55 56 extern abd_t *abd_zero_scatter; 57 58 abd_t *abd_gang_get_offset(abd_t *, size_t *); 59 abd_t *abd_alloc_struct(size_t); 60 void abd_free_struct(abd_t *); 61 62 /* 63 * OS specific functions 64 */ 65 66 abd_t *abd_alloc_struct_impl(size_t); 67 abd_t *abd_get_offset_scatter(abd_t *, abd_t *, size_t, size_t); 68 void abd_free_struct_impl(abd_t *); 69 void abd_alloc_chunks(abd_t *, size_t); 70 void abd_free_chunks(abd_t *); 71 boolean_t abd_size_alloc_linear(size_t); 72 void abd_update_scatter_stats(abd_t *, abd_stats_op_t); 73 void abd_update_linear_stats(abd_t *, abd_stats_op_t); 74 void abd_verify_scatter(abd_t *); 75 void abd_free_linear_page(abd_t *); 76 /* OS specific abd_iter functions */ 77 void abd_iter_init(struct abd_iter *, abd_t *); 78 boolean_t abd_iter_at_end(struct abd_iter *); 79 void abd_iter_advance(struct abd_iter *, size_t); 80 void abd_iter_map(struct abd_iter *); 81 void abd_iter_unmap(struct abd_iter *); 82 83 /* 84 * Helper macros 85 */ 86 #define ABDSTAT_INCR(stat, val) \ 87 wmsum_add(&abd_sums.stat, (val)) 88 #define ABDSTAT_BUMP(stat) ABDSTAT_INCR(stat, 1) 89 #define ABDSTAT_BUMPDOWN(stat) ABDSTAT_INCR(stat, -1) 90 91 #define ABD_SCATTER(abd) (abd->abd_u.abd_scatter) 92 #define ABD_LINEAR_BUF(abd) (abd->abd_u.abd_linear.abd_buf) 93 #define ABD_GANG(abd) (abd->abd_u.abd_gang) 94 95 #if defined(_KERNEL) 96 #if defined(__FreeBSD__) 97 #define abd_enter_critical(flags) critical_enter() 98 #define abd_exit_critical(flags) critical_exit() 99 #else 100 #define abd_enter_critical(flags) local_irq_save(flags) 101 #define abd_exit_critical(flags) local_irq_restore(flags) 102 #endif 103 #else /* !_KERNEL */ 104 #define abd_enter_critical(flags) ((void)0) 105 #define abd_exit_critical(flags) ((void)0) 106 #endif 107 108 #ifdef __cplusplus 109 } 110 #endif 111 112 #endif /* _ABD_IMPL_H */ 113