From 78c896b3b3127515478090c19447e27dc406427e Mon Sep 17 00:00:00 2001 From: Jianfeng Tan Date: Mon, 18 Nov 2019 06:59:50 +0000 Subject: TLDKv2 Signed-off-by: Jianfeng Tan Signed-off-by: Jielong Zhou Signed-off-by: Jian Zhang Signed-off-by: Chen Zhao Change-Id: I55c39de4c6cd30f991f35631eb507f770230f08e --- ...1-eal-don-t-start-the-interrupt-mp-thread.patch | 35 ++ .../0002-eal-prioritize-constructor.patch | 25 + .../0003-mbuf-add-single-linked-list.patch | 33 ++ ...irtio-user-add-rss-update-for-virtio-user.patch | 43 ++ ...virtio-user-support-raw-socket-as-backend.patch | 645 +++++++++++++++++++++ .../0006-mempool-add-dynamic-mempool-support.patch | 247 ++++++++ ...007-mbuf-add-dynamic-mbuf-mempool-support.patch | 305 ++++++++++ .../0008-mempool-prioritize-constructor.patch | 30 + .../0009-net-virtio-fill-desc-limit.patch | 42 ++ 9 files changed, 1405 insertions(+) create mode 100644 dpdk/dpdk-v18.11_patches/0001-eal-don-t-start-the-interrupt-mp-thread.patch create mode 100644 dpdk/dpdk-v18.11_patches/0002-eal-prioritize-constructor.patch create mode 100644 dpdk/dpdk-v18.11_patches/0003-mbuf-add-single-linked-list.patch create mode 100644 dpdk/dpdk-v18.11_patches/0004-net-virtio-user-add-rss-update-for-virtio-user.patch create mode 100644 dpdk/dpdk-v18.11_patches/0005-net-virtio-user-support-raw-socket-as-backend.patch create mode 100644 dpdk/dpdk-v18.11_patches/0006-mempool-add-dynamic-mempool-support.patch create mode 100644 dpdk/dpdk-v18.11_patches/0007-mbuf-add-dynamic-mbuf-mempool-support.patch create mode 100644 dpdk/dpdk-v18.11_patches/0008-mempool-prioritize-constructor.patch create mode 100644 dpdk/dpdk-v18.11_patches/0009-net-virtio-fill-desc-limit.patch (limited to 'dpdk/dpdk-v18.11_patches') diff --git a/dpdk/dpdk-v18.11_patches/0001-eal-don-t-start-the-interrupt-mp-thread.patch b/dpdk/dpdk-v18.11_patches/0001-eal-don-t-start-the-interrupt-mp-thread.patch new file mode 100644 index 0000000..770bf05 --- /dev/null +++ b/dpdk/dpdk-v18.11_patches/0001-eal-don-t-start-the-interrupt-mp-thread.patch @@ -0,0 +1,35 @@ +From f68558b0ccbddb4cc81aca36befa0a7730ee051c Mon Sep 17 00:00:00 2001 +From: Jianfeng Tan +Date: Wed, 29 Aug 2018 14:24:01 +0000 +Subject: [PATCH 7/9] eal: don't start the interrupt mp thread + +--- + lib/librte_eal/common/eal_common_proc.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c +index 9fcb91219..79d9e6bbe 100644 +--- a/lib/librte_eal/common/eal_common_proc.c ++++ b/lib/librte_eal/common/eal_common_proc.c +@@ -615,6 +615,7 @@ rte_mp_channel_init(void) + return -1; + } + ++#if 0 + if (rte_ctrl_thread_create(&mp_handle_tid, "rte_mp_handle", + NULL, mp_handle, NULL) < 0) { + RTE_LOG(ERR, EAL, "failed to create mp thead: %s\n", +@@ -624,6 +625,10 @@ rte_mp_channel_init(void) + mp_fd = -1; + return -1; + } ++#else ++ RTE_SET_USED(mp_handle); ++ RTE_SET_USED(mp_handle_tid); ++#endif + + /* unlock the directory */ + flock(dir_fd, LOCK_UN); +-- +2.17.1 + diff --git a/dpdk/dpdk-v18.11_patches/0002-eal-prioritize-constructor.patch b/dpdk/dpdk-v18.11_patches/0002-eal-prioritize-constructor.patch new file mode 100644 index 0000000..9d2959f --- /dev/null +++ b/dpdk/dpdk-v18.11_patches/0002-eal-prioritize-constructor.patch @@ -0,0 +1,25 @@ +From 7fe32567994a8ce782fa8406613bade1d2100dca Mon Sep 17 00:00:00 2001 +From: Jianfeng Tan +Date: Wed, 29 Aug 2018 14:14:09 +0000 +Subject: [PATCH 2/9] eal: prioritize constructor + +--- + lib/librte_eal/common/include/rte_common.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h +index 069c13ec7..a635f5be4 100644 +--- a/lib/librte_eal/common/include/rte_common.h ++++ b/lib/librte_eal/common/include/rte_common.h +@@ -84,7 +84,7 @@ typedef uint16_t unaligned_uint16_t; + #define RTE_PRIORITY_LOG 101 + #define RTE_PRIORITY_BUS 110 + #define RTE_PRIORITY_CLASS 120 +-#define RTE_PRIORITY_LAST 65535 ++#define RTE_PRIORITY_LAST 130 + + #define RTE_PRIO(prio) \ + RTE_PRIORITY_ ## prio +-- +2.17.1 + diff --git a/dpdk/dpdk-v18.11_patches/0003-mbuf-add-single-linked-list.patch b/dpdk/dpdk-v18.11_patches/0003-mbuf-add-single-linked-list.patch new file mode 100644 index 0000000..7430d1e --- /dev/null +++ b/dpdk/dpdk-v18.11_patches/0003-mbuf-add-single-linked-list.patch @@ -0,0 +1,33 @@ +From 1416ff5de58922dc32eb2fb9ce2b9b970282136c Mon Sep 17 00:00:00 2001 +From: Jianfeng Tan +Date: Wed, 29 Aug 2018 14:18:13 +0000 +Subject: [PATCH 3/9] mbuf: add single linked list + +--- + lib/librte_mbuf/rte_mbuf.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h +index 9ce5d76d7..0081bd6d7 100644 +--- a/lib/librte_mbuf/rte_mbuf.h ++++ b/lib/librte_mbuf/rte_mbuf.h +@@ -593,6 +593,8 @@ struct rte_mbuf { + */ + struct rte_mbuf_ext_shared_info *shinfo; + ++ struct rte_mbuf *next_pkt; ++ + } __rte_cache_aligned; + + /** +@@ -1237,6 +1239,7 @@ static inline void rte_pktmbuf_reset_headroom(struct rte_mbuf *m) + static inline void rte_pktmbuf_reset(struct rte_mbuf *m) + { + m->next = NULL; ++ m->next_pkt = NULL; + m->pkt_len = 0; + m->tx_offload = 0; + m->vlan_tci = 0; +-- +2.17.1 + diff --git a/dpdk/dpdk-v18.11_patches/0004-net-virtio-user-add-rss-update-for-virtio-user.patch b/dpdk/dpdk-v18.11_patches/0004-net-virtio-user-add-rss-update-for-virtio-user.patch new file mode 100644 index 0000000..e4eb8e7 --- /dev/null +++ b/dpdk/dpdk-v18.11_patches/0004-net-virtio-user-add-rss-update-for-virtio-user.patch @@ -0,0 +1,43 @@ +From 9bbe20eda858fd7fcbd8f137e5f96f51d571a556 Mon Sep 17 00:00:00 2001 +From: Jianfeng Tan +Date: Wed, 29 Aug 2018 14:20:51 +0000 +Subject: [PATCH 4/9] net/virtio-user: add rss update for virtio-user + +--- + drivers/net/virtio/virtio_ethdev.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c +index 614357da7..e7336cde9 100644 +--- a/drivers/net/virtio/virtio_ethdev.c ++++ b/drivers/net/virtio/virtio_ethdev.c +@@ -738,6 +738,18 @@ virtio_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id) + return 0; + } + ++static int ++virtio_rss_hash_update(struct rte_eth_dev *dev, ++ struct rte_eth_rss_conf *rss_conf __rte_unused) ++{ ++ struct virtio_hw *hw = dev->data->dev_private; ++ ++ if (hw->virtio_user_dev) ++ return 0; ++ ++ return -1; ++} ++ + /* + * dev_ops for virtio, bare necessities for basic operation + */ +@@ -772,6 +784,7 @@ static const struct eth_dev_ops virtio_eth_dev_ops = { + .mac_addr_add = virtio_mac_addr_add, + .mac_addr_remove = virtio_mac_addr_remove, + .mac_addr_set = virtio_mac_addr_set, ++ .rss_hash_update = virtio_rss_hash_update, + }; + + static void +-- +2.17.1 + diff --git a/dpdk/dpdk-v18.11_patches/0005-net-virtio-user-support-raw-socket-as-backend.patch b/dpdk/dpdk-v18.11_patches/0005-net-virtio-user-support-raw-socket-as-backend.patch new file mode 100644 index 0000000..1d950c5 --- /dev/null +++ b/dpdk/dpdk-v18.11_patches/0005-net-virtio-user-support-raw-socket-as-backend.patch @@ -0,0 +1,645 @@ +From 307f7debe0f2143e70659b7a082537077b20d185 Mon Sep 17 00:00:00 2001 +From: Jianfeng Tan +Date: Thu, 19 Jul 2018 11:25:22 +0000 +Subject: [PATCH] net/virtio-user: support raw socket as backend + +We will support tapfd or raw socket fd opened by application and +passed into virtio-user for initialization. + +Note if there are multiple queue pairs, users are still supposed +to pass down the iface name with the first queue pair fd passed +through this parameter. + +Signed-off-by: Jianfeng Tan +--- + drivers/net/virtio/Makefile | 1 + + drivers/net/virtio/virtio_user/vhost_kernel.c | 78 ++++++--- + drivers/net/virtio/virtio_user/vhost_kernel.h | 15 ++ + .../virtio/virtio_user/vhost_kernel_sock.c | 156 ++++++++++++++++++ + .../net/virtio/virtio_user/vhost_kernel_tap.c | 64 ++++++- + .../net/virtio/virtio_user/vhost_kernel_tap.h | 39 ----- + .../net/virtio/virtio_user/virtio_user_dev.c | 16 +- + .../net/virtio/virtio_user/virtio_user_dev.h | 3 +- + drivers/net/virtio/virtio_user_ethdev.c | 20 ++- + 9 files changed, 318 insertions(+), 74 deletions(-) + create mode 100644 drivers/net/virtio/virtio_user/vhost_kernel.h + create mode 100644 drivers/net/virtio/virtio_user/vhost_kernel_sock.c + delete mode 100644 drivers/net/virtio/virtio_user/vhost_kernel_tap.h + +diff --git a/drivers/net/virtio/Makefile b/drivers/net/virtio/Makefile +index 6c2c9967b..2e1fc9b5e 100644 +--- a/drivers/net/virtio/Makefile ++++ b/drivers/net/virtio/Makefile +@@ -41,6 +41,7 @@ ifeq ($(CONFIG_RTE_VIRTIO_USER),y) + SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_user/vhost_user.c + SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_user/vhost_kernel.c + SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_user/vhost_kernel_tap.c ++SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_user/vhost_kernel_sock.c + SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_user/virtio_user_dev.c + SRCS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio_user_ethdev.c + endif +diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.c b/drivers/net/virtio/virtio_user/vhost_kernel.c +index 6b19180d7..fa84287f5 100644 +--- a/drivers/net/virtio/virtio_user/vhost_kernel.c ++++ b/drivers/net/virtio/virtio_user/vhost_kernel.c +@@ -6,13 +6,14 @@ + #include + #include + #include ++#include + + #include + #include + + #include "vhost.h" + #include "virtio_user_dev.h" +-#include "vhost_kernel_tap.h" ++#include "vhost_kernel.h" + + struct vhost_memory_kernel { + uint32_t nregions; +@@ -152,27 +153,25 @@ prepare_vhost_memory_kernel(void) + (1ULL << VIRTIO_NET_F_HOST_TSO6) | \ + (1ULL << VIRTIO_NET_F_CSUM)) + +-static unsigned int +-tap_support_features(void) ++#define PATH_SYS_CLASS_NET "/sys/class/net" ++ ++static int ++vhost_kernel_is_tap(struct virtio_user_dev *dev) + { +- int tapfd; +- unsigned int tap_features; ++ char path[128]; + +- tapfd = open(PATH_NET_TUN, O_RDWR); +- if (tapfd < 0) { +- PMD_DRV_LOG(ERR, "fail to open %s: %s", +- PATH_NET_TUN, strerror(errno)); +- return -1; +- } ++ if (dev->ifname == NULL) ++ return 0; + +- if (ioctl(tapfd, TUNGETFEATURES, &tap_features) == -1) { +- PMD_DRV_LOG(ERR, "TUNGETFEATURES failed: %s", strerror(errno)); +- close(tapfd); +- return -1; +- } ++ snprintf(path, 128, PATH_SYS_CLASS_NET"/%s", dev->ifname); ++ if(access(path, F_OK) == -1) ++ return 1; + +- close(tapfd); +- return tap_features; ++ snprintf(path, 128, PATH_SYS_CLASS_NET"/%s/tun_flags", dev->ifname); ++ if(access(path, F_OK) != -1) ++ return 1; ++ ++ return 0; + } + + static int +@@ -186,7 +185,6 @@ vhost_kernel_ioctl(struct virtio_user_dev *dev, + struct vhost_memory_kernel *vm = NULL; + int vhostfd; + unsigned int queue_sel; +- unsigned int features; + + PMD_DRV_LOG(INFO, "%s", vhost_msg_strings[req]); + +@@ -240,21 +238,36 @@ vhost_kernel_ioctl(struct virtio_user_dev *dev, + } + + if (!ret && req_kernel == VHOST_GET_FEATURES) { +- features = tap_support_features(); +- /* with tap as the backend, all these features are supported ++ int vnet_hdr, mq; ++ ++ if (vhost_kernel_is_tap(dev)) ++ tap_support_features(&vnet_hdr, &mq); ++ else ++ sock_support_features(dev->be_fd, &vnet_hdr, &mq); ++ ++ /* with kernel vhost, all these features are supported + * but not claimed by vhost-net, so we add them back when + * reporting to upper layer. + */ +- if (features & IFF_VNET_HDR) { ++ if (vnet_hdr) { + *((uint64_t *)arg) |= VHOST_KERNEL_GUEST_OFFLOADS_MASK; + *((uint64_t *)arg) |= VHOST_KERNEL_HOST_OFFLOADS_MASK; + } + +- /* vhost_kernel will not declare this feature, but it does ++ /* kernel vhost will not declare this feature, but it does + * support multi-queue. + */ +- if (features & IFF_MULTI_QUEUE) ++ if (mq) + *(uint64_t *)arg |= (1ull << VIRTIO_NET_F_MQ); ++ ++ /* raw socket only supports vnet header size of 10, so we must ++ * eliminate below features. ++ */ ++ if (!vhost_kernel_is_tap(dev) && ++ vnet_hdr == sizeof(struct virtio_net_hdr)) { ++ *((uint64_t *)arg) &= ~(1ull << VIRTIO_NET_F_MRG_RXBUF); ++ *((uint64_t *)arg) &= ~(1ull << VIRTIO_F_VERSION_1); ++ } + } + + if (vm) +@@ -333,7 +346,8 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev, + + if (!enable) { + if (dev->tapfds[pair_idx] >= 0) { +- close(dev->tapfds[pair_idx]); ++ if (dev->be_fd < 0) ++ close(dev->tapfds[pair_idx]); + dev->tapfds[pair_idx] = -1; + } + return vhost_kernel_set_backend(vhostfd, -1); +@@ -347,8 +361,18 @@ vhost_kernel_enable_queue_pair(struct virtio_user_dev *dev, + else + hdr_size = sizeof(struct virtio_net_hdr); + +- tapfd = vhost_kernel_open_tap(&dev->ifname, hdr_size, req_mq, +- (char *)dev->mac_addr, dev->features); ++ if (vhost_kernel_is_tap(dev)) { ++ tapfd = vhost_kernel_open_tap(&dev->ifname, hdr_size, ++ req_mq, (char *)dev->mac_addr, dev->features); ++ } else { ++ if (pair_idx == 0 && dev->be_fd >= 0) ++ tapfd = vhost_kernel_set_sock(dev->be_fd, ++ hdr_size, req_mq); ++ else ++ tapfd = vhost_kernel_open_sock(dev->ifname, ++ hdr_size, dev->mac_addr, req_mq); ++ } ++ + if (tapfd < 0) { + PMD_DRV_LOG(ERR, "fail to open tap for vhost kernel"); + return -1; +diff --git a/drivers/net/virtio/virtio_user/vhost_kernel.h b/drivers/net/virtio/virtio_user/vhost_kernel.h +new file mode 100644 +index 000000000..75d6c5bf6 +--- /dev/null ++++ b/drivers/net/virtio/virtio_user/vhost_kernel.h +@@ -0,0 +1,15 @@ ++/* SPDX-License-Identifier: BSD-3-Clause ++ * Copyright(c) 2016 Intel Corporation ++ */ ++ ++int vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq, ++ const char *mac, uint64_t features); ++ ++void tap_support_features(int *vnet_hdr, int *mq); ++ ++int vhost_kernel_open_sock(char *ifname, int hdr_size, ++ uint8_t *mac, int req_mq); ++ ++int vhost_kernel_set_sock(int sockfd, int hdr_size, int req_mq); ++ ++void sock_support_features(int fd, int *vnet_hdr, int *mq); +diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_sock.c b/drivers/net/virtio/virtio_user/vhost_kernel_sock.c +new file mode 100644 +index 000000000..7c2ace294 +--- /dev/null ++++ b/drivers/net/virtio/virtio_user/vhost_kernel_sock.c +@@ -0,0 +1,156 @@ ++/* SPDX-License-Identifier: BSD-3-Clause ++ * Copyright(c) 2018 Alibaba Group ++ * Copyright(c) 2018 Ant Financial Services Group ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "../virtqueue.h" ++#include "../virtio_logs.h" ++#include "vhost_kernel.h" ++ ++#ifndef PACKET_VNET_HDR ++#define PACKET_VNET_HDR 15 ++#endif ++ ++#ifndef PACKET_FANOUT ++#define PACKET_FANOUT 18 ++#endif ++ ++#ifndef PACKET_VNET_HDR_SZ ++#define PACKET_VNET_HDR_SZ 128 ++#endif ++ ++void ++sock_support_features(int fd, int *vnet_hdr, int *mq) ++{ ++ int hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf); ++ int local_fd = 0; ++ ++ if (fd < 0) { ++ fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); ++ if (fd < 0) { ++ *mq = 0; ++ *vnet_hdr = 0; ++ return; ++ } ++ local_fd = 1; ++ } ++ ++ *mq = 1; ++ ++ if (setsockopt(fd, SOL_PACKET, PACKET_VNET_HDR_SZ, ++ (void *)&hdr_size, sizeof(hdr_size))) { ++ *vnet_hdr = sizeof(struct virtio_net_hdr); ++ } else ++ *vnet_hdr = hdr_size; ++ ++ if (local_fd) ++ close(fd); ++} ++ ++int ++vhost_kernel_set_sock(int sockfd, int hdr_size, int req_mq) ++{ ++ int ret; ++ int fanout_type = 0; /* PACKET_FANOUT_HASH */ ++ ++ if (hdr_size == sizeof(struct virtio_net_hdr)) ++ ret = setsockopt(sockfd, SOL_PACKET, PACKET_VNET_HDR, ++ (void *)&hdr_size, sizeof(hdr_size)); ++ else ++ ret = setsockopt(sockfd, SOL_PACKET, PACKET_VNET_HDR_SZ, ++ (void *)&hdr_size, sizeof(hdr_size)); ++ if (ret) { ++ PMD_DRV_LOG(ERR, "failed to set vnet hdr (%d): %s", ++ hdr_size, strerror(errno)); ++ close(sockfd); ++ return -1; ++ } ++ ++ if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK)) ++ { ++ PMD_DRV_LOG(ERR, "fcntl O_NONBLOCK failed! %s", ++ strerror(errno)); ++ close(sockfd); ++ return -1; ++ } ++ ++ if (req_mq) { ++ if (setsockopt(sockfd, SOL_PACKET, PACKET_FANOUT, ++ (void *)&fanout_type, sizeof(fanout_type))) { ++ PMD_DRV_LOG(ERR, "PACKET_FANOUT failed! %s", ++ strerror(errno)); ++ close(sockfd); ++ return -1; ++ } ++ } ++ ++ return sockfd; ++} ++ ++int ++vhost_kernel_open_sock(char *ifname, int hdr_size, ++ uint8_t *mac, int req_mq) ++{ ++ int sockfd; ++ struct ifreq ifr; ++ struct sockaddr_ll addr_ll; ++ ++ sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); ++ if (sockfd < 0) { ++ PMD_DRV_LOG(ERR, "socket failed: %s", strerror(errno)); ++ return -1; ++ } ++ ++ memset(&ifr, 0, sizeof(ifr)); ++ strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1); ++ ++ if (ioctl(sockfd, SIOCGIFINDEX, (void*)&ifr)) { ++ PMD_DRV_LOG(ERR, "SIOCGIFINDEX failed: %s", strerror(errno)); ++ close(sockfd); ++ return -1; ++ } ++ ++ memset(&addr_ll, 0, sizeof(addr_ll)); ++ addr_ll.sll_ifindex = ifr.ifr_ifindex; ++ addr_ll.sll_family = AF_PACKET; ++ addr_ll.sll_protocol = htons(ETH_P_ALL); ++ addr_ll.sll_hatype = 0; ++ //addr_ll.sll_pkttype = PACKET_HOST; ++ //addr_ll.sll_halen = ETH_ALEN; ++ if (bind(sockfd, (struct sockaddr*)&addr_ll, sizeof(addr_ll))) { ++ PMD_DRV_LOG(ERR, "bind failed: %s", strerror(errno)); ++ close(sockfd); ++ return -1; ++ } ++ ++ ifr.ifr_flags |= IFF_PROMISC | IFF_UP; ++ ++ if (ioctl(sockfd, SIOCSIFFLAGS, (char*)&ifr)) { ++ PMD_DRV_LOG(ERR, "SIOCSIFFLAGS failed: %s", strerror(errno)); ++ close(sockfd); ++ return -1; ++ } ++ ++ ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; ++ if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) == 0) ++ memcpy(mac, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); ++ ++ return vhost_kernel_set_sock(sockfd, hdr_size, req_mq); ++} +diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c +index a3faf1d0c..85dd24dd6 100644 +--- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.c ++++ b/drivers/net/virtio/virtio_user/vhost_kernel_tap.c +@@ -11,13 +11,75 @@ + #include + #include + #include ++#include + + #include + +-#include "vhost_kernel_tap.h" ++#include "vhost_kernel.h" + #include "../virtio_logs.h" + #include "../virtio_pci.h" + ++/* TUN ioctls */ ++#define TUNSETIFF _IOW('T', 202, int) ++#define TUNGETFEATURES _IOR('T', 207, unsigned int) ++#define TUNSETOFFLOAD _IOW('T', 208, unsigned int) ++#define TUNGETIFF _IOR('T', 210, unsigned int) ++#define TUNSETSNDBUF _IOW('T', 212, int) ++#define TUNGETVNETHDRSZ _IOR('T', 215, int) ++#define TUNSETVNETHDRSZ _IOW('T', 216, int) ++#define TUNSETQUEUE _IOW('T', 217, int) ++#define TUNSETVNETLE _IOW('T', 220, int) ++#define TUNSETVNETBE _IOW('T', 222, int) ++ ++/* TUNSETIFF ifr flags */ ++#define IFF_TAP 0x0002 ++#define IFF_NO_PI 0x1000 ++#define IFF_ONE_QUEUE 0x2000 ++#define IFF_VNET_HDR 0x4000 ++#define IFF_MULTI_QUEUE 0x0100 ++#define IFF_ATTACH_QUEUE 0x0200 ++#define IFF_DETACH_QUEUE 0x0400 ++ ++/* Features for GSO (TUNSETOFFLOAD). */ ++#define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */ ++#define TUN_F_TSO4 0x02 /* I can handle TSO for IPv4 packets */ ++#define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */ ++#define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */ ++#define TUN_F_UFO 0x10 /* I can handle UFO packets */ ++ ++/* Constants */ ++#define PATH_NET_TUN "/dev/net/tun" ++ ++void ++tap_support_features(int *vnet_hdr, int *mq) ++{ ++ int tapfd; ++ unsigned int tap_features; ++ ++ *vnet_hdr = 0; ++ *mq = 0; ++ ++ tapfd = open(PATH_NET_TUN, O_RDWR); ++ if (tapfd < 0) { ++ PMD_DRV_LOG(ERR, "fail to open %s: %s", ++ PATH_NET_TUN, strerror(errno)); ++ return; ++ } ++ ++ if (ioctl(tapfd, TUNGETFEATURES, &tap_features) == -1) { ++ PMD_DRV_LOG(ERR, "TUNGETFEATURES failed: %s", strerror(errno)); ++ close(tapfd); ++ return; ++ } ++ ++ close(tapfd); ++ ++ if (tap_features & IFF_VNET_HDR) ++ *vnet_hdr = 1; ++ if (tap_features & IFF_MULTI_QUEUE) ++ *mq = 1; ++} ++ + static int + vhost_kernel_tap_set_offload(int fd, uint64_t features) + { +diff --git a/drivers/net/virtio/virtio_user/vhost_kernel_tap.h b/drivers/net/virtio/virtio_user/vhost_kernel_tap.h +deleted file mode 100644 +index e0e95b4f5..000000000 +--- a/drivers/net/virtio/virtio_user/vhost_kernel_tap.h ++++ /dev/null +@@ -1,39 +0,0 @@ +-/* SPDX-License-Identifier: BSD-3-Clause +- * Copyright(c) 2016 Intel Corporation +- */ +- +-#include +- +-/* TUN ioctls */ +-#define TUNSETIFF _IOW('T', 202, int) +-#define TUNGETFEATURES _IOR('T', 207, unsigned int) +-#define TUNSETOFFLOAD _IOW('T', 208, unsigned int) +-#define TUNGETIFF _IOR('T', 210, unsigned int) +-#define TUNSETSNDBUF _IOW('T', 212, int) +-#define TUNGETVNETHDRSZ _IOR('T', 215, int) +-#define TUNSETVNETHDRSZ _IOW('T', 216, int) +-#define TUNSETQUEUE _IOW('T', 217, int) +-#define TUNSETVNETLE _IOW('T', 220, int) +-#define TUNSETVNETBE _IOW('T', 222, int) +- +-/* TUNSETIFF ifr flags */ +-#define IFF_TAP 0x0002 +-#define IFF_NO_PI 0x1000 +-#define IFF_ONE_QUEUE 0x2000 +-#define IFF_VNET_HDR 0x4000 +-#define IFF_MULTI_QUEUE 0x0100 +-#define IFF_ATTACH_QUEUE 0x0200 +-#define IFF_DETACH_QUEUE 0x0400 +- +-/* Features for GSO (TUNSETOFFLOAD). */ +-#define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */ +-#define TUN_F_TSO4 0x02 /* I can handle TSO for IPv4 packets */ +-#define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */ +-#define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */ +-#define TUN_F_UFO 0x10 /* I can handle UFO packets */ +- +-/* Constants */ +-#define PATH_NET_TUN "/dev/net/tun" +- +-int vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq, +- const char *mac, uint64_t features); +diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c +index 20816c936..7e655a0d5 100644 +--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c ++++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c +@@ -294,7 +294,7 @@ virtio_user_fill_intr_handle(struct virtio_user_dev *dev) + eth_dev->intr_handle->max_intr = dev->max_queue_pairs + 1; + eth_dev->intr_handle->type = RTE_INTR_HANDLE_VDEV; + /* For virtio vdev, no need to read counter for clean */ +- eth_dev->intr_handle->efd_counter_size = 0; ++ eth_dev->intr_handle->efd_counter_size = 8; + eth_dev->intr_handle->fd = -1; + if (dev->vhostfd >= 0) + eth_dev->intr_handle->fd = dev->vhostfd; +@@ -312,7 +312,9 @@ virtio_user_mem_event_cb(enum rte_mem_event type __rte_unused, + { + struct virtio_user_dev *dev = arg; + struct rte_memseg_list *msl; ++#if 0 + uint16_t i; ++#endif + + /* ignore externally allocated memory */ + msl = rte_mem_virt2memseg_list(addr); +@@ -325,15 +327,19 @@ virtio_user_mem_event_cb(enum rte_mem_event type __rte_unused, + goto exit; + + /* Step 1: pause the active queues */ ++#if 0 + for (i = 0; i < dev->queue_pairs; i++) + dev->ops->enable_qp(dev, i, 0); ++#endif + + /* Step 2: update memory regions */ + dev->ops->send_request(dev, VHOST_USER_SET_MEM_TABLE, NULL); + + /* Step 3: resume the active queues */ ++#if 0 + for (i = 0; i < dev->queue_pairs; i++) + dev->ops->enable_qp(dev, i, 1); ++#endif + + exit: + pthread_mutex_unlock(&dev->mutex); +@@ -412,7 +418,7 @@ virtio_user_dev_setup(struct virtio_user_dev *dev) + int + virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, + int cq, int queue_size, const char *mac, char **ifname, +- int mrg_rxbuf, int in_order) ++ int mrg_rxbuf, int in_order, int fd) + { + pthread_mutex_init(&dev->mutex, NULL); + snprintf(dev->path, PATH_MAX, "%s", path); +@@ -435,6 +441,12 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, + return -1; + } + ++ if (fd >= 0) { ++ dev->be_fd = fd; ++ } else { ++ dev->be_fd = -1; ++ } ++ + if (!dev->is_server) { + if (dev->ops->send_request(dev, VHOST_USER_SET_OWNER, + NULL) < 0) { +diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h +index c42ce5d4b..575c21e3b 100644 +--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h ++++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h +@@ -21,6 +21,7 @@ struct virtio_user_dev { + char *ifname; + int *vhostfds; + int *tapfds; ++ int be_fd; + + /* for both vhost_user and vhost_kernel */ + int callfds[VIRTIO_MAX_VIRTQUEUES]; +@@ -50,7 +51,7 @@ int virtio_user_start_device(struct virtio_user_dev *dev); + int virtio_user_stop_device(struct virtio_user_dev *dev); + int virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, + int cq, int queue_size, const char *mac, char **ifname, +- int mrg_rxbuf, int in_order); ++ int mrg_rxbuf, int in_order, int fd); + void virtio_user_dev_uninit(struct virtio_user_dev *dev); + void virtio_user_handle_cq(struct virtio_user_dev *dev, uint16_t queue_idx); + uint8_t virtio_user_handle_mq(struct virtio_user_dev *dev, uint16_t q_pairs); +diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c +index f8791391a..d5e87b24c 100644 +--- a/drivers/net/virtio/virtio_user_ethdev.c ++++ b/drivers/net/virtio/virtio_user_ethdev.c +@@ -221,8 +221,7 @@ virtio_user_get_features(struct virtio_hw *hw) + { + struct virtio_user_dev *dev = virtio_user_get_dev(hw); + +- /* unmask feature bits defined in vhost user protocol */ +- return dev->device_features & VIRTIO_PMD_SUPPORTED_GUEST_FEATURES; ++ return dev->device_features; + } + + static void +@@ -361,6 +360,8 @@ static const char *valid_args[] = { + VIRTIO_USER_ARG_MRG_RXBUF, + #define VIRTIO_USER_ARG_IN_ORDER "in_order" + VIRTIO_USER_ARG_IN_ORDER, ++#define VIRTIO_USER_ARG_FD "fd" ++ VIRTIO_USER_ARG_FD, + NULL + }; + +@@ -464,6 +465,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) + uint64_t server_mode = VIRTIO_USER_DEF_SERVER_MODE; + uint64_t mrg_rxbuf = 1; + uint64_t in_order = 1; ++ uint64_t fd = -1; + char *path = NULL; + char *ifname = NULL; + char *mac_addr = NULL; +@@ -581,6 +583,15 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) + } + } + ++ if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_FD) == 1) { ++ if (rte_kvargs_process(kvlist, VIRTIO_USER_ARG_FD, ++ &get_integer_arg, &fd) < 0) { ++ PMD_INIT_LOG(ERR, "error to parse %s", ++ VIRTIO_USER_ARG_FD); ++ goto end; ++ } ++ } ++ + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + struct virtio_user_dev *vu_dev; + +@@ -598,7 +609,7 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev) + vu_dev->is_server = false; + if (virtio_user_dev_init(hw->virtio_user_dev, path, queues, cq, + queue_size, mac_addr, &ifname, mrg_rxbuf, +- in_order) < 0) { ++ in_order, fd) < 0) { + PMD_INIT_LOG(ERR, "virtio_user_dev_init fails"); + virtio_user_eth_dev_free(eth_dev); + goto end; +@@ -677,4 +688,5 @@ RTE_PMD_REGISTER_PARAM_STRING(net_virtio_user, + "iface= " + "server=<0|1> " + "mrg_rxbuf=<0|1> " +- "in_order=<0|1>"); ++ "in_order=<0|1>" ++ "fd="); +-- +2.17.1 + diff --git a/dpdk/dpdk-v18.11_patches/0006-mempool-add-dynamic-mempool-support.patch b/dpdk/dpdk-v18.11_patches/0006-mempool-add-dynamic-mempool-support.patch new file mode 100644 index 0000000..bcc9743 --- /dev/null +++ b/dpdk/dpdk-v18.11_patches/0006-mempool-add-dynamic-mempool-support.patch @@ -0,0 +1,247 @@ +From 9d2ddfe6012b37297bc84f6ddcce810232162e5b Mon Sep 17 00:00:00 2001 +From: Jianfeng Tan +Date: Wed, 26 Dec 2018 14:39:24 +0000 +Subject: [PATCH 1/2] mempool: add dynamic mempool support + +Signed-off-by: Jianfeng Tan +--- + drivers/mempool/ring/rte_mempool_ring.c | 26 +++++++---- + lib/librte_mempool/rte_mempool.c | 27 +++++++++-- + lib/librte_mempool/rte_mempool.h | 62 ++++++++++++++++++++----- + 3 files changed, 92 insertions(+), 23 deletions(-) + +diff --git a/drivers/mempool/ring/rte_mempool_ring.c b/drivers/mempool/ring/rte_mempool_ring.c +index bc123fc52..e8fec9119 100644 +--- a/drivers/mempool/ring/rte_mempool_ring.c ++++ b/drivers/mempool/ring/rte_mempool_ring.c +@@ -49,30 +49,40 @@ common_ring_get_count(const struct rte_mempool *mp) + static int + common_ring_alloc(struct rte_mempool *mp) + { ++ int n; + int rg_flags = 0, ret; + char rg_name[RTE_RING_NAMESIZE]; + struct rte_ring *r; + +- ret = snprintf(rg_name, sizeof(rg_name), +- RTE_MEMPOOL_MZ_FORMAT, mp->name); +- if (ret < 0 || ret >= (int)sizeof(rg_name)) { +- rte_errno = ENAMETOOLONG; +- return -rte_errno; +- } +- + /* ring flags */ + if (mp->flags & MEMPOOL_F_SP_PUT) + rg_flags |= RING_F_SP_ENQ; + if (mp->flags & MEMPOOL_F_SC_GET) + rg_flags |= RING_F_SC_DEQ; + ++ if (mp->flags & MEMPOOL_F_DYNAMIC) { ++ n = RTE_MIN(mp->size, mp->populated_size + mp->dynamic_size); ++ ++ ret = snprintf(rg_name, sizeof(rg_name), ++ RTE_MEMPOOL_MZ_FORMAT"_%x", mp->name, n); ++ } else { ++ n = mp->size; ++ ret = snprintf(rg_name, sizeof(rg_name), ++ RTE_MEMPOOL_MZ_FORMAT, mp->name); ++ } ++ ++ if (ret < 0 || ret >= (int)sizeof(rg_name)) { ++ rte_errno = ENAMETOOLONG; ++ return -rte_errno; ++ } ++ + /* + * Allocate the ring that will be used to store objects. + * Ring functions will return appropriate errors if we are + * running as a secondary process etc., so no checks made + * in this function for that condition. + */ +- r = rte_ring_create(rg_name, rte_align32pow2(mp->size + 1), ++ r = rte_ring_create(rg_name, rte_align32pow2(n + 1), + mp->socket_id, rg_flags); + if (r == NULL) + return -rte_errno; +diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c +index 683b216f9..70039f6c3 100644 +--- a/lib/librte_mempool/rte_mempool.c ++++ b/lib/librte_mempool/rte_mempool.c +@@ -152,6 +152,8 @@ mempool_add_elem(struct rte_mempool *mp, __rte_unused void *opaque, + hdr->mp = mp; + hdr->iova = iova; + STAILQ_INSERT_TAIL(&mp->elt_list, hdr, next); ++ if (mp->flags & MEMPOOL_F_DYNAMIC && mp->dyn_obj_cb) ++ mp->dyn_obj_cb(mp, NULL, obj, mp->populated_size); + mp->populated_size++; + + #ifdef RTE_LIBRTE_MEMPOOL_DEBUG +@@ -426,9 +428,10 @@ rte_mempool_populate_default(struct rte_mempool *mp) + ssize_t mem_size; + size_t align, pg_sz, pg_shift; + rte_iova_t iova; +- unsigned mz_id, n; ++ unsigned mz_id, n, avail; + int ret; + bool no_contig, try_contig, no_pageshift, external; ++ bool dynamic = (mp->flags & MEMPOOL_F_DYNAMIC) ? true : false; + + ret = mempool_ops_alloc_once(mp); + if (ret != 0) +@@ -441,7 +444,7 @@ rte_mempool_populate_default(struct rte_mempool *mp) + external = ret; + + /* mempool must not be populated */ +- if (mp->nb_mem_chunks != 0) ++ if (mp->nb_mem_chunks != 0 && !dynamic) + return -EEXIST; + + no_contig = mp->flags & MEMPOOL_F_NO_IOVA_CONTIG; +@@ -512,7 +515,16 @@ rte_mempool_populate_default(struct rte_mempool *mp) + pg_shift = rte_bsf32(pg_sz); + } + +- for (mz_id = 0, n = mp->size; n > 0; mz_id++, n -= ret) { ++ n = mp->size; ++ if (dynamic) { ++ n = RTE_MIN(mp->size - mp->populated_size, mp->dynamic_size); ++ if (mp->nb_mem_chunks != 0 && rte_mempool_ops_alloc(mp) != 0) ++ return -ENOMEM; ++ } ++ ++ avail = 0; ++ mz_id = mp->nb_mem_chunks; ++ for (; n > 0; mz_id++, n -= ret, avail += ret) { + size_t min_chunk_size; + unsigned int flags; + +@@ -607,9 +619,16 @@ rte_mempool_populate_default(struct rte_mempool *mp) + } + } + +- return mp->size; ++ return avail; + + fail: ++ if (dynamic) { ++ if (avail) ++ return avail; ++ ++ return ret; ++ } ++ + rte_mempool_free_memchunks(mp); + return ret; + } +diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h +index 7c9cd9a2f..0886b19f2 100644 +--- a/lib/librte_mempool/rte_mempool.h ++++ b/lib/librte_mempool/rte_mempool.h +@@ -207,6 +207,16 @@ struct rte_mempool_info { + unsigned int contig_block_size; + } __rte_cache_aligned; + ++struct rte_mempool; ++/** ++ * An object callback function for mempool. ++ * ++ * Used by rte_mempool_create() and rte_mempool_obj_iter(). ++ */ ++typedef void (rte_mempool_obj_cb_t)(struct rte_mempool *mp, ++ void *opaque, void *obj, unsigned obj_idx); ++typedef rte_mempool_obj_cb_t rte_mempool_obj_ctor_t; /* compat */ ++ + /** + * The RTE mempool structure. + */ +@@ -247,6 +257,8 @@ struct rte_mempool { + struct rte_mempool_cache *local_cache; /**< Per-lcore local cache */ + + uint32_t populated_size; /**< Number of populated objects. */ ++ uint32_t dynamic_size; /**< Number of dynamic populated objects. */ ++ rte_mempool_obj_cb_t *dyn_obj_cb; /**< elem cb for dynamic 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 */ +@@ -264,6 +276,8 @@ struct rte_mempool { + #define MEMPOOL_F_POOL_CREATED 0x0010 /**< Internal: pool is created. */ + #define MEMPOOL_F_NO_IOVA_CONTIG 0x0020 /**< Don't need IOVA contiguous objs. */ + #define MEMPOOL_F_NO_PHYS_CONTIG MEMPOOL_F_NO_IOVA_CONTIG /* deprecated */ ++#define MEMPOOL_F_DYNAMIC 0x0040 /**< Don't populate element once for all */ ++#define MEMPOOL_F_DYNAMIC_NOW 0x0080 /**< It's is dynamically populated now */ + + /** + * @internal When debug is enabled, store some statistics. +@@ -839,15 +853,6 @@ int rte_mempool_register_ops(const struct rte_mempool_ops *ops); + rte_mempool_register_ops(&ops); \ + } + +-/** +- * An object callback function for mempool. +- * +- * Used by rte_mempool_create() and rte_mempool_obj_iter(). +- */ +-typedef void (rte_mempool_obj_cb_t)(struct rte_mempool *mp, +- void *opaque, void *obj, unsigned obj_idx); +-typedef rte_mempool_obj_cb_t rte_mempool_obj_ctor_t; /* compat */ +- + /** + * A memory callback function for mempool. + * +@@ -989,6 +994,22 @@ 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); ++ ++static inline void ++rte_mempool_set_dynamic_size(struct rte_mempool *mp, int dynamic_size) ++{ ++ mp->flags |= MEMPOOL_F_DYNAMIC; ++ mp->dynamic_size = dynamic_size; ++} ++ ++static inline void ++rte_mempool_set_dynamic_cb(struct rte_mempool *mp, ++ rte_mempool_obj_cb_t *dyn_obj_cb) ++{ ++ mp->flags |= MEMPOOL_F_DYNAMIC; ++ mp->dyn_obj_cb = dyn_obj_cb; ++} ++ + /** + * Free a mempool + * +@@ -1390,9 +1411,28 @@ __mempool_generic_get(struct rte_mempool *mp, void **obj_table, + /* get remaining objects from ring */ + ret = rte_mempool_ops_dequeue_bulk(mp, obj_table, n); + +- if (ret < 0) ++ if (ret < 0) { ++ if (mp->flags & MEMPOOL_F_DYNAMIC && ++ mp->populated_size < mp->size) { ++ int work; ++ ++ work = rte_atomic32_cmpset(&mp->flags, ++ mp->flags & ~MEMPOOL_F_DYNAMIC_NOW, ++ mp->flags | MEMPOOL_F_DYNAMIC_NOW); ++ if (work) { ++ int more; ++ ++ more = rte_mempool_populate_default(mp); ++ mp->flags &= ~MEMPOOL_F_DYNAMIC_NOW; ++ if (more > 0) ++ goto ring_dequeue; ++ } else { ++ /* mempool is populating, try again */ ++ goto ring_dequeue; ++ } ++ } + __MEMPOOL_STAT_ADD(mp, get_fail, n); +- else ++ } else + __MEMPOOL_STAT_ADD(mp, get_success, n); + + return ret; +-- +2.17.1 + diff --git a/dpdk/dpdk-v18.11_patches/0007-mbuf-add-dynamic-mbuf-mempool-support.patch b/dpdk/dpdk-v18.11_patches/0007-mbuf-add-dynamic-mbuf-mempool-support.patch new file mode 100644 index 0000000..8618928 --- /dev/null +++ b/dpdk/dpdk-v18.11_patches/0007-mbuf-add-dynamic-mbuf-mempool-support.patch @@ -0,0 +1,305 @@ +From c2a2b8eec349156b31f2faab61cc6063ef3f0c61 Mon Sep 17 00:00:00 2001 +From: Jianfeng Tan +Date: Wed, 26 Dec 2018 14:40:07 +0000 +Subject: [PATCH 2/2] mbuf: add dynamic mbuf mempool support + +Signed-off-by: Jianfeng Tan +--- + examples/Makefile | 1 + + examples/dynamic_mbuf_pool/Makefile | 56 ++++++++++++++++ + examples/dynamic_mbuf_pool/main.c | 92 ++++++++++++++++++++++++++ + examples/dynamic_mbuf_pool/meson.build | 11 +++ + lib/librte_mbuf/rte_mbuf.c | 51 ++++++++++++++ + lib/librte_mbuf/rte_mbuf.h | 5 ++ + lib/librte_mbuf/rte_mbuf_version.map | 8 ++- + 7 files changed, 223 insertions(+), 1 deletion(-) + create mode 100644 examples/dynamic_mbuf_pool/Makefile + create mode 100644 examples/dynamic_mbuf_pool/main.c + create mode 100644 examples/dynamic_mbuf_pool/meson.build + +diff --git a/examples/Makefile b/examples/Makefile +index 33fe0e586..3df9cb7ad 100644 +--- a/examples/Makefile ++++ b/examples/Makefile +@@ -21,6 +21,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += fips_validation + DIRS-$(CONFIG_RTE_LIBRTE_FLOW_CLASSIFY) += flow_classify + DIRS-y += flow_filtering + DIRS-y += helloworld ++DIRS-y += dynamic_mbuf_pool + DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += ip_pipeline + ifeq ($(CONFIG_RTE_LIBRTE_LPM),y) + DIRS-$(CONFIG_RTE_IP_FRAG) += ip_reassembly +diff --git a/examples/dynamic_mbuf_pool/Makefile b/examples/dynamic_mbuf_pool/Makefile +new file mode 100644 +index 000000000..f2761f661 +--- /dev/null ++++ b/examples/dynamic_mbuf_pool/Makefile +@@ -0,0 +1,56 @@ ++# SPDX-License-Identifier: BSD-3-Clause ++# Copyright(c) 2010-2014 Intel Corporation ++ ++# binary name ++APP = dynamic_mbuf_pool ++ ++# all source are stored in SRCS-y ++SRCS-y := main.c ++ ++# Build using pkg-config variables if possible ++$(shell pkg-config --exists libdpdk) ++ifeq ($(.SHELLSTATUS),0) ++ ++all: shared ++.PHONY: shared static ++shared: build/$(APP)-shared ++ ln -sf $(APP)-shared build/$(APP) ++static: build/$(APP)-static ++ ln -sf $(APP)-static build/$(APP) ++ ++PC_FILE := $(shell pkg-config --path libdpdk) ++CFLAGS += -O3 $(shell pkg-config --cflags libdpdk) ++LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk) ++LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk) ++ ++build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build ++ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) ++ ++build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build ++ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) ++ ++build: ++ @mkdir -p $@ ++ ++.PHONY: clean ++clean: ++ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared ++ rmdir --ignore-fail-on-non-empty build ++ ++else ++ ++ifeq ($(RTE_SDK),) ++$(error "Please define RTE_SDK environment variable") ++endif ++ ++# Default target, can be overridden by command line or environment ++RTE_TARGET ?= x86_64-native-linuxapp-gcc ++ ++include $(RTE_SDK)/mk/rte.vars.mk ++ ++CFLAGS += -O3 ++CFLAGS += $(WERROR_FLAGS) ++ ++include $(RTE_SDK)/mk/rte.extapp.mk ++ ++endif +diff --git a/examples/dynamic_mbuf_pool/main.c b/examples/dynamic_mbuf_pool/main.c +new file mode 100644 +index 000000000..a568d7cec +--- /dev/null ++++ b/examples/dynamic_mbuf_pool/main.c +@@ -0,0 +1,92 @@ ++/* SPDX-License-Identifier: BSD-3-Clause ++ * Copyright(c) 2010-2014 Intel Corporation ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define HUGE_2M "/sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages" ++#define HUGE_1G "/sys/kernel/mm/hugepages/hugepages-1048576kB/free_hugepages" ++ ++static long int ++get_value(const char *path) ++{ ++ int fd, len; ++ long int value; ++ char buf[1024]; ++ ++ fd = open(path, O_RDONLY); ++ if (fd < 0) ++ return ULONG_MAX; ++ ++ len = read(fd, buf, sizeof(buf)); ++ ++ close(fd); ++ ++ if (len <= 0) { ++ return ULONG_MAX; ++ } ++ ++ value = strtol(buf, NULL, 10); ++ return value; ++} ++ ++static void ++print_free_hugepages(void) ++{ ++ printf("2M: %ld\t\t1G: %ld\n", get_value(HUGE_2M), get_value(HUGE_1G)); ++} ++ ++int ++main(int argc, char **argv) ++{ ++ int i; ++ int ret; ++ int n = 512 * 1024; ++ int dynamic_size = 8 * 1024; ++ struct rte_mbuf *m; ++ struct rte_mempool *mp; ++ ++ ret = rte_eal_init(argc, argv); ++ if (ret < 0) ++ rte_panic("Cannot init EAL\n"); ++ ++ mp = rte_pktmbuf_dynamic_pool_create("mbuf_pool", n, ++ 64, 0, RTE_MBUF_DEFAULT_BUF_SIZE, ++ 0, dynamic_size); ++ if (mp == NULL) ++ rte_panic("Failed to create mbuf mempool"); ++ ++ for (i = 0; i < n; i++) { ++ m = rte_pktmbuf_alloc(mp); ++ if (m == NULL) ++ break; ++ ++ if ((i % dynamic_size) == 1) { ++ print_free_hugepages(); ++ usleep(100 * 1000); ++ } ++ } ++ ++ printf("have allocated %d mbufs", i); ++ rte_memzone_dump(stdout); ++ ++ return 0; ++} +diff --git a/examples/dynamic_mbuf_pool/meson.build b/examples/dynamic_mbuf_pool/meson.build +new file mode 100644 +index 000000000..c34e11e36 +--- /dev/null ++++ b/examples/dynamic_mbuf_pool/meson.build +@@ -0,0 +1,11 @@ ++# SPDX-License-Identifier: BSD-3-Clause ++# Copyright(c) 2017 Intel Corporation ++ ++# meson file, for building this example as part of a main DPDK build. ++# ++# To build this example as a standalone application with an already-installed ++# DPDK instance, use 'make' ++ ++sources = files( ++ 'main.c' ++) +diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c +index 9790b4fb1..b70abd88c 100644 +--- a/lib/librte_mbuf/rte_mbuf.c ++++ b/lib/librte_mbuf/rte_mbuf.c +@@ -167,6 +167,57 @@ rte_pktmbuf_pool_create(const char *name, unsigned int n, + data_room_size, socket_id, NULL); + } + ++struct rte_mempool * ++rte_pktmbuf_dynamic_pool_create(const char *name, unsigned int n, ++ unsigned int cache_size, uint16_t priv_size, ++ uint16_t data_room_size, int socket_id, int dynamic_size) ++{ ++ struct rte_mempool *mp; ++ struct rte_pktmbuf_pool_private mbp_priv; ++ const char *mp_ops_name; ++ unsigned elt_size; ++ int ret; ++ ++ if (RTE_ALIGN(priv_size, RTE_MBUF_PRIV_ALIGN) != priv_size) { ++ RTE_LOG(ERR, MBUF, "mbuf priv_size=%u is not aligned\n", ++ priv_size); ++ rte_errno = EINVAL; ++ return NULL; ++ } ++ elt_size = sizeof(struct rte_mbuf) + (unsigned)priv_size + ++ (unsigned)data_room_size; ++ mbp_priv.mbuf_data_room_size = data_room_size; ++ mbp_priv.mbuf_priv_size = priv_size; ++ ++ mp = rte_mempool_create_empty(name, n, elt_size, cache_size, ++ sizeof(struct rte_pktmbuf_pool_private), ++ socket_id, MEMPOOL_F_DYNAMIC); ++ if (mp == NULL) ++ return NULL; ++ ++ mp_ops_name = rte_mbuf_best_mempool_ops(); ++ ret = rte_mempool_set_ops_byname(mp, mp_ops_name, NULL); ++ if (ret != 0) { ++ RTE_LOG(ERR, MBUF, "error setting mempool handler\n"); ++ rte_mempool_free(mp); ++ rte_errno = -ret; ++ return NULL; ++ } ++ rte_pktmbuf_pool_init(mp, &mbp_priv); ++ ++ rte_mempool_set_dynamic_size(mp, dynamic_size); ++ rte_mempool_set_dynamic_cb(mp, rte_pktmbuf_init); ++ ++ ret = rte_mempool_populate_default(mp); ++ if (ret < 0) { ++ rte_mempool_free(mp); ++ rte_errno = -ret; ++ return NULL; ++ } ++ ++ return mp; ++} ++ + /* do some sanity checks on a mbuf: panic if it fails */ + void + rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header) +diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h +index 3dbc6695e..5a2d81605 100644 +--- a/lib/librte_mbuf/rte_mbuf.h ++++ b/lib/librte_mbuf/rte_mbuf.h +@@ -1183,6 +1183,11 @@ rte_pktmbuf_pool_create(const char *name, unsigned n, + unsigned cache_size, uint16_t priv_size, uint16_t data_room_size, + int socket_id); + ++struct rte_mempool * ++rte_pktmbuf_dynamic_pool_create(const char *name, unsigned int n, ++ unsigned int cache_size, uint16_t priv_size, ++ uint16_t data_room_size, int socket_id, int dynamic_size); ++ + /** + * Create a mbuf pool with a given mempool ops name + * +diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map +index cae68db8d..d6d25af95 100644 +--- a/lib/librte_mbuf/rte_mbuf_version.map ++++ b/lib/librte_mbuf/rte_mbuf_version.map +@@ -44,4 +44,10 @@ DPDK_18.08 { + rte_mbuf_set_user_mempool_ops; + rte_mbuf_user_mempool_ops; + rte_pktmbuf_pool_create_by_ops; +-} DPDK_16.11; ++} DPDK_18.11; ++ ++DPDK_18.11 { ++ global: ++ ++ rte_pktmbuf_dynamic_pool_create; ++} DPDK_18.12; +-- +2.17.1 + diff --git a/dpdk/dpdk-v18.11_patches/0008-mempool-prioritize-constructor.patch b/dpdk/dpdk-v18.11_patches/0008-mempool-prioritize-constructor.patch new file mode 100644 index 0000000..c941443 --- /dev/null +++ b/dpdk/dpdk-v18.11_patches/0008-mempool-prioritize-constructor.patch @@ -0,0 +1,30 @@ +From cd36895a4a7bfc342915b42e3856bd233452f0bd Mon Sep 17 00:00:00 2001 +From: Jianfeng Tan +Date: Fri, 13 Jul 2018 15:25:22 +0800 +Subject: [PATCH 1/9] mempool: prioritize constructor + +--- + lib/librte_mempool/rte_mempool.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h +index 7c9cd9a2f..bdc32d583 100644 +--- a/lib/librte_mempool/rte_mempool.h ++++ b/lib/librte_mempool/rte_mempool.h +@@ -833,10 +833,10 @@ int rte_mempool_register_ops(const struct rte_mempool_ops *ops); + * more than RTE_MEMPOOL_MAX_OPS_IDX is registered. + */ + #define MEMPOOL_REGISTER_OPS(ops) \ +- void mp_hdlr_init_##ops(void); \ +- void __attribute__((constructor, used)) mp_hdlr_init_##ops(void)\ ++ static void __attribute__((constructor(101), used)) \ ++ mp_hdlr_init_##ops(void) \ + { \ +- rte_mempool_register_ops(&ops); \ ++ rte_mempool_register_ops(&ops); \ + } + + /** +-- +2.17.1 + diff --git a/dpdk/dpdk-v18.11_patches/0009-net-virtio-fill-desc-limit.patch b/dpdk/dpdk-v18.11_patches/0009-net-virtio-fill-desc-limit.patch new file mode 100644 index 0000000..146ea88 --- /dev/null +++ b/dpdk/dpdk-v18.11_patches/0009-net-virtio-fill-desc-limit.patch @@ -0,0 +1,42 @@ +commit 470acd1b108f20ae12b1216c9f6157b78655bcc7 +Author: Jianfeng Tan +Date: Wed Dec 12 02:14:03 2018 +0000 + + net/virtio: fill desc limit + + We shall fill desc limit accordingly, or APIs, such as + rte_eth_dev_adjust_nb_rx_tx_desc, will not give correct desc + information. + + Signed-off-by: Jianfeng Tan + +diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c +index dbfa6865c..d369d5ce8 100644 +--- a/drivers/net/virtio/virtio_ethdev.c ++++ b/drivers/net/virtio/virtio_ethdev.c +@@ -2172,6 +2172,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) + { + uint64_t tso_mask, host_features; + struct virtio_hw *hw = dev->data->dev_private; ++ struct virtqueue *vq; + + dev_info->speed_capa = ETH_LINK_SPEED_10G; /* fake value */ + +@@ -2209,6 +2210,17 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) + (1ULL << VIRTIO_NET_F_HOST_TSO6); + if ((host_features & tso_mask) == tso_mask) + dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO; ++ ++ ++ if (hw->vqs) { ++ vq = hw->vqs[VTNET_SQ_RQ_QUEUE_IDX]; ++ dev_info->rx_desc_lim.nb_max = vq->vq_nentries; ++ dev_info->rx_desc_lim.nb_min = 256; ++ ++ vq = hw->vqs[VTNET_SQ_TQ_QUEUE_IDX]; ++ dev_info->tx_desc_lim.nb_max = vq->vq_nentries; ++ dev_info->tx_desc_lim.nb_min = 256; ++ } + } + + /* -- cgit 1.2.3-korg