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_VCHAN_PER_LCORE 64
32
34#define DAO_DMA_MAX_INFLIGHT_MDATA 4096
35
49
53 uint16_t tail;
55 uint16_t head;
57 int16_t devid;
59 uint8_t vchan;
60 uint8_t rsvd;
62 uint16_t src_i;
64 uint16_t dst_i;
66 uint8_t flush_thr;
68 uint8_t auto_free : 1;
69 uint8_t rsvd2 : 7;
71 uint16_t pend_ops;
73 struct rte_dma_sge src[DAO_DMA_MAX_POINTER];
75 struct rte_dma_sge dst[DAO_DMA_MAX_POINTER];
77 uint64_t ptrs;
79 uint64_t ops;
81 uint64_t dbells;
83 uint64_t dma_enq_errs;
89
101
105 uint64_t ptrs;
107 uint64_t ops;
109 uint64_t dbells;
111 uint64_t enq_errs;
112};
113
125
128
136
144
155int dao_dma_stats_get(uint16_t lcore_id, struct dao_dma_stats *stats);
156
169int dao_dma_lcore_dev2mem_set(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr);
170
183int dao_dma_lcore_mem2dev_set(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr);
184
197int dao_dma_lcore_mem2dev_autofree_set(int16_t dma_devid, uint16_t vchan, bool enable);
198
209int dao_dma_ctrl_dev_set(int16_t dev2mem_id, int16_t mem2dev_id);
210
218
226
233void dao_dma_compl_wait(uint16_t vchan);
234
241void dao_dma_compl_wait_v2(uint16_t vchan);
242
249static __rte_always_inline int
251{
252#if DAO_DMA_STATS
253 return 1;
254#else
255 return 0;
256#endif
257}
258
270static __rte_always_inline bool
271dao_dma_op_status(struct dao_dma_vchan_state *vchan, uint16_t op_idx)
272{
273 uint16_t head = vchan->head;
274 uint16_t tail = vchan->tail;
275
276 if (vchan->src_i && (tail == op_idx))
277 return false;
278
279 return head <= tail ? (op_idx < head || op_idx >= tail) : (op_idx < head && op_idx >= tail);
280}
281
292static __rte_always_inline bool
293dao_dma_flush(struct dao_dma_vchan_state *vchan, const uint8_t avail)
294{
295 int src_avail = vchan->flush_thr - vchan->src_i;
296 int dst_avail = vchan->flush_thr - vchan->dst_i;
297 uint64_t flags = (uint64_t)vchan->auto_free << 3;
298 int rc;
299
300 if (likely((src_avail >= (int)avail || !vchan->src_i) &&
301 (dst_avail >= (int)avail || !vchan->dst_i)))
302 goto exit;
303
304 rc = rte_dma_copy_sg(vchan->devid, vchan->vchan, vchan->src, vchan->dst, vchan->src_i,
305 vchan->dst_i, flags);
306 if (unlikely(rc < 0)) {
308 vchan->dma_enq_errs++;
309 return false;
310 }
311 vchan->tail++;
312 vchan->pend_ops++;
314 vchan->ptrs += vchan->src_i;
315 vchan->ops++;
316 }
317 vchan->src_i = 0;
318 vchan->dst_i = 0;
319exit:
320 return true;
321}
322
331static __rte_always_inline uint16_t
333{
334 int src_avail = vchan->flush_thr - vchan->src_i;
335
336 return src_avail;
337}
338
347static __rte_always_inline uint16_t
349{
350 int dst_avail = vchan->flush_thr - vchan->dst_i;
351
352 return dst_avail;
353}
354
363static __rte_always_inline struct rte_dma_sge *
365{
366 return &vchan->src[vchan->src_i];
367}
368
377static __rte_always_inline struct rte_dma_sge *
379{
380 return &vchan->dst[vchan->dst_i];
381}
382
400static __rte_always_inline void
401dao_dma_enq_x1(struct dao_dma_vchan_state *vchan, rte_iova_t src, uint32_t src_len, rte_iova_t dst,
402 uint32_t dst_len)
403{
404 uint16_t src_i = vchan->src_i;
405 uint16_t dst_i = vchan->dst_i;
406
407 vchan->dst[dst_i].addr = dst;
408 vchan->dst[dst_i].length = dst_len;
409 vchan->src[src_i].addr = src;
410 vchan->src[src_i].length = src_len;
411
412 vchan->src_i = src_i + 1;
413 vchan->dst_i = dst_i + 1;
414}
415
429static __rte_always_inline void
430dao_dma_enq_dst_x1(struct dao_dma_vchan_state *vchan, rte_iova_t dst, uint32_t dst_len)
431{
432 uint16_t dst_i = vchan->dst_i;
433
434 vchan->dst[dst_i].addr = dst;
435 vchan->dst[dst_i].length = dst_len;
436
437 vchan->dst_i = dst_i + 1;
438}
439
453static __rte_always_inline void
454dao_dma_enq_src_x1(struct dao_dma_vchan_state *vchan, rte_iova_t src, uint32_t src_len)
455{
456 uint16_t src_i = vchan->src_i;
457
458 vchan->src[src_i].addr = src;
459 vchan->src[src_i].length = src_len;
460
461 vchan->src_i = src_i + 1;
462}
463
476static __rte_always_inline uint16_t
477dao_dma_enq_x4(struct dao_dma_vchan_state *vchan, uint64x2_t *vsrc, uint64x2_t *vdst)
478{
479 struct rte_dma_sge *src, *dst;
480 uint16_t src_i = vchan->src_i;
481 uint16_t dst_i = vchan->dst_i;
482 int src_avail = vchan->flush_thr - src_i;
483 int i;
484
485 src = vchan->src + src_i;
486 dst = vchan->dst + dst_i;
487 if (src_avail >= 4) {
488 vst1q_u64((uint64_t *)&src[0], vsrc[0]);
489 vst1q_u64((uint64_t *)&src[1], vsrc[1]);
490 vst1q_u64((uint64_t *)&src[2], vsrc[2]);
491 vst1q_u64((uint64_t *)&src[3], vsrc[3]);
492
493 vst1q_u64((uint64_t *)&dst[0], vdst[0]);
494 vst1q_u64((uint64_t *)&dst[1], vdst[1]);
495 vst1q_u64((uint64_t *)&dst[2], vdst[2]);
496 vst1q_u64((uint64_t *)&dst[3], vdst[3]);
497
498 vchan->src_i = src_i + 4;
499 vchan->dst_i = dst_i + 4;
500 return 4;
501 }
502
503 i = 0;
504 while (i < 4 && src_avail > 0) {
505 vst1q_u64((uint64_t *)src, vsrc[i]);
506 vst1q_u64((uint64_t *)dst, vdst[i]);
507 src++;
508 dst++;
509 i++;
510 src_avail--;
511 };
512 vchan->src_i = src_i + i;
513 vchan->dst_i = dst_i + i;
514
515 /* Flush enqueued pointers */
516 dao_dma_flush(vchan, 4);
517
518 src_i = vchan->src_i;
519 dst_i = vchan->dst_i;
520 src = vchan->src + src_i;
521 dst = vchan->dst + dst_i;
522 src_avail = vchan->flush_thr - src_i;
523
524 while (i < 4 && src_avail > 0) {
525 vst1q_u64((uint64_t *)src, vsrc[i]);
526 vst1q_u64((uint64_t *)dst, vdst[i]);
527 i++;
528 src++;
529 dst++;
530 src_avail--;
531 vchan->src_i++;
532 vchan->dst_i++;
533 };
534 return i;
535}
536
543static __rte_always_inline void
545{
546 uint16_t cmpl;
547 bool has_err = 0;
548
549 /* Fetch all DMA completed status */
550 cmpl = rte_dma_completed(vchan->devid, vchan->vchan, 128, NULL, &has_err);
551 if (unlikely(has_err)) {
552 vchan->dma_compl_errs++;
553 cmpl += 1;
554 }
555 vchan->head += cmpl;
556}
557
567static __rte_always_inline void
568dao_dma_check_meta_compl(struct dao_dma_vchan_state *vchan, const int mem_order)
569{
570 uint32_t cmpl, i, j, idx = 0;
571 bool has_err = 0;
572
573 /* Fetch all DMA completed status */
574 cmpl = rte_dma_completed(vchan->devid, vchan->vchan, 128, NULL, &has_err);
575 if (unlikely(has_err)) {
576 vchan->dma_compl_errs++;
577 cmpl += 1;
578 }
579 for (i = vchan->head; i < vchan->head + cmpl; i++) {
581 for (j = 0; j < vchan->mdata[idx].cnt; j++) {
582 if (mem_order)
583 __atomic_store_n(vchan->mdata[idx].ptr[j], vchan->mdata[idx].val[j],
584 __ATOMIC_RELEASE);
585 else
586 *vchan->mdata[idx].ptr[j] = vchan->mdata[idx].val[j];
587 *vchan->mdata[idx].pend_ptr[j] -= vchan->mdata[idx].pend_val[j];
588 }
589 vchan->mdata[idx].cnt = 0;
590 }
591 vchan->head += cmpl;
592}
593
610static __rte_always_inline void
611dao_dma_update_cmpl_meta(struct dao_dma_vchan_state *vchan, uint16_t *ptr, uint16_t val,
612 uint16_t *pend_ptr, uint16_t pend_val, uint16_t tail)
613{
614 uint16_t idx = tail % DAO_DMA_MAX_INFLIGHT_MDATA;
615 uint16_t j = vchan->mdata[idx].cnt;
616
617 vchan->mdata[idx].ptr[j] = ptr;
618 vchan->mdata[idx].val[j] = val;
619 vchan->mdata[idx].pend_ptr[j] = pend_ptr;
620 vchan->mdata[idx].pend_val[j] = pend_val;
621 vchan->mdata[idx].cnt = j + 1;
622}
623
633static __rte_always_inline void
634dao_dma_check_meta_compl_v2(struct dao_dma_vchan_state *vchan, const int mem_order)
635{
636 uint32_t cmpl, i, j, idx = 0;
637 bool has_err = 0;
638
639 /* Fetch all DMA completed status */
640 cmpl = rte_dma_completed(vchan->devid, vchan->vchan, 128, NULL, &has_err);
641 if (unlikely(has_err)) {
642 vchan->dma_compl_errs++;
643 cmpl += 1;
644 }
645 for (i = vchan->head; i < vchan->head + cmpl; i++) {
647 for (j = 0; j < vchan->mdata[idx].cnt; j++) {
648 if (mem_order)
649 __atomic_store_n(vchan->mdata[idx].ptr[j], vchan->mdata[idx].val[j],
650 __ATOMIC_RELAXED);
651 else
652 *vchan->mdata[idx].ptr[j] = vchan->mdata[idx].val[j];
653 }
654 vchan->mdata[idx].cnt = 0;
655 }
656 vchan->head += cmpl;
657}
658
671static __rte_always_inline void
672dao_dma_update_cmpl_meta_v2(struct dao_dma_vchan_state *vchan, uint16_t *ptr, uint16_t val,
673 uint16_t tail)
674{
675 uint16_t idx = tail % DAO_DMA_MAX_INFLIGHT_MDATA;
676 uint16_t j = vchan->mdata[idx].cnt;
677
678 vchan->mdata[idx].ptr[j] = ptr;
679 vchan->mdata[idx].val[j] = val;
680 vchan->mdata[idx].cnt = j + 1;
681}
682
683#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:454
static __rte_always_inline int dao_dma_has_stats_feature(void)
Definition dao_dma.h:250
static __rte_always_inline struct rte_dma_sge * dao_dma_sge_dst(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:378
static __rte_always_inline void dao_dma_check_meta_compl(struct dao_dma_vchan_state *vchan, const int mem_order)
Definition dao_dma.h:568
void dao_dma_compl_wait_v2(uint16_t vchan)
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:34
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:544
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:401
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:31
#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:332
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:430
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:634
static __rte_always_inline uint16_t dao_dma_dst_avail(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:348
static __rte_always_inline bool dao_dma_flush(struct dao_dma_vchan_state *vchan, const uint8_t avail)
Definition dao_dma.h:293
static __rte_always_inline struct rte_dma_sge * dao_dma_sge_src(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:364
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:611
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:672
static __rte_always_inline bool dao_dma_op_status(struct dao_dma_vchan_state *vchan, uint16_t op_idx)
Definition dao_dma.h:271
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:477
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:43
uint16_t * pend_ptr[DAO_DMA_MAX_META_POINTER]
Definition dao_dma.h:39
uint16_t * ptr[DAO_DMA_MAX_META_POINTER]
Definition dao_dma.h:45
uint16_t pend_val[DAO_DMA_MAX_META_POINTER]
Definition dao_dma.h:41
uint16_t nb_mem2dev
Definition dao_dma.h:119
struct dao_dma_vchan_stats dev2mem[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:121
struct dao_dma_vchan_stats mem2dev[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:123
uint16_t nb_dev2mem
Definition dao_dma.h:117
struct dao_dma_vchan_state mem2dev[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:99
uint16_t nb_mem2dev
Definition dao_dma.h:95
struct dao_dma_vchan_state dev2mem[DAO_DMA_MAX_VCHAN_PER_LCORE]
Definition dao_dma.h:97
uint16_t nb_dev2mem
Definition dao_dma.h:93
uint64_t dma_enq_errs
Definition dao_dma.h:83
uint8_t flush_thr
Definition dao_dma.h:66
struct rte_dma_sge dst[DAO_DMA_MAX_POINTER]
Definition dao_dma.h:75
uint8_t auto_free
Definition dao_dma.h:68
uint16_t pend_ops
Definition dao_dma.h:71
uint64_t dma_compl_errs
Definition dao_dma.h:85
uint64_t dbells
Definition dao_dma.h:81
struct rte_dma_sge src[DAO_DMA_MAX_POINTER]
Definition dao_dma.h:73
struct dao_dma_cmpl_mdata mdata[DAO_DMA_MAX_INFLIGHT_MDATA]
Definition dao_dma.h:87
uint64_t enq_errs
Definition dao_dma.h:111