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_POINTER_THR_DFLT 8u
29
31#define DAO_DMA_MAX_VCHAN_PER_LCORE 128
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
147int dao_dma_stats_get(uint16_t lcore_id, struct dao_dma_stats *stats);
148
161int dao_dma_lcore_dev2mem_set(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr);
162
175int dao_dma_lcore_mem2dev_set(int16_t dma_devid, uint16_t nb_vchans, uint16_t flush_thr);
176
189int dao_dma_lcore_mem2dev_autofree_set(int16_t dma_devid, uint16_t vchan, bool enable);
190
201int dao_dma_ctrl_dev_set(int16_t dev2mem_id, int16_t mem2dev_id);
202
210
218
225void dao_dma_compl_wait(uint16_t vchan);
226
233static __rte_always_inline int
235{
236#if DAO_DMA_STATS
237 return 1;
238#else
239 return 0;
240#endif
241}
242
254static __rte_always_inline bool
255dao_dma_op_status(struct dao_dma_vchan_state *vchan, uint16_t op_idx)
256{
257 uint16_t head = vchan->head;
258 uint16_t tail = vchan->tail;
259
260 if (vchan->src_i && (tail == op_idx))
261 return false;
262
263 return head <= tail ? (op_idx < head || op_idx >= tail) : (op_idx < head && op_idx >= tail);
264}
265
276static __rte_always_inline bool
277dao_dma_flush(struct dao_dma_vchan_state *vchan, const uint8_t avail)
278{
279 int src_avail = vchan->flush_thr - vchan->src_i;
280 int dst_avail = vchan->flush_thr - vchan->dst_i;
281 uint64_t flags = (uint64_t)vchan->auto_free << 3;
282 int rc;
283
284 if (likely((src_avail >= (int)avail || !vchan->src_i) &&
285 (dst_avail >= (int)avail || !vchan->dst_i)))
286 goto exit;
287
288 rc = rte_dma_copy_sg(vchan->devid, vchan->vchan, vchan->src, vchan->dst, vchan->src_i,
289 vchan->dst_i, flags);
290 if (unlikely(rc < 0)) {
292 vchan->dma_enq_errs++;
293 return false;
294 }
295 vchan->tail++;
296 vchan->pend_ops++;
298 vchan->ptrs += vchan->src_i;
299 vchan->ops++;
300 }
301 vchan->src_i = 0;
302 vchan->dst_i = 0;
303exit:
304 return true;
305}
306
315static __rte_always_inline uint16_t
317{
318 int src_avail = vchan->flush_thr - vchan->src_i;
319
320 return src_avail;
321}
322
331static __rte_always_inline struct rte_dma_sge *
333{
334 return &vchan->src[vchan->src_i];
335}
336
345static __rte_always_inline struct rte_dma_sge *
347{
348 return &vchan->dst[vchan->dst_i];
349}
350
368static __rte_always_inline void
369dao_dma_enq_x1(struct dao_dma_vchan_state *vchan, rte_iova_t src, uint32_t src_len, rte_iova_t dst,
370 uint32_t dst_len)
371{
372 uint16_t src_i = vchan->src_i;
373 uint16_t dst_i = vchan->dst_i;
374
375 vchan->dst[dst_i].addr = dst;
376 vchan->dst[dst_i].length = dst_len;
377 vchan->src[src_i].addr = src;
378 vchan->src[src_i].length = src_len;
379
380 vchan->src_i = src_i + 1;
381 vchan->dst_i = dst_i + 1;
382}
383
397static __rte_always_inline void
398dao_dma_enq_dst_x1(struct dao_dma_vchan_state *vchan, rte_iova_t dst, uint32_t dst_len)
399{
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
405 vchan->dst_i = dst_i + 1;
406}
407
421static __rte_always_inline void
422dao_dma_enq_src_x1(struct dao_dma_vchan_state *vchan, rte_iova_t src, uint32_t src_len)
423{
424 uint16_t src_i = vchan->src_i;
425
426 vchan->src[src_i].addr = src;
427 vchan->src[src_i].length = src_len;
428
429 vchan->src_i = src_i + 1;
430}
431
444static __rte_always_inline uint16_t
445dao_dma_enq_x4(struct dao_dma_vchan_state *vchan, uint64x2_t *vsrc, uint64x2_t *vdst)
446{
447 struct rte_dma_sge *src, *dst;
448 uint16_t src_i = vchan->src_i;
449 uint16_t dst_i = vchan->dst_i;
450 int src_avail = vchan->flush_thr - src_i;
451 int i;
452
453 src = vchan->src + src_i;
454 dst = vchan->dst + dst_i;
455 if (src_avail >= 4) {
456 vst1q_u64((uint64_t *)&src[0], vsrc[0]);
457 vst1q_u64((uint64_t *)&src[1], vsrc[1]);
458 vst1q_u64((uint64_t *)&src[2], vsrc[2]);
459 vst1q_u64((uint64_t *)&src[3], vsrc[3]);
460
461 vst1q_u64((uint64_t *)&dst[0], vdst[0]);
462 vst1q_u64((uint64_t *)&dst[1], vdst[1]);
463 vst1q_u64((uint64_t *)&dst[2], vdst[2]);
464 vst1q_u64((uint64_t *)&dst[3], vdst[3]);
465
466 vchan->src_i = src_i + 4;
467 vchan->dst_i = dst_i + 4;
468 return 4;
469 }
470
471 i = 0;
472 while (i < 4 && src_avail > 0) {
473 vst1q_u64((uint64_t *)src, vsrc[i]);
474 vst1q_u64((uint64_t *)dst, vdst[i]);
475 src++;
476 dst++;
477 i++;
478 src_avail--;
479 };
480 vchan->src_i = src_i + i;
481 vchan->dst_i = dst_i + i;
482
483 /* Flush enqueued pointers */
484 dao_dma_flush(vchan, 4);
485
486 src_i = vchan->src_i;
487 dst_i = vchan->dst_i;
488 src = vchan->src + src_i;
489 dst = vchan->dst + dst_i;
490 src_avail = vchan->flush_thr - src_i;
491
492 while (i < 4 && src_avail > 0) {
493 vst1q_u64((uint64_t *)src, vsrc[i]);
494 vst1q_u64((uint64_t *)dst, vdst[i]);
495 i++;
496 src++;
497 dst++;
498 src_avail--;
499 vchan->src_i++;
500 vchan->dst_i++;
501 };
502 return i;
503}
504
511static __rte_always_inline void
513{
514 uint16_t cmpl;
515 bool has_err = 0;
516
517 /* Fetch all DMA completed status */
518 cmpl = rte_dma_completed(vchan->devid, vchan->vchan, 128, NULL, &has_err);
519 if (unlikely(has_err)) {
520 vchan->dma_compl_errs++;
521 cmpl += 1;
522 }
523 vchan->head += cmpl;
524}
525
535static __rte_always_inline void
536dao_dma_check_meta_compl(struct dao_dma_vchan_state *vchan, const int mem_order)
537{
538 uint32_t cmpl, i, j, idx = 0;
539 bool has_err = 0;
540
541 /* Fetch all DMA completed status */
542 cmpl = rte_dma_completed(vchan->devid, vchan->vchan, 128, NULL, &has_err);
543 if (unlikely(has_err)) {
544 vchan->dma_compl_errs++;
545 cmpl += 1;
546 }
547 for (i = vchan->head; i < vchan->head + cmpl; i++) {
549 for (j = 0; j < vchan->mdata[idx].cnt; j++) {
550 if (mem_order)
551 __atomic_store_n(vchan->mdata[idx].ptr[j], vchan->mdata[idx].val[j],
552 __ATOMIC_RELAXED);
553 else
554 *vchan->mdata[idx].ptr[j] = vchan->mdata[idx].val[j];
555 *vchan->mdata[idx].pend_ptr[j] -= vchan->mdata[idx].pend_val[j];
556 }
557 vchan->mdata[idx].cnt = 0;
558 }
559 vchan->head += cmpl;
560}
561
578static __rte_always_inline void
579dao_dma_update_cmpl_meta(struct dao_dma_vchan_state *vchan, uint16_t *ptr, uint16_t val,
580 uint16_t *pend_ptr, uint16_t pend_val, uint16_t tail)
581{
582 uint16_t idx = tail % DAO_DMA_MAX_INFLIGHT_MDATA;
583 uint16_t j = vchan->mdata[idx].cnt;
584
585 vchan->mdata[idx].ptr[j] = ptr;
586 vchan->mdata[idx].val[j] = val;
587 vchan->mdata[idx].pend_ptr[j] = pend_ptr;
588 vchan->mdata[idx].pend_val[j] = pend_val;
589 vchan->mdata[idx].cnt = j + 1;
590}
591
592#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:422
static __rte_always_inline int dao_dma_has_stats_feature(void)
Definition dao_dma.h:234
static __rte_always_inline struct rte_dma_sge * dao_dma_sge_dst(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:346
static __rte_always_inline void dao_dma_check_meta_compl(struct dao_dma_vchan_state *vchan, const int mem_order)
Definition dao_dma.h:536
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:512
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:369
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
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:398
static __rte_always_inline bool dao_dma_flush(struct dao_dma_vchan_state *vchan, const uint8_t avail)
Definition dao_dma.h:277
static __rte_always_inline struct rte_dma_sge * dao_dma_sge_src(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:332
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:579
static __rte_always_inline bool dao_dma_op_status(struct dao_dma_vchan_state *vchan, uint16_t op_idx)
Definition dao_dma.h:255
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:445
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
static __rte_always_inline uint16_t dao_dma_avail(struct dao_dma_vchan_state *vchan)
Definition dao_dma.h:316
uint16_t * ptr[DAO_DMA_MAX_POINTER]
Definition dao_dma.h:45
uint16_t * pend_ptr[DAO_DMA_MAX_POINTER]
Definition dao_dma.h:39
uint16_t val[DAO_DMA_MAX_POINTER]
Definition dao_dma.h:43
uint16_t pend_val[DAO_DMA_MAX_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