Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2019 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/util.h"
7 : : #include "spdk/log.h"
8 : :
9 : : void
10 : 14928 : spdk_iov_memset(struct iovec *iovs, int iovcnt, int c)
11 : : {
12 : 14928 : int iov_idx = 0;
13 : : struct iovec *iov;
14 : :
15 [ + + ]: 29870 : while (iov_idx < iovcnt) {
16 [ - + ]: 14942 : iov = &iovs[iov_idx];
17 [ - + - + : 14942 : memset(iov->iov_base, c, iov->iov_len);
- + - + -
+ ]
18 [ - + ]: 14942 : iov_idx++;
19 : : }
20 : 14928 : }
21 : :
22 : : size_t
23 : 221636096 : spdk_ioviter_first(struct spdk_ioviter *iter,
24 : : struct iovec *siov, size_t siovcnt,
25 : : struct iovec *diov, size_t diovcnt,
26 : : void **src, void **dst)
27 : : {
28 : 35549620 : struct iovec *iovs[2];
29 : 35549620 : size_t iovcnts[2];
30 : 35549620 : void *out[2];
31 : : size_t len;
32 : :
33 [ + - + - ]: 221636096 : iovs[0] = siov;
34 [ + - + - ]: 221636096 : iovcnts[0] = siovcnt;
35 : :
36 [ + - + - : 221636096 : iovs[1] = diov;
+ - ]
37 [ + - + - : 221636096 : iovcnts[1] = diovcnt;
+ - ]
38 : :
39 : 221636096 : len = spdk_ioviter_firstv(iter, 2, iovs, iovcnts, out);
40 : :
41 [ + + ]: 221636096 : if (len > 0) {
42 [ + - + - : 222215876 : *src = out[0];
+ - ]
43 [ + - + - : 222215876 : *dst = out[1];
+ - + - ]
44 : 31216675 : }
45 : :
46 : 222795668 : return len;
47 : : }
48 : :
49 : : size_t
50 : 222082839 : spdk_ioviter_firstv(struct spdk_ioviter *iter,
51 : : uint32_t count,
52 : : struct iovec **iov,
53 : : size_t *iovcnt,
54 : : void **out)
55 : : {
56 : : struct spdk_single_ioviter *it;
57 : : uint32_t i;
58 : :
59 [ + - + - ]: 222082839 : iter->count = count;
60 : :
61 [ + + ]: 666667301 : for (i = 0; i < count; i++) {
62 [ + - + - : 444584462 : it = &iter->iters[i];
+ - ]
63 [ + - + - : 444584462 : it->iov = iov[i];
+ - + - ]
64 [ + - + - : 444584462 : it->iovcnt = iovcnt[i];
+ - + - ]
65 [ + - + - ]: 444584462 : it->idx = 0;
66 [ + - + - : 444584462 : it->iov_len = iov[i][0].iov_len;
+ - + - +
- + - +
- ]
67 [ + - + - : 444584462 : it->iov_base = iov[i][0].iov_base;
+ - + - +
- + - +
- ]
68 : 61711506 : }
69 : :
70 : 222082839 : return spdk_ioviter_nextv(iter, out);
71 : : }
72 : :
73 : : size_t
74 : 232207577 : spdk_ioviter_next(struct spdk_ioviter *iter, void **src, void **dst)
75 : : {
76 : 36254626 : void *out[2];
77 : : size_t len;
78 : :
79 : 232207577 : len = spdk_ioviter_nextv(iter, out);
80 : :
81 [ + + ]: 232207577 : if (len > 0) {
82 [ # # # # : 10050697 : *src = out[0];
# # ]
83 [ # # # # : 10050697 : *dst = out[1];
# # # # ]
84 : 951 : }
85 : :
86 : 232207577 : return len;
87 : : }
88 : :
89 : : size_t
90 : 454769402 : spdk_ioviter_nextv(struct spdk_ioviter *iter, void **out)
91 : : {
92 : : struct spdk_single_ioviter *it;
93 : : size_t len;
94 : : uint32_t i;
95 : :
96 : : /* Figure out the minimum size of each iovec's next segment */
97 : 454769402 : len = UINT32_MAX;
98 [ + + + - : 1030003542 : for (i = 0; i < iter->count; i++) {
+ + ]
99 [ + - + - : 797354792 : it = &iter->iters[i];
+ - ]
100 [ + + + + : 797354792 : if (it->idx == it->iovcnt || it->iov_len == 0) {
+ - + - +
+ + - + -
+ + ]
101 : : /* This element has 0 bytes remaining, so we're done. */
102 : 222120652 : return 0;
103 : : }
104 : :
105 [ + + + - : 575234140 : len = spdk_min(len, it->iov_len);
- + + - +
- ]
106 : 62219081 : }
107 : :
108 [ + + + - : 698253972 : for (i = 0; i < iter->count; i++) {
+ + ]
109 [ + - + - : 465605222 : it = &iter->iters[i];
+ - ]
110 : :
111 [ + - + - : 465605222 : out[i] = it->iov_base;
+ - + - ]
112 : :
113 [ + + + - : 465605222 : if (it->iov_len == len) {
+ + ]
114 : : /* Advance to next element */
115 [ + - ]: 342663736 : it->idx++;
116 [ + + + - : 342663736 : if (it->idx != it->iovcnt) {
+ - + - +
+ ]
117 : : /* Set up for next element */
118 [ - + - + : 21962233 : it->iov_len = it->iov[it->idx].iov_len;
- + - + -
+ - + - +
- + - + ]
119 [ - + - + : 21962233 : it->iov_base = it->iov[it->idx].iov_base;
- + - + -
+ - + - +
- + - + ]
120 : 34518 : }
121 : 62580099 : } else {
122 : : /* Partial buffer */
123 [ + - + - : 122941486 : it->iov_base += len;
+ - ]
124 [ + - + - ]: 122941486 : it->iov_len -= len;
125 : : }
126 : 62632726 : }
127 : :
128 : 232648750 : return len;
129 : 62430474 : }
130 : :
131 : : size_t
132 : 122558114 : spdk_iovcpy(struct iovec *siov, size_t siovcnt, struct iovec *diov, size_t diovcnt)
133 : : {
134 : 615338 : struct spdk_ioviter iter;
135 : : size_t len, total_sz;
136 : 615338 : void *src, *dst;
137 : :
138 : 122558114 : total_sz = 0;
139 [ + + ]: 122643395 : for (len = spdk_ioviter_first(&iter, siov, siovcnt, diov, diovcnt, &src, &dst);
140 [ + + ]: 246931581 : len != 0;
141 : 124373467 : len = spdk_ioviter_next(&iter, &src, &dst)) {
142 [ - + - + ]: 124373467 : memcpy(dst, src, len);
143 : 124373467 : total_sz += len;
144 : 85281 : }
145 : :
146 : 122558114 : return total_sz;
147 : : }
148 : :
149 : : size_t
150 : 140 : spdk_iovmove(struct iovec *siov, size_t siovcnt, struct iovec *diov, size_t diovcnt)
151 : : {
152 : 105 : struct spdk_ioviter iter;
153 : : size_t len, total_sz;
154 : 105 : void *src, *dst;
155 : :
156 : 140 : total_sz = 0;
157 [ + + ]: 175 : for (len = spdk_ioviter_first(&iter, siov, siovcnt, diov, diovcnt, &src, &dst);
158 [ + + ]: 280 : len != 0;
159 : 140 : len = spdk_ioviter_next(&iter, &src, &dst)) {
160 [ - + - + ]: 140 : memmove(dst, src, len);
161 : 140 : total_sz += len;
162 : 35 : }
163 : :
164 : 140 : return total_sz;
165 : : }
166 : :
167 : : void
168 : 2709671 : spdk_iov_xfer_init(struct spdk_iov_xfer *ix, struct iovec *iovs, int iovcnt)
169 : : {
170 [ + - + - ]: 2709671 : ix->iovs = iovs;
171 [ + - + - ]: 2709671 : ix->iovcnt = iovcnt;
172 [ + - + - ]: 2709671 : ix->cur_iov_idx = 0;
173 [ + - + - ]: 2709671 : ix->cur_iov_offset = 0;
174 : 2709671 : }
175 : :
176 : : static size_t
177 : 2715599 : iov_xfer(struct spdk_iov_xfer *ix, const void *buf, size_t buf_len, bool to_buf)
178 : : {
179 : 2715599 : size_t len, iov_remain_len, copied_len = 0;
180 : : struct iovec *iov;
181 : :
182 [ + + ]: 2715599 : if (buf_len == 0) {
183 : 0 : return 0;
184 : : }
185 : :
186 [ + + + - : 7849110 : while (ix->cur_iov_idx < ix->iovcnt) {
+ - + - +
- ]
187 [ + - + - : 5278782 : iov = &ix->iovs[ix->cur_iov_idx];
+ - + - +
- ]
188 [ + - + - : 5278782 : iov_remain_len = iov->iov_len - ix->cur_iov_offset;
+ - + - ]
189 [ + + ]: 5278782 : if (iov_remain_len == 0) {
190 [ # # # # ]: 2570251 : ix->cur_iov_idx++;
191 [ # # # # ]: 2570251 : ix->cur_iov_offset = 0;
192 : 2570251 : continue;
193 : : }
194 : :
195 [ + + ]: 2708531 : len = spdk_min(iov_remain_len, buf_len - copied_len);
196 : :
197 [ + + - + ]: 2708531 : if (to_buf) {
198 [ - + - + : 138938 : memcpy((char *)buf + copied_len,
# # ]
199 [ # # # # : 138836 : (char *)iov->iov_base + ix->cur_iov_offset, len);
# # # # #
# ]
200 : 102 : } else {
201 [ - + - + : 3079841 : memcpy((char *)iov->iov_base + ix->cur_iov_offset,
- + - + -
+ - + -
+ ]
202 [ - + ]: 510146 : (const char *)buf + copied_len, len);
203 : : }
204 : 2708531 : copied_len += len;
205 [ + - + - ]: 2708531 : ix->cur_iov_offset += len;
206 : :
207 [ + + ]: 2708531 : if (buf_len == copied_len) {
208 : 145271 : return copied_len;
209 : : }
210 : : }
211 : :
212 : 2570328 : return copied_len;
213 : 517438 : }
214 : :
215 : : size_t
216 : 2569429 : spdk_iov_xfer_from_buf(struct spdk_iov_xfer *ix, const void *buf, size_t buf_len)
217 : : {
218 : 2569429 : return iov_xfer(ix, buf, buf_len, false);
219 : : }
220 : :
221 : : size_t
222 : 138784 : spdk_iov_xfer_to_buf(struct spdk_iov_xfer *ix, const void *buf, size_t buf_len)
223 : : {
224 : 138784 : return iov_xfer(ix, buf, buf_len, true);
225 : : }
226 : :
227 : : void
228 : 8203 : spdk_copy_iovs_to_buf(void *buf, size_t buf_len, struct iovec *iovs, int iovcnt)
229 : : {
230 : 8169 : struct spdk_iov_xfer ix;
231 : :
232 : 8203 : spdk_iov_xfer_init(&ix, iovs, iovcnt);
233 : 8203 : spdk_iov_xfer_to_buf(&ix, buf, buf_len);
234 : 8203 : }
235 : :
236 : : void
237 : 2556878 : spdk_copy_buf_to_iovs(struct iovec *iovs, int iovcnt, void *buf, size_t buf_len)
238 : : {
239 : 1891810 : struct spdk_iov_xfer ix;
240 : :
241 : 2556878 : spdk_iov_xfer_init(&ix, iovs, iovcnt);
242 : 2556878 : spdk_iov_xfer_from_buf(&ix, buf, buf_len);
243 : 2556878 : }
|