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_vect.h>
19
20#include <dao_config.h>
21
22#include "dao_log.h"
23
25#define DAO_DMA_MAX_POINTER 15u
26
28#define DAO_DMA_MAX_META_POINTER 48
29
31#define DAO_DMA_MAX_POINTER_THR_DFLT 8u
32
34#define DAO_DMA_MAX_VCHAN_PER_LCORE 64
35
37#define DAO_DMA_MAX_INFLIGHT_MDATA 4096
38
52
56 uint16_t tail;
58 uint16_t head;
60 int16_t devid;
62 uint8_t vchan;
63 uint8_t rsvd;
65 uint16_t src_i;
67 uint16_t dst_i;
69 uint8_t flush_thr;
71 uint8_t auto_free : 1;
72 uint8_t rsvd2 : 7;
74 uint16_t pend_ops;
76 struct rte_dma_sge src[DAO_DMA_MAX_POINTER];
78 struct rte_dma_sge dst[DAO_DMA_MAX_POINTER];
80 uint64_t ptrs;
82 uint64_t ops;
84 uint64_t dbells;
86 uint64_t dma_enq_errs;
92
104
108 uint64_t ptrs;
110 uint64_t ops;
112 uint64_t dbells;
114 uint64_t enq_errs;
115};
116
128
131
139
147
158int dao_dma_stats_get(uint16_t lcore_id, struct dao_dma_stats *stats);
159
172int dao_dma_lcore_dev2mem_set(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr);
173
186int dao_dma_lcore_mem2dev_set(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr);
187
200int dao_dma_lcore_mem2dev_autofree_set(int16_t dma_devid, uint16_t vchan, bool enable);
201
212int dao_dma_ctrl_dev_set(int16_t dev2mem_id, int16_t mem2dev_id);
213
221
229
236void dao_dma_compl_wait(uint16_t vchan);
237
244static __rte_always_inline int
246{
247#if DAO_DMA_STATS
248 return 1;
249#else
250 return 0;
251#endif
252}
253
265static __rte_always_inline bool
266dao_dma_op_status(struct dao_dma_vchan_state *vchan, uint16_t op_idx)
267{
268 uint16_t head = vchan->head;
269 uint16_t tail = vchan->tail;
270
271 if (vchan->src_i && (tail == op_idx))
272 return false;
273
274 return head <= tail ? (op_idx < head || op_idx >= tail) : (op_idx < head && op_idx >= tail);
275}
276
287static __rte_always_inline bool
288dao_dma_flush(struct dao_dma_vchan_state *vchan, const uint8_t avail)
289{
290 int src_avail = vchan->flush_thr - vchan->src_i;
291 int dst_avail = vchan->flush_thr - vchan->dst_i;
292 uint64_t flags = (uint64_t)vchan->auto_free << 3;
293 int rc;
294
295 if (likely((src_avail >= (int)avail || !vchan->src_i) &&
296 (dst_avail >= (int)avail || !vchan->dst_i)))
297 goto exit;
298
299 rc = rte_dma_copy_sg(vchan->devid, vchan->vchan, vchan->src, vchan->dst, vchan->src_i,
300 vchan->dst_i, flags);
301 if (unlikely(rc < 0)) {
303 vchan->dma_enq_errs++;
304 return false;
305 }
306 vchan->tail++;
307 vchan->pend_ops++;
309 vchan->ptrs += vchan->src_i;
310 vchan->ops++;
311 }
312 vchan->src_i = 0;
313 vchan->dst_i = 0;
314exit:
315 return true;
316}
317
326static __rte_always_inline uint16_t
328{
329 int src_avail = vchan->flush_thr - vchan->src_i;
330
331 return src_avail;
332}
333
342static __rte_always_inline uint16_t
344{
345 int dst_avail = vchan->flush_thr - vchan->dst_i;
346
347 return dst_avail;
348}
349
358static __rte_always_inline struct rte_dma_sge *
360{
361 return &vchan->src[vchan->src_i];
362}
363
372static __rte_always_inline struct rte_dma_sge *
374{
375 return &vchan->dst[vchan->dst_i];
376}
377
395static __rte_always_inline void
396dao_dma_enq_x1(struct dao_dma_vchan_state *vchan, rte_iova_t src, uint32_t src_len, rte_iova_t dst,
397 uint32_t dst_len)
398{
399 uint16_t src_i = vchan->src_i;
400 uint16_t dst_i = vchan->dst_i;
401
402 vchan->dst[dst_i].addr = dst;
403 vchan->dst[dst_i].length = dst_len;
404 vchan->src[src_i].addr = src;
405 vchan->src[src_i].length = src_len;
406
407 vchan->src_i = src_i + 1;
408 vchan->dst_i = dst_i + 1;
409}
410
424static __rte_always_inline void
425dao_dma_enq_dst_x1(struct dao_dma_vchan_state *vchan, rte_iova_t dst, uint32_t dst_len)
426{
427 uint16_t dst_i = vchan->dst_i;
428
429 vchan->dst[dst_i].addr = dst;
430 vchan->dst[dst_i].length = dst_len;
431
432 vchan->dst_i = dst_i + 1;
433}
434
448static __rte_always_inline void
449dao_dma_enq_src_x1(struct dao_dma_vchan_state *vchan, rte_iova_t src, uint32_t src_len)
450{
451 uint16_t src_i = vchan->src_i;
452
453 vchan->src[src_i].addr = src;
454 vchan->src[src_i].length = src_len;
455
456 vchan->src_i = src_i + 1;
457}
458
471static __rte_always_inline uint16_t
472dao_dma_enq_x4(struct dao_dma_vchan_state *vchan, uint64x2_t *vsrc, uint64x2_t *vdst)
473{
474 struct rte_dma_sge *src, *dst;
475 uint16_t src_i = vchan->src_i;
476 uint16_t dst_i = vchan->dst_i;
477 int src_avail = vchan->flush_thr - src_i;
478 int i;
479
480 src = vchan->src + src_i;
481 dst = vchan->dst + dst_i;
482 if (src_avail >= 4) {
483 vst1q_u64((uint64_t *)&src[0], vsrc[0]);
484 vst1q_u64((uint64_t *)&src[1], vsrc[1]);
485 vst1q_u64((uint64_t *)&src[2], vsrc[2]);
486 vst1q_u64((uint64_t *)&src[3], vsrc[3]);
487
488 vst1q_u64((uint64_t *)&dst[0], vdst[0]);
489 vst1q_u64((uint64_t *)&dst[1], vdst[1]);
490 vst1q_u64((uint64_t *)&dst[2], vdst[2]);
491 vst1q_u64((uint64_t *)&dst[3], vdst[3]);
492
493 vchan->src_i = src_i + 4;
494 vchan->dst_i = dst_i + 4;
495 return 4;
496 }
497
498 i = 0;
499 while (i < 4 && src_avail > 0) {
500 vst1q_u64((uint64_t *)src, vsrc[i]);
501 vst1q_u64((uint64_t *)dst, vdst[i]);
502 src++;
503 dst++;
504 i++;
505 src_avail--;
506 };
507 vchan->src_i = src_i + i;
508 vchan->dst_i = dst_i + i;
509
510 /* Flush enqueued pointers */
511 dao_dma_flush(vchan, 4);
512
513 src_i = vchan->src_i;
514 dst_i = vchan->dst_i;
515 src = vchan->src + src_i;
516 dst = vchan->dst + dst_i;
517 src_avail = vchan->flush_thr - src_i;
518
519 while (i < 4 && src_avail > 0) {
520 vst1q_u64((uint64_t *)src, vsrc[i]);
521 vst1q_u64((uint64_t *)dst, vdst[i]);
522 i++;
523 src++;
524 dst++;
525 src_avail--;
526 vchan->src_i++;
527 vchan->dst_i++;
528 };
529 return i;
530}
531
538static __rte_always_inline void
540{
541 uint16_t cmpl;
542 bool has_err = 0;
543
544 /* Fetch all DMA completed status */
545 cmpl = rte_dma_completed(vchan->devid, vchan->vchan, 128, NULL, &has_err);
546 if (unlikely(has_err)) {
547 vchan->dma_compl_errs++;
548 cmpl += 1;
549 }
550 vchan->head += cmpl;
551}
552
562static __rte_always_inline void
563dao_dma_check_meta_compl(struct dao_dma_vchan_state *vchan, const int mem_order)
564{
565 uint32_t cmpl, i, j, idx = 0;
566 bool has_err = 0;
567
568 /* Fetch all DMA completed status */
569 cmpl = rte_dma_completed(vchan->devid, vchan->vchan, 128, NULL, &has_err);
570 if (unlikely(has_err)) {
571 vchan->dma_compl_errs++;
572 cmpl += 1;
573 }
574 for (i = vchan->head; i < vchan->head + cmpl; i++) {
576 for (j = 0; j < vchan->mdata[idx].cnt; j++) {
577 if (mem_order)
578 __atomic_store_n(vchan->mdata[idx].ptr[j], vchan->mdata[idx].val[j],
579 __ATOMIC_RELEASE);
580 else
581 *vchan->mdata[idx].ptr[j] = vchan->mdata[idx].val[j];
582 *vchan->mdata[idx].pend_ptr[j] -= vchan->mdata[idx].pend_val[j];
583 }
584 vchan->mdata[idx].cnt = 0;
585 }
586 vchan->head += cmpl;
587}
588
605static __rte_always_inline void
606dao_dma_update_cmpl_meta(struct dao_dma_vchan_state *vchan, uint16_t *ptr, uint16_t val,
607 uint16_t *pend_ptr, uint16_t pend_val, uint16_t tail)
608{
609 uint16_t idx = tail % DAO_DMA_MAX_INFLIGHT_MDATA;
610 uint16_t j = vchan->mdata[idx].cnt;
611
612 vchan->mdata[idx].ptr[j] = ptr;
613 vchan->mdata[idx].val[j] = val;
614 vchan->mdata[idx].pend_ptr[j] = pend_ptr;
615 vchan->mdata[idx].pend_val[j] = pend_val;
616 vchan->mdata[idx].cnt = j + 1;
617}
618
628static __rte_always_inline void
629dao_dma_check_meta_compl_v2(struct dao_dma_vchan_state *vchan, const int mem_order)
630{
631 uint32_t cmpl, i, j, idx = 0;
632 bool has_err = 0;
633
634 /* Fetch all DMA completed status */
635 cmpl = rte_dma_completed(vchan->devid, vchan->vchan, 128, NULL, &has_err);
636 if (unlikely(has_err)) {
637 vchan->dma_compl_errs++;
638 cmpl += 1;
639 }
640 for (i = vchan->head; i < vchan->head + cmpl; i++) {
642 for (j = 0; j < vchan->mdata[idx].cnt; j++) {
643 if (mem_order)
644 __atomic_store_n(vchan->mdata[idx].ptr[j], vchan->mdata[idx].val[j],
645 __ATOMIC_RELAXED);
646 else
647 *vchan->mdata[idx].ptr[j] = vchan->mdata[idx].val[j];
648 }
649 vchan->mdata[idx].cnt = 0;
650 }
651 vchan->head += cmpl;
652}
653
666static __rte_always_inline void
667dao_dma_update_cmpl_meta_v2(struct dao_dma_vchan_state *vchan, uint16_t *ptr, uint16_t val,
668 uint16_t tail)
669{
670 uint16_t idx = tail % DAO_DMA_MAX_INFLIGHT_MDATA;
671 uint16_t j = vchan->mdata[idx].cnt;
672
673 vchan->mdata[idx].ptr[j] = ptr;
674 vchan->mdata[idx].val[j] = val;
675 vchan->mdata[idx].cnt = j + 1;
676}
677
678#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:449
static __rte_always_inline int dao_dma_has_stats_feature(void)
Definition dao_dma.h:245
static __rte_always_inline struct rte_dma_sge * dao_dma_sge_dst(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:373
static __rte_always_inline void dao_dma_check_meta_compl(struct dao_dma_vchan_state *vchan, const int mem_order)
Definition dao_dma.h:563
void dao_dma_compl_wait(uint16_t vchan)
int dao_dma_lcore_mem2dev_autofree_set(int16_t dma_devid, uint16_t vchan, bool enable)
#define DAO_DMA_MAX_INFLIGHT_MDATA
Definition dao_dma.h:37
int16_t dao_dma_ctrl_mem2dev(void)
static __rte_always_inline void dao_dma_check_compl(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:539
int dao_dma_lcore_mem2dev_set(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr)
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:396
int dao_dma_stats_get(uint16_t lcore_id, struct dao_dma_stats *stats)
#define DAO_DMA_MAX_VCHAN_PER_LCORE
Definition dao_dma.h:34
#define DAO_DMA_MAX_META_POINTER
Definition dao_dma.h:28
static __rte_always_inline uint16_t dao_dma_src_avail(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:327
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:425
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:629
static __rte_always_inline uint16_t dao_dma_dst_avail(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:343
static __rte_always_inline bool dao_dma_flush(struct dao_dma_vchan_state *vchan, const uint8_t avail)
Definition dao_dma.h:288
static __rte_always_inline struct rte_dma_sge * dao_dma_sge_src(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:359
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:606
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:667
static __rte_always_inline bool dao_dma_op_status(struct dao_dma_vchan_state *vchan, uint16_t op_idx)
Definition dao_dma.h:266
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:472
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:25
uint16_t val[DAO_DMA_MAX_META_POINTER]
Definition dao_dma.h:46
uint16_t * pend_ptr[DAO_DMA_MAX_META_POINTER]
Definition dao_dma.h:42
uint16_t * ptr[DAO_DMA_MAX_META_POINTER]
Definition dao_dma.h:48
uint16_t pend_val[DAO_DMA_MAX_META_POINTER]
Definition dao_dma.h:44
uint16_t nb_mem2dev
Definition dao_dma.h:122
struct dao_dma_vchan_stats dev2mem[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:124
struct dao_dma_vchan_stats mem2dev[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:126
uint16_t nb_dev2mem
Definition dao_dma.h:120
struct dao_dma_vchan_state mem2dev[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:102
uint16_t nb_mem2dev
Definition dao_dma.h:98
struct dao_dma_vchan_state dev2mem[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:100
uint16_t nb_dev2mem
Definition dao_dma.h:96
uint64_t dma_enq_errs
Definition dao_dma.h:86
uint8_t flush_thr
Definition dao_dma.h:69
struct rte_dma_sge dst[DAO_DMA_MAX_POINTER]
Definition dao_dma.h:78
uint8_t auto_free
Definition dao_dma.h:71
uint16_t pend_ops
Definition dao_dma.h:74
uint64_t dma_compl_errs
Definition dao_dma.h:88
uint64_t dbells
Definition dao_dma.h:84
struct rte_dma_sge src[DAO_DMA_MAX_POINTER]
Definition dao_dma.h:76
struct dao_dma_cmpl_mdata mdata[DAO_DMA_MAX_INFLIGHT_MDATA]
Definition dao_dma.h:90
uint64_t enq_errs
Definition dao_dma.h:114