| 182 | } |
| 183 | |
| 184 | static void |
| 185 | rte_dpaa2_mbuf_release(struct rte_mempool *pool __rte_unused, |
| 186 | void * const *obj_table, |
| 187 | uint32_t bpid, |
| 188 | uint32_t meta_data_size, |
| 189 | int count) |
| 190 | { |
| 191 | struct qbman_release_desc releasedesc; |
| 192 | struct qbman_swp *swp; |
| 193 | int ret; |
| 194 | int i, n, retry_count; |
| 195 | uint64_t bufs[DPAA2_MBUF_MAX_ACQ_REL]; |
| 196 | |
| 197 | if (unlikely(!DPAA2_PER_LCORE_DPIO)) { |
| 198 | ret = dpaa2_affine_qbman_swp(); |
| 199 | if (ret != 0) { |
| 200 | DPAA2_MEMPOOL_ERR( |
| 201 | "Failed to allocate IO portal, tid: %d", |
| 202 | rte_gettid()); |
| 203 | return; |
| 204 | } |
| 205 | } |
| 206 | swp = DPAA2_PER_LCORE_PORTAL; |
| 207 | |
| 208 | /* Create a release descriptor required for releasing |
| 209 | * buffers into QBMAN |
| 210 | */ |
| 211 | qbman_release_desc_clear(&releasedesc); |
| 212 | qbman_release_desc_set_bpid(&releasedesc, bpid); |
| 213 | |
| 214 | n = count % DPAA2_MBUF_MAX_ACQ_REL; |
| 215 | if (unlikely(!n)) |
| 216 | goto aligned; |
| 217 | |
| 218 | /* convert mbuf to buffers for the remainder */ |
| 219 | for (i = 0; i < n ; i++) { |
| 220 | #ifdef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA |
| 221 | bufs[i] = (uint64_t)rte_mempool_virt2iova(obj_table[i]) |
| 222 | + meta_data_size; |
| 223 | #else |
| 224 | bufs[i] = (uint64_t)obj_table[i] + meta_data_size; |
| 225 | #endif |
| 226 | } |
| 227 | |
| 228 | /* feed them to bman */ |
| 229 | retry_count = 0; |
| 230 | while ((ret = qbman_swp_release(swp, &releasedesc, bufs, n)) == |
| 231 | -EBUSY) { |
| 232 | retry_count++; |
| 233 | if (retry_count > DPAA2_MAX_TX_RETRY_COUNT) { |
| 234 | DPAA2_MEMPOOL_ERR("bman release retry exceeded, low fbpr?"); |
| 235 | return; |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | aligned: |
| 240 | /* if there are more buffers to free */ |
| 241 | while (n < count) { |
no test coverage detected