| 70 | } |
| 71 | |
| 72 | void |
| 73 | pdcp_cnt_report_fill(struct pdcp_cnt_bitmap bitmap, struct entity_state state, |
| 74 | uint8_t *data, uint16_t data_len) |
| 75 | { |
| 76 | uint64_t slab = 0, next_slab = 0, leftover; |
| 77 | uint32_t zeros, report_len, diff; |
| 78 | uint32_t slab_id, next_slab_id; |
| 79 | uint32_t pos = 0, next_pos = 0; |
| 80 | |
| 81 | const uint32_t start_count = state.rx_deliv + 1; |
| 82 | const uint32_t nb_slabs = bitmap.size / RTE_BITMAP_SLAB_BIT_SIZE; |
| 83 | const uint32_t nb_data_slabs = data_len / SLAB_BYTE_SIZE; |
| 84 | const uint32_t start_slab_id = start_count / RTE_BITMAP_SLAB_BIT_SIZE; |
| 85 | const uint32_t stop_slab_id = (start_slab_id + nb_data_slabs) % nb_slabs; |
| 86 | const uint32_t shift = start_count % RTE_BITMAP_SLAB_BIT_SIZE; |
| 87 | const uint32_t leftover_shift = shift ? RTE_BITMAP_SLAB_BIT_SIZE - shift : 0; |
| 88 | const uint8_t *data_end = RTE_PTR_ADD(data, data_len + SLAB_BYTE_SIZE); |
| 89 | |
| 90 | /* NOTE: Mask required to workaround case - when shift is not needed */ |
| 91 | const uint64_t leftover_mask = shift ? ~0 : 0; |
| 92 | |
| 93 | /* NOTE: implement scan init at to set custom position */ |
| 94 | __rte_bitmap_scan_init(bitmap.bmp); |
| 95 | while (true) { |
| 96 | assert(rte_bitmap_scan(bitmap.bmp, &pos, &slab) == 1); |
| 97 | slab_id = pos / RTE_BITMAP_SLAB_BIT_SIZE; |
| 98 | if (slab_id >= start_slab_id) |
| 99 | break; |
| 100 | } |
| 101 | |
| 102 | report_len = nb_data_slabs; |
| 103 | |
| 104 | if (slab_id > start_slab_id) { |
| 105 | /* Zero slabs at beginning */ |
| 106 | zeros = (slab_id - start_slab_id - 1) * SLAB_BYTE_SIZE; |
| 107 | memset(data, 0, zeros); |
| 108 | data = RTE_PTR_ADD(data, zeros); |
| 109 | leftover = leftover_get(slab, leftover_shift, leftover_mask); |
| 110 | memcpy(data, &leftover, SLAB_BYTE_SIZE); |
| 111 | data = RTE_PTR_ADD(data, SLAB_BYTE_SIZE); |
| 112 | report_len -= (slab_id - start_slab_id); |
| 113 | } |
| 114 | |
| 115 | while (report_len) { |
| 116 | rte_bitmap_scan(bitmap.bmp, &next_pos, &next_slab); |
| 117 | next_slab_id = next_pos / RTE_BITMAP_SLAB_BIT_SIZE; |
| 118 | diff = (next_slab_id + nb_slabs - slab_id) % nb_slabs; |
| 119 | |
| 120 | /* If next_slab_id == slab_id - overlap */ |
| 121 | diff += !(next_slab_id ^ slab_id) * nb_slabs; |
| 122 | |
| 123 | /* Size check - next slab is outsize of size range */ |
| 124 | if (diff > report_len) { |
| 125 | next_slab = 0; |
| 126 | next_slab_id = stop_slab_id; |
| 127 | diff = report_len; |
| 128 | } |
| 129 |
no test coverage detected