Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2022 Marvell.
3 : : */
4 : :
5 : : #include <rte_bitops.h>
6 : : #include <rte_mldev_pmd.h>
7 : :
8 : : #include <roc_api.h>
9 : :
10 : : #include "cn10k_ml_ocm.h"
11 : :
12 : : #include "cnxk_ml_dev.h"
13 : : #include "cnxk_ml_model.h"
14 : :
15 : : /* OCM macros */
16 : : #define BYTE_LEN 8
17 : : #define OCM_MAP_WORD_SIZE (sizeof(uint8_t) * BYTE_LEN)
18 : : #define IS_BIT_SET(num, n) ((num) & (1 << (n)))
19 : : #define SET_BIT(num, n) ((num) | (1 << (n)))
20 : : #define CLEAR_BIT(num, n) ((num) &= ~((1) << (n)))
21 : :
22 : : /* Left shift multi-word mask by 1 bit.
23 : : *
24 : : * For example, given a mask of two uint8_t words
25 : : * Input: [00110101] [00110111]
26 : : * Output: [01101010] [01101110]
27 : : */
28 : : static void
29 : : lshift_mask(uint8_t *mask, int nwords)
30 : : {
31 : : int i;
32 : : int word_sz;
33 : :
34 : : word_sz = sizeof(uint8_t) * BYTE_LEN;
35 [ # # # # : 0 : for (i = nwords - 1; i >= 0; i--) {
# # ]
36 : 0 : mask[i] = mask[i] << 1;
37 [ # # # # : 0 : if (i != 0)
# # ]
38 : 0 : mask[i] = mask[i] | (mask[i - 1] >> (word_sz - 1));
39 : : }
40 : : }
41 : :
42 : : /* Get the index of the first unused slot in a multi-word mask (base_mask). Unused slots only after
43 : : * the start_pos are considered. An unused slot is a sequence of slot_sz continuous unset bits in
44 : : * the multi-word mask. For example given a multi-word mask,
45 : : *
46 : : * The program creates a search_mask with slot_sz bits set. Uses a sliding windows approach to scan
47 : : * the mask to identify the available first slot. search_mask slides left from start_pos to end.
48 : : *
49 : : * [10111000] [01001001]
50 : : * - WORD 1 --- WORD 0 -
51 : : *
52 : : * When start = 0,
53 : : * Index of the first unused slot of size 4 is 7.
54 : : * Index of the first unused slot of size 3 is 7.
55 : : * Index of the first unused slot of size 2 is 1.
56 : : * Index of the first unused slot of size 1 is 1.
57 : : *
58 : : * When start = 2,
59 : : * Index of the first unused slot of size 4 is 7.
60 : : * Index of the first unused slot of size 2 is 4.
61 : : * Index of the first unused slot of size 1 is 2.
62 : : *
63 : : * When unable to find a valid slot, return 0
64 : : * When slot_sz is zero, return max_idx + 1
65 : : */
66 : : static int
67 : 0 : slot_index_lowest(uint8_t *base_mask, int nwords, int slot_sz, int start_pos)
68 : : {
69 : : uint8_t *search_mask;
70 : : int word_sz;
71 : : int end_pos;
72 : : int min_idx;
73 : : int max_idx;
74 : : bool match;
75 : : int i, j;
76 : : int idx;
77 : :
78 : : word_sz = sizeof(uint8_t) * BYTE_LEN;
79 : : min_idx = 0;
80 : 0 : max_idx = word_sz * nwords;
81 : : idx = min_idx - 1;
82 : :
83 [ # # ]: 0 : if (slot_sz == 0)
84 : : return max_idx;
85 : :
86 : : /* Create a mask with slot_sz bits set */
87 : 0 : search_mask = plt_zmalloc(nwords * sizeof(uint8_t), 0);
88 [ # # ]: 0 : if (search_mask == NULL)
89 : 0 : goto error;
90 : :
91 [ # # ]: 0 : for (i = 0; i < nwords; i++) {
92 [ # # ]: 0 : if (i < slot_sz / word_sz)
93 : 0 : search_mask[i] = 0xFF;
94 [ # # ]: 0 : else if (i > slot_sz / word_sz)
95 : 0 : search_mask[i] = 0x00;
96 : : else
97 : 0 : search_mask[i] = (1 << (slot_sz % word_sz)) - 1;
98 : : }
99 : :
100 : : /* Shift search mask by start_pos bits */
101 [ # # ]: 0 : for (i = 0; i < start_pos; i++)
102 : : lshift_mask(search_mask, nwords);
103 : :
104 : : /* Scan for a slot, left shift search mask after every iteration */
105 : 0 : end_pos = nwords * word_sz - slot_sz + 1;
106 [ # # ]: 0 : for (j = start_pos; j < end_pos; j++) {
107 : : match = true;
108 [ # # ]: 0 : for (i = 0; i < nwords; i++)
109 [ # # # # ]: 0 : match = match && (((~base_mask[i]) & search_mask[i]) == search_mask[i]);
110 : :
111 [ # # ]: 0 : if (match) {
112 : : idx = j;
113 : 0 : goto found;
114 : : }
115 : :
116 : : lshift_mask(search_mask, nwords);
117 : : }
118 : :
119 : 0 : found:
120 : 0 : plt_free(search_mask);
121 : :
122 : : error:
123 : : return idx;
124 : : }
125 : :
126 : : /* Find the largest possible unused slot, with a minimum size of search_sz in a multi-work mask. The
127 : : * function returns the start index of the slot and the size of the identified slot (slot_sz).
128 : : *
129 : : * For example, in multi-word mask
130 : : *
131 : : * [10111000] [01001001]
132 : : * - WORD 1 --- WORD 0 -
133 : : *
134 : : * When search_sz > 4, return value = -1, slot_sz = 0
135 : : * When search_sz <=4, return value = 7, slot_sz = 4
136 : : */
137 : : static int
138 : 0 : slot_index_largest(uint8_t *base_mask, int nwords, int search_sz, int *slot_sz)
139 : : {
140 : : uint8_t *search_mask;
141 : : int mask_sz;
142 : : int word_sz;
143 : : int end_pos;
144 : : bool match;
145 : : int i, j;
146 : : int idx;
147 : :
148 : : word_sz = sizeof(uint8_t) * BYTE_LEN;
149 : 0 : mask_sz = nwords * word_sz;
150 : : idx = -1;
151 : :
152 : : /* Create a mask with mask_sz bits set */
153 : 0 : search_mask = plt_zmalloc(mask_sz, 0);
154 [ # # ]: 0 : if (search_mask == NULL)
155 : 0 : goto error;
156 : :
157 : 0 : start:
158 [ # # ]: 0 : for (i = 0; i < nwords; i++) {
159 [ # # ]: 0 : if (i < mask_sz / word_sz)
160 : 0 : search_mask[i] = 0xFF;
161 [ # # ]: 0 : else if (i > mask_sz / word_sz)
162 : 0 : search_mask[i] = 0x00;
163 : : else
164 : 0 : search_mask[i] = (1 << (mask_sz % word_sz)) - 1;
165 : : }
166 : :
167 : : /* Scan for a slot, left shift search mask after every iteration */
168 : 0 : end_pos = nwords * word_sz - mask_sz + 1;
169 [ # # ]: 0 : for (j = 0; j < end_pos; j++) {
170 : : match = true;
171 [ # # ]: 0 : for (i = 0; i < nwords; i++)
172 [ # # # # ]: 0 : match = match && (((~base_mask[i]) & search_mask[i]) == search_mask[i]);
173 : :
174 [ # # ]: 0 : if (match) {
175 : : idx = j;
176 : 0 : goto found;
177 : : }
178 : : lshift_mask(search_mask, nwords);
179 : : }
180 : :
181 : 0 : mask_sz--;
182 [ # # ]: 0 : if (mask_sz >= search_sz)
183 : 0 : goto start;
184 : : else
185 : : mask_sz = 0;
186 : :
187 : 0 : found:
188 : 0 : plt_free(search_mask);
189 [ # # ]: 0 : if (search_sz == 0)
190 : : idx = word_sz * nwords;
191 : :
192 : 0 : error:
193 [ # # ]: 0 : if (slot_sz)
194 : 0 : *slot_sz = mask_sz;
195 : :
196 : 0 : return idx;
197 : : }
198 : :
199 : : /* Count number of bits in a tilemask. Assumes that all set bits are contiguous. */
200 : : int
201 : 0 : cn10k_ml_ocm_tilecount(uint64_t tilemask, int *start, int *end)
202 : : {
203 : : uint8_t count;
204 : :
205 : : PLT_ASSERT(tilemask != 0);
206 : :
207 : 0 : *start = rte_ctz64(tilemask);
208 : 0 : *end = 64 - rte_clz64(tilemask) - 1;
209 : 0 : count = *end - *start + 1;
210 : :
211 : : PLT_ASSERT(count == rte_popcount64(tilemask));
212 : 0 : return count;
213 : : }
214 : :
215 : : /* Find the tiles and wb_page_start to load the model on given 'num_tiles' tiles with the specified
216 : : * scratch & WB pages and OCM allocation mode.
217 : : */
218 : : int
219 : 0 : cn10k_ml_ocm_tilemask_find(struct cnxk_ml_dev *cnxk_mldev, uint8_t num_tiles, uint16_t wb_pages,
220 : : uint16_t scratch_pages, uint64_t *tilemask)
221 : : {
222 : : struct cn10k_ml_dev *cn10k_mldev;
223 : : struct cn10k_ml_ocm *ocm;
224 : :
225 : : uint16_t used_scratch_pages_max;
226 : : uint16_t scratch_page_start;
227 : : int used_last_wb_page_max;
228 : : uint16_t scratch_page_end;
229 : : uint8_t search_end_tile;
230 : : uint8_t *local_ocm_mask;
231 : : int wb_page_start_curr;
232 : : int max_slot_sz_curr;
233 : : uint8_t tile_start;
234 : : int wb_page_start;
235 : : uint16_t tile_id;
236 : : uint16_t word_id;
237 : : uint8_t tile_idx;
238 : : int max_slot_sz;
239 : : int page_id;
240 : :
241 : : cn10k_mldev = &cnxk_mldev->cn10k_mldev;
242 : : ocm = &cn10k_mldev->ocm;
243 : :
244 [ # # ]: 0 : if (num_tiles > ML_CN10K_OCM_NUMTILES) {
245 : 0 : plt_err("Invalid num_tiles = %u (> %u)", num_tiles, ML_CN10K_OCM_NUMTILES);
246 : 0 : return -1;
247 : : }
248 : :
249 : : memset(tilemask, 0, sizeof(uint64_t));
250 : : wb_page_start = -1;
251 : : used_scratch_pages_max = 0;
252 : : used_last_wb_page_max = -1;
253 : 0 : max_slot_sz_curr = 0;
254 : : max_slot_sz = 0;
255 : : tile_idx = 0;
256 : : tile_start = 0;
257 : 0 : search_end_tile = ocm->num_tiles - num_tiles;
258 : :
259 : : /* Allocate for local ocm mask */
260 : 0 : local_ocm_mask = rte_zmalloc("local_ocm_mask", ocm->mask_words, RTE_CACHE_LINE_SIZE);
261 [ # # ]: 0 : if (local_ocm_mask == NULL) {
262 : 0 : plt_err("Unable to allocate memory for local_ocm_mask");
263 : 0 : return -1;
264 : : }
265 : :
266 : 0 : start_search:
267 : : used_scratch_pages_max = 0;
268 : : used_last_wb_page_max = -1;
269 [ # # ]: 0 : for (tile_id = tile_start; tile_id < tile_start + num_tiles; tile_id++) {
270 : : used_scratch_pages_max =
271 : 0 : PLT_MAX(ocm->tile_ocm_info[tile_id].scratch_pages, used_scratch_pages_max);
272 : : used_last_wb_page_max =
273 : 0 : PLT_MAX(ocm->tile_ocm_info[tile_id].last_wb_page, used_last_wb_page_max);
274 : : }
275 : :
276 : 0 : memset(local_ocm_mask, 0, ocm->mask_words);
277 [ # # ]: 0 : for (tile_id = tile_start; tile_id < tile_start + num_tiles; tile_id++) {
278 [ # # ]: 0 : for (word_id = 0; word_id < ocm->mask_words; word_id++)
279 : 0 : local_ocm_mask[word_id] |= ocm->tile_ocm_info[tile_id].ocm_mask[word_id];
280 : : }
281 : :
282 [ # # ]: 0 : if (used_scratch_pages_max < scratch_pages) { /* Check for extra scratch pages */
283 [ # # ]: 0 : if (ocm->num_pages - used_last_wb_page_max - 1 >=
284 : : scratch_pages) { /* Pages available */
285 : 0 : scratch_page_start = ocm->num_pages - scratch_pages;
286 : 0 : scratch_page_end = ocm->num_pages - 1;
287 [ # # ]: 0 : for (page_id = scratch_page_start; page_id <= scratch_page_end;
288 : 0 : page_id++) { /* Mark the extra scratch pages as used */
289 : 0 : local_ocm_mask[page_id / OCM_MAP_WORD_SIZE] =
290 : 0 : SET_BIT(local_ocm_mask[page_id / OCM_MAP_WORD_SIZE],
291 : : page_id % OCM_MAP_WORD_SIZE);
292 : : }
293 : : } else { /* Pages not available, check for next set of tiles */
294 : 0 : goto next_search;
295 : : }
296 : : }
297 : :
298 [ # # ]: 0 : if (strcmp(ocm->alloc_mode, "lowest") == 0) {
299 : 0 : wb_page_start = slot_index_lowest(local_ocm_mask, ocm->mask_words, wb_pages, 0);
300 [ # # ]: 0 : if (wb_page_start != -1) { /* Have a valid slot for WB, else next set of tiles */
301 : : tile_idx = tile_start;
302 : 0 : goto found;
303 : : }
304 [ # # ]: 0 : } else if (strcmp(ocm->alloc_mode, "largest") == 0) {
305 : 0 : wb_page_start_curr = slot_index_largest(local_ocm_mask, ocm->mask_words, wb_pages,
306 : : &max_slot_sz_curr);
307 [ # # ]: 0 : if (max_slot_sz_curr > max_slot_sz) {
308 : : wb_page_start = wb_page_start_curr;
309 : : max_slot_sz = max_slot_sz_curr;
310 : : tile_idx = tile_start;
311 [ # # ]: 0 : } else if (max_slot_sz_curr == max_slot_sz) {
312 : : wb_page_start = wb_page_start_curr;
313 [ # # ]: 0 : if (wb_page_start == ocm->num_pages) {
314 : : tile_idx = tile_start;
315 : 0 : goto found;
316 : : }
317 : : }
318 : : }
319 : :
320 : 0 : next_search:
321 : 0 : tile_start = tile_start + num_tiles;
322 [ # # ]: 0 : if (tile_start <= search_end_tile)
323 : 0 : goto start_search;
324 : :
325 : 0 : found:
326 [ # # ]: 0 : if (wb_page_start != -1)
327 : 0 : *tilemask = GENMASK_ULL(tile_idx + num_tiles - 1, tile_idx);
328 : :
329 : 0 : rte_free(local_ocm_mask);
330 : :
331 : 0 : return wb_page_start;
332 : : }
333 : :
334 : : void
335 : 0 : cn10k_ml_ocm_reserve_pages(struct cnxk_ml_dev *cnxk_mldev, uint16_t model_id, uint16_t layer_id,
336 : : uint64_t tilemask, int wb_page_start, uint16_t wb_pages,
337 : : uint16_t scratch_pages)
338 : : {
339 : : struct cnxk_ml_model *model;
340 : : struct cnxk_ml_layer *layer;
341 : : struct cn10k_ml_ocm *ocm;
342 : :
343 : : int scratch_page_start;
344 : : int scratch_page_end;
345 : : int wb_page_end;
346 : : int tile_start;
347 : : int tile_end;
348 : : int tile_id;
349 : : int page_id;
350 : :
351 : : ocm = &cnxk_mldev->cn10k_mldev.ocm;
352 : 0 : model = cnxk_mldev->mldev->data->models[model_id];
353 : 0 : layer = &model->layer[layer_id];
354 : :
355 : : /* Get first set bit, tile_start */
356 : 0 : tile_start = 0;
357 : 0 : tile_end = 0;
358 : 0 : cn10k_ml_ocm_tilecount(tilemask, &tile_start, &tile_end);
359 : 0 : wb_page_end = wb_page_start + wb_pages - 1;
360 : 0 : scratch_page_start = ocm->num_pages - scratch_pages;
361 : 0 : scratch_page_end = ocm->num_pages - 1;
362 : :
363 : : /* Update tile_ocm_info */
364 [ # # ]: 0 : for (tile_id = tile_start; tile_id <= tile_end; tile_id++) {
365 : : /* Scratch pages */
366 [ # # ]: 0 : for (page_id = scratch_page_start; page_id <= scratch_page_end; page_id++)
367 : 0 : ocm->tile_ocm_info[tile_id].ocm_mask[page_id / OCM_MAP_WORD_SIZE] = SET_BIT(
368 : : ocm->tile_ocm_info[tile_id].ocm_mask[page_id / OCM_MAP_WORD_SIZE],
369 : : page_id % OCM_MAP_WORD_SIZE);
370 : 0 : ocm->tile_ocm_info[tile_id].scratch_pages =
371 : 0 : PLT_MAX(ocm->tile_ocm_info[tile_id].scratch_pages, scratch_pages);
372 : :
373 : : /* WB pages */
374 [ # # ]: 0 : for (page_id = wb_page_start; page_id <= wb_page_end; page_id++)
375 : 0 : ocm->tile_ocm_info[tile_id].ocm_mask[page_id / OCM_MAP_WORD_SIZE] = SET_BIT(
376 : : ocm->tile_ocm_info[tile_id].ocm_mask[page_id / OCM_MAP_WORD_SIZE],
377 : : page_id % OCM_MAP_WORD_SIZE);
378 [ # # ]: 0 : if (wb_pages != 0)
379 : 0 : ocm->tile_ocm_info[tile_id].last_wb_page =
380 : 0 : PLT_MAX(ocm->tile_ocm_info[tile_id].last_wb_page, wb_page_end);
381 : : }
382 : :
383 : 0 : layer->glow.addr.tile_start = tile_start;
384 : 0 : layer->glow.addr.tile_end = tile_end;
385 : :
386 : 0 : plt_ml_dbg("model_id = %u, tilemask = 0x%016lx", model_id, tilemask);
387 : 0 : plt_ml_dbg("model_id = %u, wb_page_start = %d, wb_page_end = %d", model_id, wb_page_start,
388 : : wb_page_end);
389 : 0 : plt_ml_dbg("model_id = %u, scratch_page_start = %d, scratch_page_end = %d", model_id,
390 : : scratch_page_start, scratch_page_end);
391 : 0 : }
392 : :
393 : : void
394 : 0 : cn10k_ml_ocm_free_pages(struct cnxk_ml_dev *cnxk_mldev, uint16_t model_id, uint16_t layer_id)
395 : : {
396 : : struct cnxk_ml_model *local_model;
397 : : struct cnxk_ml_layer *local_layer;
398 : : struct cnxk_ml_model *model;
399 : : struct cnxk_ml_layer *layer;
400 : : struct cn10k_ml_ocm *ocm;
401 : :
402 : : int scratch_resize_pages;
403 : : int wb_page_start;
404 : : int wb_page_end;
405 : : int prev_start;
406 : : int curr_start;
407 : : int tile_id;
408 : : int page_id;
409 : : uint16_t i;
410 : : uint16_t j;
411 : :
412 : : ocm = &cnxk_mldev->cn10k_mldev.ocm;
413 : 0 : model = cnxk_mldev->mldev->data->models[model_id];
414 : 0 : layer = &model->layer[layer_id];
415 : :
416 : : /* Update OCM info for WB memory */
417 : 0 : wb_page_start = layer->glow.ocm_map.wb_page_start;
418 : 0 : wb_page_end = wb_page_start + layer->glow.ocm_map.wb_pages - 1;
419 [ # # ]: 0 : for (tile_id = layer->glow.addr.tile_start; tile_id <= layer->glow.addr.tile_end;
420 : 0 : tile_id++) {
421 [ # # ]: 0 : for (page_id = wb_page_start; page_id <= wb_page_end; page_id++) {
422 : 0 : CLEAR_BIT(ocm->tile_ocm_info[tile_id].ocm_mask[page_id / OCM_MAP_WORD_SIZE],
423 : : page_id % OCM_MAP_WORD_SIZE);
424 : : }
425 : :
426 : : /* Update last_wb_page size */
427 [ # # ]: 0 : if (wb_page_end == ocm->tile_ocm_info[tile_id].last_wb_page)
428 : 0 : ocm->tile_ocm_info[tile_id].last_wb_page = wb_page_start - 1;
429 : :
430 : : /* Get max scratch pages required, excluding the current model */
431 : : scratch_resize_pages = 0;
432 [ # # ]: 0 : for (i = 0; i < cnxk_mldev->mldev->data->nb_models; i++) {
433 : 0 : local_model = cnxk_mldev->mldev->data->models[i];
434 [ # # ]: 0 : if (local_model == NULL)
435 : 0 : continue;
436 : :
437 [ # # ]: 0 : for (j = 0; j < local_model->nb_layers; j++) {
438 : 0 : local_layer = &local_model->layer[j];
439 [ # # ]: 0 : if (local_layer->type != ML_CNXK_LAYER_TYPE_MRVL)
440 : 0 : continue;
441 : :
442 [ # # ]: 0 : if (local_layer != layer &&
443 [ # # ]: 0 : local_layer->glow.ocm_map.ocm_reserved) {
444 [ # # ]: 0 : if (IS_BIT_SET(local_layer->glow.ocm_map.tilemask, tile_id))
445 : : scratch_resize_pages =
446 : 0 : PLT_MAX((int)local_layer->glow.ocm_map
447 : : .scratch_pages,
448 : : scratch_resize_pages);
449 : : }
450 : : }
451 : : }
452 : :
453 : : /* Clear extra scratch pages */
454 [ # # ]: 0 : if (scratch_resize_pages < ocm->tile_ocm_info[tile_id].scratch_pages) {
455 : 0 : prev_start = ocm->num_pages - ocm->tile_ocm_info[tile_id].scratch_pages;
456 : 0 : curr_start = ocm->num_pages - scratch_resize_pages;
457 [ # # ]: 0 : for (page_id = prev_start; page_id < curr_start; page_id++) {
458 : 0 : CLEAR_BIT(ocm->tile_ocm_info[tile_id]
459 : : .ocm_mask[page_id / OCM_MAP_WORD_SIZE],
460 : : page_id % OCM_MAP_WORD_SIZE);
461 : : }
462 : 0 : ocm->tile_ocm_info[tile_id].scratch_pages = scratch_resize_pages;
463 : : }
464 : : }
465 : 0 : }
466 : :
467 : : static void
468 : 0 : cn10k_ml_ocm_pagemask_to_str(struct cn10k_ml_ocm_tile_info *tile_info, uint16_t nwords, char *str)
469 : : {
470 : : char *p = str;
471 : : int word;
472 : :
473 : : /* Add prefix 0x */
474 : 0 : *p++ = '0';
475 : 0 : *p++ = 'x';
476 : :
477 : : /* Build hex string */
478 [ # # ]: 0 : for (word = nwords - 1; word >= 0; word--) {
479 : 0 : sprintf(p, "%02X", tile_info->ocm_mask[word]);
480 : 0 : p += 2;
481 : : }
482 : :
483 : : /* Terminate */
484 : 0 : *p++ = 0;
485 : 0 : }
486 : :
487 : : void
488 : 0 : cn10k_ml_ocm_print(struct cnxk_ml_dev *cnxk_mldev, FILE *fp)
489 : : {
490 : : struct cn10k_ml_ocm *ocm;
491 : : uint8_t tile_id;
492 : : uint8_t word_id;
493 : : int wb_pages;
494 : : char *str;
495 : :
496 : : ocm = &cnxk_mldev->cn10k_mldev.ocm;
497 : :
498 : : /* Nibbles + prefix '0x' */
499 : 0 : str = rte_zmalloc("ocm_mask_str", ocm->num_pages / 4 + 2, RTE_CACHE_LINE_SIZE);
500 [ # # ]: 0 : if (str == NULL) {
501 : 0 : plt_err("Unable to allocate memory for ocm_mask_str");
502 : 0 : return;
503 : : }
504 : :
505 : : fprintf(fp, "OCM State:\n");
506 [ # # ]: 0 : for (tile_id = 0; tile_id < ocm->num_tiles; tile_id++) {
507 : 0 : cn10k_ml_ocm_pagemask_to_str(&ocm->tile_ocm_info[tile_id], ocm->mask_words, str);
508 : :
509 : 0 : wb_pages = 0 - ocm->tile_ocm_info[tile_id].scratch_pages;
510 [ # # ]: 0 : for (word_id = 0; word_id < ocm->mask_words; word_id++)
511 : 0 : wb_pages += rte_popcount32(ocm->tile_ocm_info[tile_id].ocm_mask[word_id]);
512 : :
513 : 0 : fprintf(fp,
514 : : "tile = %2u, scratch_pages = %4u,"
515 : : " wb_pages = %4d, last_wb_page = %4d,"
516 : : " pagemask = %s\n",
517 : : tile_id, ocm->tile_ocm_info[tile_id].scratch_pages, wb_pages,
518 : : ocm->tile_ocm_info[tile_id].last_wb_page, str);
519 : : }
520 : :
521 : 0 : rte_free(str);
522 : : }
|