| 377 | #define OPT_FENCE(idx) ((fence && idx == 8) ? RTE_DMA_OP_FLAG_FENCE : 0) |
| 378 | |
| 379 | static int |
| 380 | test_failure_in_full_burst(int16_t dev_id, uint16_t vchan, bool fence, |
| 381 | struct rte_mbuf **srcs, struct rte_mbuf **dsts, unsigned int fail_idx) |
| 382 | { |
| 383 | /* Test single full batch statuses with failures */ |
| 384 | enum rte_dma_status_code status[COMP_BURST_SZ]; |
| 385 | struct rte_dma_stats baseline, stats; |
| 386 | uint16_t invalid_addr_id = 0; |
| 387 | uint16_t idx; |
| 388 | uint16_t count, status_count; |
| 389 | unsigned int i; |
| 390 | bool error = false; |
| 391 | int err_count = 0; |
| 392 | |
| 393 | rte_dma_stats_get(dev_id, vchan, &baseline); /* get a baseline set of stats */ |
| 394 | for (i = 0; i < COMP_BURST_SZ; i++) { |
| 395 | int id = rte_dma_copy(dev_id, vchan, |
| 396 | (i == fail_idx ? 0 : rte_mbuf_data_iova(srcs[i])), |
| 397 | rte_mbuf_data_iova(dsts[i]), COPY_LEN, OPT_FENCE(i)); |
| 398 | if (id < 0) |
| 399 | ERR_RETURN("Error with rte_dma_copy for buffer %u\n", i); |
| 400 | if (i == fail_idx) |
| 401 | invalid_addr_id = id; |
| 402 | } |
| 403 | rte_dma_submit(dev_id, vchan); |
| 404 | rte_dma_stats_get(dev_id, vchan, &stats); |
| 405 | if (stats.submitted != baseline.submitted + COMP_BURST_SZ) |
| 406 | ERR_RETURN("Submitted stats value not as expected, %"PRIu64" not %"PRIu64"\n", |
| 407 | stats.submitted, baseline.submitted + COMP_BURST_SZ); |
| 408 | |
| 409 | await_hw(dev_id, vchan); |
| 410 | |
| 411 | count = rte_dma_completed(dev_id, vchan, COMP_BURST_SZ, &idx, &error); |
| 412 | if (count != fail_idx) |
| 413 | ERR_RETURN("Error with rte_dma_completed for failure test. Got returned %u not %u.\n", |
| 414 | count, fail_idx); |
| 415 | if (!error) |
| 416 | ERR_RETURN("Error, missing expected failed copy, %u. has_error is not set\n", |
| 417 | fail_idx); |
| 418 | if (idx != invalid_addr_id - 1) |
| 419 | ERR_RETURN("Error, missing expected failed copy, %u. Got last idx %u, not %u\n", |
| 420 | fail_idx, idx, invalid_addr_id - 1); |
| 421 | |
| 422 | /* all checks ok, now verify calling completed() again always returns 0 */ |
| 423 | for (i = 0; i < 10; i++) |
| 424 | if (rte_dma_completed(dev_id, vchan, COMP_BURST_SZ, &idx, &error) != 0 |
| 425 | || error == false || idx != (invalid_addr_id - 1)) |
| 426 | ERR_RETURN("Error with follow-up completed calls for fail idx %u\n", |
| 427 | fail_idx); |
| 428 | |
| 429 | status_count = rte_dma_completed_status(dev_id, vchan, COMP_BURST_SZ, |
| 430 | &idx, status); |
| 431 | /* some HW may stop on error and be restarted after getting error status for single value |
| 432 | * To handle this case, if we get just one error back, wait for more completions and get |
| 433 | * status for rest of the burst |
| 434 | */ |
| 435 | if (status_count == 1) { |
| 436 | await_hw(dev_id, vchan); |
no test coverage detected