https://doc.dpdk.org/
Compilation of the DPDK
(https://doc.dpdk.org/guides/linux_gsg/sys_reqs.html#compilation-of-the-dpdk) 를 참고하실 수 있습니다.
$ apt install build-essential $ apt install meson ninja-build $ apt install python3-pyelftools $ apt install libnuma-dev $ apt install python3-sphinx python3-sphinx-rtd-theme doxygen
$ git clone https://github.com/DPDK/dpdk.git MyDPDK $ cd MyDPDK $ meson setup -D enable_docs=true -D examples=all build $ cd build $ ninja ... $ meson install --destdir "$(HOME)/MyRootFS"
Running DPDK Applications
(https://doc.dpdk.org/guides/linux_gsg/sys_reqs.html#running-dpdk-applications) 를 참고하실 수 있습니다.
Environment Abstraction Layer
(https://doc.dpdk.org/guides/prog_guide/overview.html#environment-abstraction-layer) 를 참고하실 수 있습니다.
int rc;
/* STEP: EAL 초기화 */
/* int rte_eal_init(int argc, char **argv); */
rc = rte_eal_init(argc, argv);
if (unlikely(rc < 0)) {
/* void rte_exit(int exit_code, const char *format, ...); */
rte_exit(EXIT_FAILURE, "ERROR: Invalid EAL parameters (errno=%d[\"%s\"])\n", rte_errno, rte_strerror(rte_errno));
}
/* STEP: EAL 초기화 완료 */
argc -= rc;
argv += rc;
/* STEP: EAL 옵션 이외의 옵션들을 처리 */
/*
STEP: 이제 DPDK의 EAL 세상입니다... 관련 port / queue 등의 구성을 진행합니다.
*/
/* STEP: 이제 lcore 별 실행되는 자신만의 my_lcore_main 함수를 작성하고 Data 를 처리하는 lcore 별 main loop 를 작성합니다. */
/* int rte_eal_mp_remote_launch(lcore_function_t *f, void *arg, enum rte_rmt_call_main_t call_main); */
rc = rte_eal_mp_remote_launch(my_lcore_main /* int my_lcore_main(void *s_argument) */, my_arg, CALL_MAIN /* or SKIP_MAIN */);
if (rc == 0) {
unsigned int lcore_id;
/* 모든 lcore의 main 함수가 종료되기를 기다립니다. */
RTE_LCORE_FOREACH_WORKER(lcore_id) {
/* int rte_eal_wait_lcore(unsigned worker_id); */
rc = rte_eal_wait_lcore(lcore_id);
if (unlikely(rc < 0)) {
RTE_LOG(ERR, EAL, "rte_eal_wait_lcore failed ! (lcore=%u)\n", lcore_id);
break;
}
}
}
/* STEP: EAL 종료 */
/* int rte_eal_cleanup(void); */
rc = rte_eal_cleanup();
if (unlikely(rc != 0)) {
rte_exit(EXIT_FAILURE, "ERROR: There was an error in releasing all resources (errno=%d[\"%s\"])\n", rte_errno, rte_strerror(rte_errno));
}
/* "lib/eal/include/rte_memzone.h" */
#define RTE_MEMZONE_2MB 0x00000001 /**< Use 2MB pages. */
#define RTE_MEMZONE_1GB 0x00000002 /**< Use 1GB pages. */
#define RTE_MEMZONE_16MB 0x00000100 /**< Use 16MB pages. */
#define RTE_MEMZONE_16GB 0x00000200 /**< Use 16GB pages. */
#define RTE_MEMZONE_256KB 0x00010000 /**< Use 256KB pages. */
#define RTE_MEMZONE_256MB 0x00020000 /**< Use 256MB pages. */
#define RTE_MEMZONE_512MB 0x00040000 /**< Use 512MB pages. */
#define RTE_MEMZONE_4GB 0x00080000 /**< Use 4GB pages. */
#define RTE_MEMZONE_SIZE_HINT_ONLY 0x00000004 /**< Use available page size */
#define RTE_MEMZONE_IOVA_CONTIG 0x00100000 /**< Ask for IOVA-contiguous memzone. */
struct rte_memzone {
#define RTE_MEMZONE_NAMESIZE 32 /**< Maximum length of memory zone name.*/
char name[RTE_MEMZONE_NAMESIZE]; /**< Name of the memory zone. */
rte_iova_t iova; /**< Start IO address. */
union {
void *addr; /**< Start virtual address. */
uint64_t addr_64; /**< Makes sure addr is always 64-bits */
};
size_t len; /**< Length of the memzone. */
uint64_t hugepage_sz; /**< The page size of underlying memory */
int32_t socket_id; /**< NUMA socket ID. */
uint32_t flags; /**< Characteristics of this memzone. */
} __rte_packed;
/* 최대 memzone 영역 설정 또는 확인 */
int rte_memzone_max_set(size_t max);
size_t rte_memzone_max_get(void);
/* memzone 할당 및 해제 */
const struct rte_memzone *rte_memzone_reserve(const char *name, size_t len, int socket_id, unsigned flags);
const struct rte_memzone *rte_memzone_reserve_aligned(const char *name, size_t len, int socket_id, unsigned flags, unsigned align);
const struct rte_memzone *rte_memzone_reserve_bounded(const char *name, size_t len, int socket_id, unsigned flags, unsigned align, unsigned bound);
int rte_memzone_free(const struct rte_memzone *mz);
/* 이미 생성된 memzone 을 이름으로 찾기 */
const struct rte_memzone *rte_memzone_lookup(const char *name);
/* memzone 상황 dump */
void rte_memzone_dump(FILE *f);
/* 전체 memzone 들 순회 */
void rte_memzone_walk(void (*func)(const struct rte_memzone *, void *arg), void *arg);
/* "lib/mempool/rte_mempool.h" */
struct __rte_cache_aligned rte_mempool {
char name[RTE_MEMPOOL_NAMESIZE]; /**< Name of mempool. */
union {
void *pool_data; /**< Ring or pool to store objects. */
uint64_t pool_id; /**< External mempool identifier. */
};
void *pool_config; /**< optional args for ops alloc. */
const struct rte_memzone *mz; /**< Memzone where pool is alloc'd. */
unsigned int flags; /**< Flags of the mempool. */
int socket_id; /**< Socket id passed at create. */
uint32_t size; /**< Max size of the mempool. */
uint32_t cache_size;
/**< Size of per-lcore default local cache. */
uint32_t elt_size; /**< Size of an element. */
uint32_t header_size; /**< Size of header (before elt). */
uint32_t trailer_size; /**< Size of trailer (after elt). */
unsigned private_data_size; /**< Size of private data. */
/**
* Index into rte_mempool_ops_table array of mempool ops
* structs, which contain callback function pointers.
* We're using an index here rather than pointers to the callbacks
* to facilitate any secondary processes that may want to use
* this mempool.
*/
int32_t ops_index;
struct rte_mempool_cache *local_cache; /**< Per-lcore local cache */
uint32_t populated_size; /**< Number of populated objects. */
struct rte_mempool_objhdr_list elt_list; /**< List of objects in pool */
uint32_t nb_mem_chunks; /**< Number of memory chunks */
struct rte_mempool_memhdr_list mem_list; /**< List of memory chunks */
#ifdef RTE_LIBRTE_MEMPOOL_STATS
/** Per-lcore statistics.
*
* Plus one, for unregistered non-EAL threads.
*/
struct rte_mempool_debug_stats stats[RTE_MAX_LCORE + 1];
#endif
};
typedef void (rte_mempool_obj_cb_t)(struct rte_mempool *mp, void *opaque, void *obj, unsigned obj_idx);
typedef void (rte_mempool_ctor_t)(struct rte_mempool *, void *);
/* mempool 생성/제거 */
struct rte_mempool *rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size, unsigned cache_size, unsigned private_data_size, int socket_id, unsigned flags);
struct rte_mempool *rte_mempool_create(const char *name, unsigned n, unsigned elt_size, unsigned cache_size, unsigned private_data_size, rte_mempool_ctor_t *mp_init, void *mp_init_arg, rte_mempool_obj_cb_t *obj_init, void *obj_init_arg, int socket_id, unsigned flags);
void rte_mempool_free(struct rte_mempool *mp);
int rte_mempool_populate_default(struct rte_mempool *mp);
/* mempool object 들에 대하여 호출 */
uint32_t rte_mempool_obj_iter(struct rte_mempool *mp, rte_mempool_obj_cb_t *obj_cb, void *obj_cb_arg);
/* 주어진 이름 또는 object로부터 mempool을 반환 */
struct rte_mempool *rte_mempool_lookup(const char *name);
static inline struct rte_mempool *rte_mempool_from_obj(void *obj);
/* mempool의 할당 상황 */
unsigned int rte_mempool_avail_count(const struct rte_mempool *mp);
unsigned int rte_mempool_in_use_count(const struct rte_mempool *mp);
static inline int rte_mempool_full(const struct rte_mempool *mp);
static inline int rte_mempool_empty(const struct rte_mempool *mp);
/* 주어진 n개만큼의 object를 할당 및 해제 */
static __rte_always_inline int rte_mempool_get_bulk(struct rte_mempool *mp, void **obj_table, unsigned int n);
static __rte_always_inline void rte_mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table, unsigned int n);
/* 한개의 object를 할당 및 해제 */
static __rte_always_inline int rte_mempool_get(struct rte_mempool *mp, void **obj_p);
static __rte_always_inline void rte_mempool_put(struct rte_mempool *mp, void *obj);
/* 모든 mempool 을 순회하면서 호출 */
void rte_mempool_walk(void (*func)(struct rte_mempool *, void *arg), void *arg);
/* "lib/ring/rte_ring_core.h" */
enum rte_ring_queue_behavior {
RTE_RING_QUEUE_FIXED = 0,
RTE_RING_QUEUE_VARIABLE
};
#define RTE_RING_MZ_PREFIX "RG_"
#define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - sizeof(RTE_RING_MZ_PREFIX) + 1)
enum rte_ring_sync_type {
RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
RTE_RING_SYNC_ST, /**< single thread only */
RTE_RING_SYNC_MT_RTS, /**< multi-thread relaxed tail sync */
RTE_RING_SYNC_MT_HTS, /**< multi-thread head/tail sync */
};
...
struct rte_ring {
alignas(RTE_CACHE_LINE_SIZE) char name[RTE_RING_NAMESIZE];
int flags; /**< Flags supplied at creation. */
const struct rte_memzone *memzone; /**< Memzone, if any, containing the rte_ring */
uint32_t size; /**< Size of ring. */
uint32_t mask; /**< Mask (size-1) of ring. */
uint32_t capacity; /**< Usable size of ring */
RTE_CACHE_GUARD;
/** Ring producer status. */
union __rte_cache_aligned {
struct rte_ring_headtail prod;
struct rte_ring_hts_headtail hts_prod;
struct rte_ring_rts_headtail rts_prod;
};
RTE_CACHE_GUARD;
/** Ring consumer status. */
union __rte_cache_aligned {
struct rte_ring_headtail cons;
struct rte_ring_hts_headtail hts_cons;
struct rte_ring_rts_headtail rts_cons;
};
RTE_CACHE_GUARD;
};
#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
#define RING_F_EXACT_SZ 0x0004
#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
#define RING_F_MP_RTS_ENQ 0x0008 /**< The default enqueue is "MP RTS". */
#define RING_F_MC_RTS_DEQ 0x0010 /**< The default dequeue is "MC RTS". */
#define RING_F_MP_HTS_ENQ 0x0020 /**< The default enqueue is "MP HTS". */
#define RING_F_MC_HTS_DEQ 0x0040 /**< The default dequeue is "MC HTS". */
/* "lib/ring/rte_ring.h" */
ssize_t rte_ring_get_memsize(unsigned int count);
int rte_ring_init(struct rte_ring *r, const char *name, unsigned int count, unsigned int flags);
struct rte_ring *rte_ring_create(const char *name, unsigned int count, int socket_id, unsigned int flags);
void rte_ring_free(struct rte_ring *r);
void rte_ring_dump(FILE *f, const struct rte_ring *r);
static __rte_always_inline unsigned int rte_ring_mp_enqueue_bulk(struct rte_ring *r, void * const *obj_table, unsigned int n, unsigned int *free_space)
static __rte_always_inline unsigned int rte_ring_sp_enqueue_bulk(struct rte_ring *r, void * const *obj_table, unsigned int n, unsigned int *free_space)
static __rte_always_inline unsigned int rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table, unsigned int n, unsigned int *free_space)
static __rte_always_inline int rte_ring_mp_enqueue(struct rte_ring *r, void *obj)
static __rte_always_inline int rte_ring_sp_enqueue(struct rte_ring *r, void *obj)
static __rte_always_inline unsigned int rte_ring_mc_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n, unsigned int *available)
static __rte_always_inline unsigned int rte_ring_sc_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n, unsigned int *available)
static __rte_always_inline unsigned int rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n, unsigned int *available)
static __rte_always_inline int rte_ring_mc_dequeue(struct rte_ring *r, void **obj_p)
static __rte_always_inline int rte_ring_sc_dequeue(struct rte_ring *r, void **obj_p)
static __rte_always_inline int rte_ring_dequeue(struct rte_ring *r, void **obj_p)
void rte_ring_reset(struct rte_ring *r);
static inline unsigned int rte_ring_count(const struct rte_ring *r)
static inline unsigned int rte_ring_free_count(const struct rte_ring *r)
static inline int rte_ring_full(const struct rte_ring *r)
static inline int rte_ring_empty(const struct rte_ring *r)
static inline unsigned int rte_ring_get_size(const struct rte_ring *r)
static inline unsigned int rte_ring_get_capacity(const struct rte_ring *r)
static inline enum rte_ring_sync_type rte_ring_get_prod_sync_type(const struct rte_ring *r)
static inline int rte_ring_is_prod_single(const struct rte_ring *r)
static inline enum rte_ring_sync_type rte_ring_get_cons_sync_type(const struct rte_ring *r)
static inline int rte_ring_is_cons_single(const struct rte_ring *r)
void rte_ring_list_dump(FILE *f);
struct rte_ring *rte_ring_lookup(const char *name);
static __rte_always_inline unsigned int rte_ring_mp_enqueue_burst(struct rte_ring *r, void * const *obj_table, unsigned int n, unsigned int *free_space)
static __rte_always_inline unsigned int rte_ring_sp_enqueue_burst(struct rte_ring *r, void * const *obj_table, unsigned int n, unsigned int *free_space)
static __rte_always_inline unsigned int rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table, unsigned int n, unsigned int *free_space)
static __rte_always_inline unsigned int rte_ring_mc_dequeue_burst(struct rte_ring *r, void **obj_table, unsigned int n, unsigned int *available)
static __rte_always_inline unsigned int rte_ring_sc_dequeue_burst(struct rte_ring *r, void **obj_table, unsigned int n, unsigned int *available)
static __rte_always_inline unsigned int rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table, unsigned int n, unsigned int *available)
https://doc.dpdk.org/
The DPDK uses the Open Source BSD-3-Clause license for the core libraries and drivers. The kernel components are GPL-2.0 licensed. ... 상세한 내용은 DPDK source 의 license 디렉토리에서 README를 참고 ...
Getting Started Guide for Linux
(https://doc.dpdk.org/guides/linux_gsg/)
Compilation of the DPDK
(https://doc.dpdk.org/guides/linux_gsg/sys_reqs.html#compilation-of-the-dpdk)
Running DPDK Applications
(https://doc.dpdk.org/guides/linux_gsg/sys_reqs.html#running-dpdk-applications)
Compiling the DPDK Target from Source
(https://doc.dpdk.org/guides/linux_gsg/build_dpdk.html)
Programmer’s Guide
(https://doc.dpdk.org/guides/prog_guide/)
API Documentation
(https://doc.dpdk.org/api/)
Supported Hardware
(https://core.dpdk.org/supported/)
DPDK 23.11 Download
(https://fast.dpdk.org/rel/dpdk-23.11.tar.xz)
DPDK repositories (git.dpdk.org)
(https://git.dpdk.org/)
$ git clone https://dpdk.org/git/dpdk
DPDK - Github
(https://github.com/DPDK)
$ git clone https://github.com/DPDK/dpdk.git
https://elixir.bootlin.com/dpdk/latest/source
DPDK Project - YouTube
(https://www.youtube.com/@dpdkproject)
Data Plane Development Kit - WIKIPEDIA
(https://en.wikipedia.org/wiki/Data_Plane_Development_Kit)
Intel DPDK - 나무위키
(https://namu.wiki/w/Intel%20DPDK)
NVIDIA BlueField Networking Platform - NVIDIA
(https://www.nvidia.com/en-us/networking/products/data-processing-unit/)
Achieve fast packet processing and low latency with NVIDIA Poll Mode Driver (PMD) in DPDK
(https://developer.nvidia.com/networking/dpdk)
Data Processing Units (DPU) - MARVELL PRODUCTS
(https://www.marvell.com/products/data-processing-units.html)
The Fast Data Project (FD.io), Vector Packet Processing (VPP)
(https://fd.io/)
DPDK로 더 빠른 네트워크 패킷 처리 사용 설정 - Google Cloud
(https://cloud.google.com/compute/docs/networking/use-dpdk)
DPDK와 FD.io VPP로 고성능 Security Gateway 만들기
(https://slowbootkernelhacks.blogspot.com/2020/10/dpdk-fdio-vpp-security-gateway.html)
MinimalDPDKExamples - NEOAdvancedTechnology
(https://github.com/NEOAdvancedTechnology/MinimalDPDKExamples/)
| 참고 영상 |
| 참고 영상 |
| 참고 영상 |
| 참고 영상 |
| 참고 영상 |