Motr  M0
zerovec.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2011-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #include "ut/ut.h"
24 #include "lib/vec.h"
25 #include "lib/memory.h"
26 #include "lib/arith.h"
27 #include "lib/errno.h" /* ENOENT */
28 
29 #ifdef __KERNEL__
30 #include <linux/pagemap.h> /* PAGE_SIZE */
31 #endif
32 
34  ZEROVEC_UT_SEG_SIZE = M0_0VEC_ALIGN,
36 };
37 
39 
40 static void zerovec_init(struct m0_0vec *zvec, const m0_bcount_t seg_size)
41 {
42  int rc;
43 
45  M0_UT_ASSERT(rc == 0);
46 }
47 
48 #ifndef __KERNEL__
49 
51 
52 static void zerovec_init_bvec(void)
53 {
54  uint32_t i;
55  struct m0_0vec zvec;
56  struct m0_bufvec bufvec;
57 
59 
60  /* Have to manually allocate buffers for m0_bufvec that are
61  aligned on 4k boundary. */
64  M0_UT_ASSERT(bufvec.ov_vec.v_count != NULL);
66  M0_UT_ASSERT(bufvec.ov_buf != NULL);
67 
68  for (i = 0; i < bufvec.ov_vec.v_nr; ++i) {
70  M0_0VEC_SHIFT);
71  M0_UT_ASSERT(bufvec.ov_buf[i] != NULL);
73  }
74 
75  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i)
76  indices[i] = i;
77 
78  m0_0vec_bvec_init(&zvec, &bufvec, indices);
79 
80  /* Checks if buffer array, index array and segment count array
81  are populated correctly. */
82  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i) {
83  M0_UT_ASSERT(zvec.z_bvec.ov_buf[i] == bufvec.ov_buf[i]);
86  M0_UT_ASSERT(zvec.z_index[i] == indices[i]);
87  }
88 
89  m0_bufvec_free(&bufvec);
90  m0_0vec_fini(&zvec);
91 }
92 
93 static void zerovec_init_bufs(void)
94 {
95  char **bufs;
96  uint32_t i;
97  uint64_t seed;
98  struct m0_0vec zvec;
99 
100  seed = 0;
102 
104  M0_UT_ASSERT(bufs != NULL);
105 
106  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i) {
107  bufs[i] = m0_alloc_aligned(ZEROVEC_UT_SEG_SIZE, M0_0VEC_SHIFT);
108  M0_UT_ASSERT(bufs[i] != NULL);
111  }
112 
113  m0_0vec_bufs_init(&zvec, (void**)bufs, indices, counts,
115 
116  /* Checks if buffer array, index array and segment count array
117  are populated correctly. */
118  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i) {
119  M0_UT_ASSERT(zvec.z_index[i] == indices[i]);
121  M0_UT_ASSERT(zvec.z_bvec.ov_buf[i] == bufs[i]);
122  }
124 
125  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i)
126  m0_free(bufs[i]);
127  m0_free(bufs);
128  m0_0vec_fini(&zvec);
129 }
130 
131 static void zerovec_init_cbuf(void)
132 {
133  int i;
134  int rc;
135  uint64_t seed;
136  struct m0_buf bufs[ZEROVEC_UT_SEGS_NR];
137  struct m0_0vec zvec;
138 
139  seed = 0;
141 
142  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i) {
144  M0_0VEC_SHIFT);
145  M0_UT_ASSERT(bufs[i].b_addr != NULL);
146  bufs[i].b_nob = ZEROVEC_UT_SEG_SIZE;
148 
149  rc = m0_0vec_cbuf_add(&zvec, &bufs[i], &indices[i]);
150  M0_UT_ASSERT(rc == 0);
151  }
152 
153  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i) {
154  M0_UT_ASSERT(zvec.z_index[i] == indices[i]);
155  M0_UT_ASSERT(zvec.z_bvec.ov_buf[i] == bufs[i].b_addr);
156  M0_UT_ASSERT(zvec.z_bvec.ov_vec.v_count[i] == bufs[i].b_nob);
157  }
158 
159  /* Tries to add more buffers beyond zerovec's capacity. Should fail. */
160  rc = m0_0vec_cbuf_add(&zvec, &bufs[0], &indices[0]);
161  M0_UT_ASSERT(rc == -EMSGSIZE);
162 
164 
165  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i)
166  m0_free(bufs[i].b_addr);
167  m0_0vec_fini(&zvec);
168 }
169 #else
170 
171 static void zerovec_init_pages(void)
172 {
173  int rc;
174  uint32_t i;
175  uint64_t seed;
176  struct page **pages;
177  struct m0_0vec zvec;
178 
179  seed = 0;
180  zerovec_init(&zvec, PAGE_SIZE);
181 
183  M0_UT_ASSERT(pages != NULL);
184  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i) {
185  pages[i] = alloc_page(GFP_KERNEL);
186  M0_UT_ASSERT(pages[i] != NULL);
187  }
188 
189  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i) {
191  rc = m0_0vec_page_add(&zvec, pages[i], indices[i]);
192  M0_UT_ASSERT(rc == 0);
193  }
194 
195  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i) {
196  M0_UT_ASSERT(zvec.z_index[i] == indices[i]);
197  M0_UT_ASSERT(zvec.z_bvec.ov_buf[i] ==
198  page_address(pages[i]));
199  M0_UT_ASSERT(zvec.z_bvec.ov_vec.v_count[i] == PAGE_SIZE);
200  }
201 
202  M0_UT_ASSERT(zvec.z_bvec.ov_vec.v_nr == ZEROVEC_UT_SEGS_NR);
203 
204  /* Tries to add more pages beyond zerovec's capacity. Should fail. */
205  rc = m0_0vec_page_add(&zvec, pages[0], indices[0]);
206  M0_UT_ASSERT(rc == -EMSGSIZE);
207 
208  for (i = 0; i < ZEROVEC_UT_SEGS_NR; ++i)
209  __free_page(pages[i]);
210  m0_free(pages);
211  m0_0vec_fini(&zvec);
212 }
213 #endif
214 
215 void test_zerovec(void)
216 {
217 #ifndef __KERNEL__
218  /* Populate the zero vector using a m0_bufvec structure. */
220 
221  /* Populate the zero vector using array of buffers, indices
222  and counts. */
224 
225  /* Populate the zero vector using a m0_buf structure and
226  array of indices. */
228 #else
229  /* Populate the zero vector using a page. */
230  zerovec_init_pages();
231 #endif
232 }
static m0_bcount_t seg_size
Definition: net.c:118
M0_INTERNAL int m0_0vec_init(struct m0_0vec *zvec, uint32_t segs_nr)
Definition: vec.c:826
static m0_bindex_t indices[ZEROVEC_UT_SEGS_NR]
Definition: zerovec.c:38
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
M0_INTERNAL void m0_0vec_fini(struct m0_0vec *zvec)
Definition: vec.c:794
#define NULL
Definition: misc.h:38
m0_bindex_t * z_index
Definition: vec.h:516
void * b_addr
Definition: buf.h:39
M0_INTERNAL void m0_0vec_bvec_init(struct m0_0vec *zvec, const struct m0_bufvec *src, const m0_bindex_t *index)
Definition: vec.c:853
struct m0_vec ov_vec
Definition: vec.h:147
uint64_t m0_bindex_t
Definition: types.h:80
uint64_t m0_bcount_t
Definition: types.h:77
#define PAGE_SIZE
Definition: lnet_ut.c:277
void ** ov_buf
Definition: vec.h:149
static void zerovec_init_bufs(void)
Definition: zerovec.c:93
Definition: buf.h:37
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
int i
Definition: dir.c:1033
static void zerovec_init(struct m0_0vec *zvec, const m0_bcount_t seg_size)
Definition: zerovec.c:40
void * b_addr
Definition: buf.h:231
M0_INTERNAL uint64_t m0_rnd(uint64_t max, uint64_t *seed)
Definition: misc.c:115
static m0_bcount_t counts[ZEROVEC_UT_SEGS_NR]
Definition: zerovec.c:50
m0_bcount_t b_nob
Definition: buf.h:38
void test_zerovec(void)
Definition: zerovec.c:215
static void zerovec_init_cbuf(void)
Definition: zerovec.c:131
static void zerovec_init_bvec(void)
Definition: zerovec.c:52
Definition: vec.h:512
M0_INTERNAL int m0_0vec_cbuf_add(struct m0_0vec *zvec, const struct m0_buf *buf, const m0_bindex_t *index)
Definition: vec.c:903
uint32_t v_nr
Definition: vec.h:51
m0_bcount_t * v_count
Definition: vec.h:53
struct m0_bufvec z_bvec
Definition: vec.h:514
M0_INTERNAL void m0_0vec_bufs_init(struct m0_0vec *zvec, void **bufs, const m0_bindex_t *index, const m0_bcount_t *counts, uint32_t segs_nr)
Definition: vec.c:876
M0_INTERNAL void * m0_alloc_aligned(size_t size, unsigned shift)
Definition: memory.c:168
M0_INTERNAL int m0_0vec_page_add(struct m0_0vec *zvec, struct page *pg, m0_bindex_t index)
Definition: kvec.c:28
ZEROVEC_UT_VALUES
Definition: zerovec.c:33
void m0_free(void *data)
Definition: memory.c:146
int32_t rc
Definition: trigger_fop.h:47
#define M0_UT_ASSERT(a)
Definition: ut.h:46
Definition: vec.h:145