Data Accelerator Offload
Loading...
Searching...
No Matches
dao_dma.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: Marvell-MIT
2 * Copyright (c) 2023 Marvell.
3 */
4
11#ifndef __INCLUDE_DAO_DMA_H__
12#define __INCLUDE_DAO_DMA_H__
13
14#include <rte_eal.h>
15
16#include <rte_dmadev.h>
17#include <rte_lcore.h>
18#include <rte_mempool.h>
19#include <rte_prefetch.h>
20#include <rte_vect.h>
21
22#include <dao_config.h>
23
24#include "dao_log.h"
25
27#define DAO_DMA_MAX_POINTER 15u
28
30#define DAO_DMA_MAX_META_POINTER 48
31
33#define DAO_DMA_MAX_VCHAN_PER_LCORE 64
34
36#define DAO_DMA_MAX_INFLIGHT_MDATA 4096
37
39#define DAO_DMA_DOORBELL_THRESHOLD 1024
40
54
58 uint16_t tail;
60 uint16_t head;
62 int16_t devid;
64 uint8_t vchan;
65 uint8_t rsvd;
67 uint16_t src_i;
69 uint16_t dst_i;
71 uint8_t flush_thr;
73 uint8_t auto_free : 1;
74 uint8_t rsvd2 : 7;
76 uint16_t pend_ops;
78 struct rte_dma_sge src[DAO_DMA_MAX_POINTER];
80 struct rte_dma_sge dst[DAO_DMA_MAX_POINTER];
82 uint64_t ptrs;
84 uint64_t ops;
86 uint64_t dbells;
88 uint64_t dma_enq_errs;
92 void *ops_mem;
94 struct rte_dma_op **dma_ops;
96 uint16_t ops_head;
98 uint16_t ops_tail;
100 uint16_t ops_mask;
104
116
120 uint64_t ptrs;
122 uint64_t ops;
124 uint64_t dbells;
126 uint64_t enq_errs;
127};
128
140
143
151
159
167
178int dao_dma_stats_get(uint16_t lcore_id, struct dao_dma_stats *stats);
179
192int dao_dma_lcore_dev2mem_set(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr);
193
208int dao_dma_lcore_dev2mem_set_ops(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr,
209 uint16_t nb_ops);
210
223int dao_dma_lcore_mem2dev_set(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr);
224
239int dao_dma_lcore_mem2dev_set_ops(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr,
240 uint16_t nb_ops);
241
254int dao_dma_lcore_mem2dev_autofree_set(int16_t dma_devid, uint16_t vchan, bool enable);
255
266int dao_dma_ctrl_dev_set(int16_t dev2mem_id, int16_t mem2dev_id);
267
275
283
290void dao_dma_compl_wait_inflight(uint16_t vchan);
291
298static __rte_always_inline int
300{
301#if DAO_DMA_STATS
302 return 1;
303#else
304 return 0;
305#endif
306}
307
316static __rte_always_inline uint16_t
318{
319 return rte_dma_burst_capacity(vchan->devid, vchan->vchan);
320}
321
334static __rte_always_inline bool
335dao_dma_desc_avail_get(struct dao_dma_vchan_state *vchan, uint32_t nb_src, uint32_t nb_dst)
336{
337 int src_avail = vchan->flush_thr - vchan->src_i;
338 int dst_avail = vchan->flush_thr - vchan->dst_i;
339 uint16_t inflight = vchan->tail - vchan->head;
340 uint32_t n_src, n_dst, nb_desc;
341 uint8_t flush_thr;
342
343 if (likely((src_avail >= (int)nb_src || !vchan->src_i) &&
344 (dst_avail >= (int)nb_dst || !vchan->dst_i)))
345 return true;
346
347 flush_thr = vchan->flush_thr;
348 n_src = (nb_src + flush_thr - 1) / flush_thr;
349 n_dst = (nb_dst + flush_thr - 1) / flush_thr;
350 nb_desc = RTE_MAX(n_src, n_dst);
351
352 /* increment by 1 to consider current enqueued pointers
353 */
354 nb_desc++;
355 if (inflight + nb_desc > DAO_DMA_MAX_INFLIGHT_MDATA)
356 return false;
357
358 return dao_dma_burst_capacity(vchan) >= nb_desc;
359}
360
372static __rte_always_inline bool
373dao_dma_op_status(struct dao_dma_vchan_state *vchan, uint16_t op_idx)
374{
375 uint16_t head = vchan->head;
376 uint16_t tail = vchan->tail;
377
378 if (vchan->src_i && (tail == op_idx))
379 return false;
380
381 return head <= tail ? (op_idx < head || op_idx >= tail) : (op_idx < head && op_idx >= tail);
382}
383
394static __rte_always_inline bool
395dao_dma_flush(struct dao_dma_vchan_state *vchan, const uint8_t avail)
396{
397 int src_avail = vchan->flush_thr - vchan->src_i;
398 int dst_avail = vchan->flush_thr - vchan->dst_i;
399 uint64_t flags = (uint64_t)vchan->auto_free << 3;
400 int rc;
401
402 if (likely((src_avail >= (int)avail || !vchan->src_i) &&
403 (dst_avail >= (int)avail || !vchan->dst_i)))
404 goto exit;
405
407 flags |= RTE_DMA_OP_FLAG_SUBMIT;
408
409 rc = rte_dma_copy_sg(vchan->devid, vchan->vchan, vchan->src, vchan->dst, vchan->src_i,
410 vchan->dst_i, flags);
411 if (unlikely(rc < 0)) {
413 vchan->dma_enq_errs++;
414 return false;
415 }
416 vchan->tail++;
417 vchan->pend_ops++;
418
419 if (flags & RTE_DMA_OP_FLAG_SUBMIT)
420 vchan->pend_ops = 0;
421
423 vchan->ptrs += vchan->src_i;
424 vchan->ops++;
425 }
426 vchan->src_i = 0;
427 vchan->dst_i = 0;
428exit:
429 return true;
430}
431
440static __rte_always_inline uint16_t
442{
443 int src_avail = vchan->flush_thr - vchan->src_i;
444
445 return src_avail;
446}
447
456static __rte_always_inline uint16_t
458{
459 int dst_avail = vchan->flush_thr - vchan->dst_i;
460
461 return dst_avail;
462}
463
472static __rte_always_inline struct rte_dma_sge *
474{
475 return &vchan->src[vchan->src_i];
476}
477
486static __rte_always_inline struct rte_dma_sge *
488{
489 return &vchan->dst[vchan->dst_i];
490}
491
509static __rte_always_inline void
510dao_dma_enq_x1(struct dao_dma_vchan_state *vchan, rte_iova_t src, uint32_t src_len, rte_iova_t dst,
511 uint32_t dst_len)
512{
513 uint16_t src_i = vchan->src_i;
514 uint16_t dst_i = vchan->dst_i;
515
516 vchan->dst[dst_i].addr = dst;
517 vchan->dst[dst_i].length = dst_len;
518 vchan->src[src_i].addr = src;
519 vchan->src[src_i].length = src_len;
520
521 vchan->src_i = src_i + 1;
522 vchan->dst_i = dst_i + 1;
523}
524
538static __rte_always_inline void
539dao_dma_enq_dst_x1(struct dao_dma_vchan_state *vchan, rte_iova_t dst, uint32_t dst_len)
540{
541 uint16_t dst_i = vchan->dst_i;
542
543 vchan->dst[dst_i].addr = dst;
544 vchan->dst[dst_i].length = dst_len;
545
546 vchan->dst_i = dst_i + 1;
547}
548
562static __rte_always_inline void
563dao_dma_enq_src_x1(struct dao_dma_vchan_state *vchan, rte_iova_t src, uint32_t src_len)
564{
565 uint16_t src_i = vchan->src_i;
566
567 vchan->src[src_i].addr = src;
568 vchan->src[src_i].length = src_len;
569
570 vchan->src_i = src_i + 1;
571}
572
585static __rte_always_inline uint16_t
586dao_dma_enq_x4(struct dao_dma_vchan_state *vchan, uint64x2_t *vsrc, uint64x2_t *vdst)
587{
588 struct rte_dma_sge *src, *dst;
589 uint16_t src_i = vchan->src_i;
590 uint16_t dst_i = vchan->dst_i;
591 int src_avail = vchan->flush_thr - src_i;
592 int i;
593
594 src = vchan->src + src_i;
595 dst = vchan->dst + dst_i;
596 if (src_avail >= 4) {
597 vst1q_u64((uint64_t *)&src[0], vsrc[0]);
598 vst1q_u64((uint64_t *)&src[1], vsrc[1]);
599 vst1q_u64((uint64_t *)&src[2], vsrc[2]);
600 vst1q_u64((uint64_t *)&src[3], vsrc[3]);
601
602 vst1q_u64((uint64_t *)&dst[0], vdst[0]);
603 vst1q_u64((uint64_t *)&dst[1], vdst[1]);
604 vst1q_u64((uint64_t *)&dst[2], vdst[2]);
605 vst1q_u64((uint64_t *)&dst[3], vdst[3]);
606
607 vchan->src_i = src_i + 4;
608 vchan->dst_i = dst_i + 4;
609 return 4;
610 }
611
612 i = 0;
613 while (i < 4 && src_avail > 0) {
614 vst1q_u64((uint64_t *)src, vsrc[i]);
615 vst1q_u64((uint64_t *)dst, vdst[i]);
616 src++;
617 dst++;
618 i++;
619 src_avail--;
620 };
621 vchan->src_i = src_i + i;
622 vchan->dst_i = dst_i + i;
623
624 /* Flush enqueued pointers */
625 dao_dma_flush(vchan, 4);
626
627 src_i = vchan->src_i;
628 dst_i = vchan->dst_i;
629 src = vchan->src + src_i;
630 dst = vchan->dst + dst_i;
631 src_avail = vchan->flush_thr - src_i;
632
633 while (i < 4 && src_avail > 0) {
634 vst1q_u64((uint64_t *)src, vsrc[i]);
635 vst1q_u64((uint64_t *)dst, vdst[i]);
636 i++;
637 src++;
638 dst++;
639 src_avail--;
640 vchan->src_i++;
641 vchan->dst_i++;
642 };
643 return i;
644}
645
652static __rte_always_inline void
654{
655 uint16_t cmpl;
656 bool has_err = 0;
657
658 /* Fetch all DMA completed status */
659 cmpl = rte_dma_completed(vchan->devid, vchan->vchan, 128, NULL, &has_err);
660 if (unlikely(has_err)) {
661 vchan->dma_compl_errs++;
662 cmpl += 1;
663 }
664 vchan->head += cmpl;
665}
666
675static __rte_always_inline uint16_t
677{
678 return vchan->ops_head - vchan->ops_tail;
679}
680
691static __rte_always_inline struct rte_dma_op **
692dao_dma_ops_get(struct dao_dma_vchan_state *vchan, uint16_t n)
693{
694 uint16_t tail = vchan->ops_tail;
695
696 vchan->ops_tail = tail + n;
697 return &vchan->dma_ops[tail & vchan->ops_mask];
698}
699
708static __rte_always_inline void
709dao_dma_ops_put(struct dao_dma_vchan_state *vchan, uint16_t n)
710{
711 vchan->ops_head += n;
712}
713
722static __rte_always_inline void
723dao_dma_ops_release(struct dao_dma_vchan_state *vchan, uint16_t n)
724{
725 vchan->ops_tail -= n;
726}
727
736static __rte_always_inline void
737dao_dma_op_set_cmpl(struct rte_dma_op *op, uint16_t *ptr, uint16_t val, uint16_t *pend_ptr,
738 uint16_t pend_val)
739{
740 op->user_meta = (uint64_t)(uintptr_t)ptr;
741 op->event_meta = (uint64_t)(uintptr_t)pend_ptr;
742 op->rsvd = ((uint32_t)val << 16) | pend_val;
743}
744
754static __rte_always_inline void
755dao_dma_check_meta_compl(struct dao_dma_vchan_state *vchan, const int mem_order)
756{
757 uint32_t cmpl, i, j, idx = 0;
758 bool has_err = 0;
759
760 /* Fetch all DMA completed status */
761 cmpl = rte_dma_completed(vchan->devid, vchan->vchan, 128, NULL, &has_err);
762 if (unlikely(has_err)) {
763 vchan->dma_compl_errs++;
764 cmpl += 1;
765 }
766 for (i = vchan->head; i < vchan->head + cmpl; i++) {
768 for (j = 0; j < vchan->mdata[idx].cnt; j++) {
769 if (mem_order)
770 __atomic_store_n(vchan->mdata[idx].ptr[j], vchan->mdata[idx].val[j],
771 __ATOMIC_RELEASE);
772 else
773 *vchan->mdata[idx].ptr[j] = vchan->mdata[idx].val[j];
774 *vchan->mdata[idx].pend_ptr[j] -= vchan->mdata[idx].pend_val[j];
775 }
776 vchan->mdata[idx].cnt = 0;
777 }
778 vchan->head += cmpl;
779}
780
790static __rte_always_inline void
791dao_dma_check_meta_compl_ops(struct dao_dma_vchan_state *vchan, const int mem_order)
792{
793#define DEQ_SZ 128
794 uint32_t cmpl, i;
795 struct rte_dma_op *deq_ops[DEQ_SZ];
796
797 /* Skip costly dequeue call when no ops are inflight */
798 if (vchan->head == vchan->tail)
799 return;
800
801 cmpl = rte_dma_dequeue_ops(vchan->devid, vchan->vchan, deq_ops, DEQ_SZ);
802 if (!cmpl)
803 return;
804
805 for (i = 0; i < cmpl; i++) {
806 struct rte_dma_op *op = deq_ops[i];
807
808 if (unlikely(op->status != RTE_DMA_STATUS_SUCCESSFUL))
809 vchan->dma_compl_errs++;
810
811 if (op->rsvd) {
812 uint16_t *ptr = (uint16_t *)(uintptr_t)op->user_meta;
813 uint16_t *pend_ptr = (uint16_t *)(uintptr_t)op->event_meta;
814 uint16_t val = op->rsvd >> 16;
815 uint16_t pend_val = op->rsvd & 0xFFFF;
816
817 if (mem_order)
818 __atomic_store_n(ptr, val, __ATOMIC_RELEASE);
819 else
820 *ptr = val;
821 *pend_ptr -= pend_val;
822 op->rsvd = 0;
823 }
824 }
825
826 /* Return ops to ring buffer */
827 dao_dma_ops_put(vchan, cmpl);
828 vchan->head += cmpl;
829}
830
847static __rte_always_inline void
848dao_dma_update_cmpl_meta(struct dao_dma_vchan_state *vchan, uint16_t *ptr, uint16_t val,
849 uint16_t *pend_ptr, uint16_t pend_val, uint16_t tail)
850{
851 uint16_t idx = tail % DAO_DMA_MAX_INFLIGHT_MDATA;
852 uint16_t j = vchan->mdata[idx].cnt;
853
854 vchan->mdata[idx].ptr[j] = ptr;
855 vchan->mdata[idx].val[j] = val;
856 vchan->mdata[idx].pend_ptr[j] = pend_ptr;
857 vchan->mdata[idx].pend_val[j] = pend_val;
858 vchan->mdata[idx].cnt = j + 1;
859}
860
870static __rte_always_inline void
871dao_dma_check_meta_compl_v2(struct dao_dma_vchan_state *vchan, const int mem_order)
872{
873 uint32_t cmpl, i, j, idx = 0;
874 bool has_err = 0;
875
876 /* Fetch all DMA completed status */
877 cmpl = rte_dma_completed(vchan->devid, vchan->vchan, 128, NULL, &has_err);
878 if (unlikely(has_err)) {
879 vchan->dma_compl_errs++;
880 cmpl += 1;
881 }
882 for (i = vchan->head; i < vchan->head + cmpl; i++) {
884 for (j = 0; j < vchan->mdata[idx].cnt; j++) {
885 if (mem_order)
886 __atomic_store_n(vchan->mdata[idx].ptr[j], vchan->mdata[idx].val[j],
887 __ATOMIC_RELEASE);
888 else
889 *vchan->mdata[idx].ptr[j] = vchan->mdata[idx].val[j];
890 }
891 vchan->mdata[idx].cnt = 0;
892 }
893 vchan->head += cmpl;
894}
895
908static __rte_always_inline void
909dao_dma_update_cmpl_meta_v2(struct dao_dma_vchan_state *vchan, uint16_t *ptr, uint16_t val,
910 uint16_t tail)
911{
912 uint16_t idx = tail % DAO_DMA_MAX_INFLIGHT_MDATA;
913 uint16_t j = vchan->mdata[idx].cnt;
914
915 vchan->mdata[idx].ptr[j] = ptr;
916 vchan->mdata[idx].val[j] = val;
917 vchan->mdata[idx].cnt = j + 1;
918}
919
920#endif /* __INCLUDE_DAO_DMA_H__ */
static __rte_always_inline void dao_dma_enq_src_x1(struct dao_dma_vchan_state *vchan, rte_iova_t src, uint32_t src_len)
Definition dao_dma.h:563
static __rte_always_inline int dao_dma_has_stats_feature(void)
Definition dao_dma.h:299
static __rte_always_inline struct rte_dma_sge * dao_dma_sge_dst(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:487
static __rte_always_inline void dao_dma_check_meta_compl(struct dao_dma_vchan_state *vchan, const int mem_order)
Definition dao_dma.h:755
static __rte_always_inline uint16_t dao_dma_burst_capacity(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:317
#define DAO_DMA_DOORBELL_THRESHOLD
Definition dao_dma.h:39
int dao_dma_lcore_mem2dev_autofree_set(int16_t dma_devid, uint16_t vchan, bool enable)
static __rte_always_inline void dao_dma_ops_release(struct dao_dma_vchan_state *vchan, uint16_t n)
Definition dao_dma.h:723
#define DAO_DMA_MAX_INFLIGHT_MDATA
Definition dao_dma.h:36
static __rte_always_inline struct rte_dma_op ** dao_dma_ops_get(struct dao_dma_vchan_state *vchan, uint16_t n)
Definition dao_dma.h:692
static __rte_always_inline void dao_dma_ops_put(struct dao_dma_vchan_state *vchan, uint16_t n)
Definition dao_dma.h:709
int16_t dao_dma_ctrl_mem2dev(void)
void dao_dma_compl_wait_inflight(uint16_t vchan)
static __rte_always_inline void dao_dma_check_compl(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:653
int dao_dma_lcore_mem2dev_set(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr)
static __rte_always_inline bool dao_dma_desc_avail_get(struct dao_dma_vchan_state *vchan, uint32_t nb_src, uint32_t nb_dst)
Definition dao_dma.h:335
static __rte_always_inline void dao_dma_enq_x1(struct dao_dma_vchan_state *vchan, rte_iova_t src, uint32_t src_len, rte_iova_t dst, uint32_t dst_len)
Definition dao_dma.h:510
int dao_dma_lcore_dev2mem_set_ops(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr, uint16_t nb_ops)
int dao_dma_stats_get(uint16_t lcore_id, struct dao_dma_stats *stats)
static __rte_always_inline void dao_dma_check_meta_compl_ops(struct dao_dma_vchan_state *vchan, const int mem_order)
Definition dao_dma.h:791
int dao_dma_flush_submit_ops(void)
#define DAO_DMA_MAX_VCHAN_PER_LCORE
Definition dao_dma.h:33
#define DAO_DMA_MAX_META_POINTER
Definition dao_dma.h:30
static __rte_always_inline uint16_t dao_dma_src_avail(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:441
int dao_dma_flush_submit(void)
RTE_DECLARE_PER_LCORE(struct dao_dma_vchan_info *, dao_dma_vchan_info)
static __rte_always_inline void dao_dma_enq_dst_x1(struct dao_dma_vchan_state *vchan, rte_iova_t dst, uint32_t dst_len)
Definition dao_dma.h:539
static __rte_always_inline void dao_dma_check_meta_compl_v2(struct dao_dma_vchan_state *vchan, const int mem_order)
Definition dao_dma.h:871
static __rte_always_inline void dao_dma_op_set_cmpl(struct rte_dma_op *op, uint16_t *ptr, uint16_t val, uint16_t *pend_ptr, uint16_t pend_val)
Definition dao_dma.h:737
static __rte_always_inline uint16_t dao_dma_dst_avail(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:457
static __rte_always_inline bool dao_dma_flush(struct dao_dma_vchan_state *vchan, const uint8_t avail)
Definition dao_dma.h:395
static __rte_always_inline struct rte_dma_sge * dao_dma_sge_src(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:473
static __rte_always_inline void dao_dma_update_cmpl_meta(struct dao_dma_vchan_state *vchan, uint16_t *ptr, uint16_t val, uint16_t *pend_ptr, uint16_t pend_val, uint16_t tail)
Definition dao_dma.h:848
int dao_dma_flush_submit_v2(void)
static __rte_always_inline void dao_dma_update_cmpl_meta_v2(struct dao_dma_vchan_state *vchan, uint16_t *ptr, uint16_t val, uint16_t tail)
Definition dao_dma.h:909
static __rte_always_inline bool dao_dma_op_status(struct dao_dma_vchan_state *vchan, uint16_t op_idx)
Definition dao_dma.h:373
static __rte_always_inline uint16_t dao_dma_ops_avail(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:676
int dao_dma_lcore_mem2dev_set_ops(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr, uint16_t nb_ops)
int16_t dao_dma_ctrl_dev2mem(void)
static __rte_always_inline uint16_t dao_dma_enq_x4(struct dao_dma_vchan_state *vchan, uint64x2_t *vsrc, uint64x2_t *vdst)
Definition dao_dma.h:586
int dao_dma_ctrl_dev_set(int16_t dev2mem_id, int16_t mem2dev_id)
int dao_dma_lcore_dev2mem_set(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr)
#define DAO_DMA_MAX_POINTER
Definition dao_dma.h:27
uint16_t val[DAO_DMA_MAX_META_POINTER]
Definition dao_dma.h:48
uint16_t * pend_ptr[DAO_DMA_MAX_META_POINTER]
Definition dao_dma.h:44
uint16_t * ptr[DAO_DMA_MAX_META_POINTER]
Definition dao_dma.h:50
uint16_t pend_val[DAO_DMA_MAX_META_POINTER]
Definition dao_dma.h:46
uint16_t nb_mem2dev
Definition dao_dma.h:134
struct dao_dma_vchan_stats dev2mem[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:136
struct dao_dma_vchan_stats mem2dev[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:138
uint16_t nb_dev2mem
Definition dao_dma.h:132
struct dao_dma_vchan_state mem2dev[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:114
uint16_t nb_mem2dev
Definition dao_dma.h:110
struct dao_dma_vchan_state dev2mem[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:112
uint16_t nb_dev2mem
Definition dao_dma.h:108
uint64_t dma_enq_errs
Definition dao_dma.h:88
uint16_t ops_head
Definition dao_dma.h:96
uint16_t ops_tail
Definition dao_dma.h:98
uint16_t ops_mask
Definition dao_dma.h:100
uint8_t flush_thr
Definition dao_dma.h:71
struct rte_dma_sge dst[DAO_DMA_MAX_POINTER]
Definition dao_dma.h:80
struct rte_dma_op ** dma_ops
Definition dao_dma.h:94
uint8_t auto_free
Definition dao_dma.h:73
uint16_t pend_ops
Definition dao_dma.h:76
uint64_t dma_compl_errs
Definition dao_dma.h:90
uint64_t dbells
Definition dao_dma.h:86
struct rte_dma_sge src[DAO_DMA_MAX_POINTER]
Definition dao_dma.h:78
struct dao_dma_cmpl_mdata mdata[DAO_DMA_MAX_INFLIGHT_MDATA]
Definition dao_dma.h:102
uint64_t enq_errs
Definition dao_dma.h:126