From: Matias Elo <matias....@nokia.com> Allocating enough memory for storing each packet in the packet pool in each RX/TX block wastes a lot of memory. Also, the following mmap() call in mmap_sock() can start failing when the number of memory blocks increases (large number of CPU cores). Reduce the amount of required memory by limiting the size of memory blocks.
Signed-off-by: Matias Elo <matias....@nokia.com> --- /** Email created from pull request 397 (matiaselo:dev/pktio_fixes) ** https://github.com/Linaro/odp/pull/397 ** Patch: https://github.com/Linaro/odp/pull/397.patch ** Base sha: 5a4502fc6bc53e6503169da3028f456b64811a0b ** Merge commit sha: 492c47d1c79534d1080b42047c948f1e19498ad3 **/ platform/linux-generic/pktio/socket_mmap.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c index b83486778..b4357f7b3 100644 --- a/platform/linux-generic/pktio/socket_mmap.c +++ b/platform/linux-generic/pktio/socket_mmap.c @@ -37,6 +37,9 @@ #include <protocols/eth.h> #include <protocols/ip.h> +/* Maximum number of packets to store in each RX/TX block */ +#define MAX_PKTS_PER_BLOCK 512 + static int disable_pktio; /** !0 this pktio disabled, 0 enabled */ static int set_pkt_sock_fanout_mmap(pkt_sock_mmap_t *const pkt_sock, @@ -349,6 +352,7 @@ static inline unsigned pkt_mmap_v2_tx(int sock, struct ring *ring, static void mmap_fill_ring(struct ring *ring, odp_pool_t pool_hdl, int fanout) { + uint32_t num_frames; int pz = getpagesize(); pool_t *pool; @@ -360,13 +364,15 @@ static void mmap_fill_ring(struct ring *ring, odp_pool_t pool_hdl, int fanout) /* Frame has to capture full packet which can fit to the pool block.*/ ring->req.tp_frame_size = (pool->headroom + pool->seg_len + pool->tailroom + TPACKET_HDRLEN + - TPACKET_ALIGNMENT + + (pz - 1)) & (-pz); + TPACKET_ALIGNMENT + (pz - 1)) & (-pz); - /* Calculate how many pages do we need to hold all pool packets - * and align size to page boundary. - */ - ring->req.tp_block_size = (ring->req.tp_frame_size * - pool->num + (pz - 1)) & (-pz); + /* Calculate how many pages we need to hold at most MAX_PKTS_PER_BLOCK + * packets and align size to page boundary. + */ + num_frames = pool->num < MAX_PKTS_PER_BLOCK ? pool->num : + MAX_PKTS_PER_BLOCK; + ring->req.tp_block_size = (ring->req.tp_frame_size * num_frames + + (pz - 1)) & (-pz); if (!fanout) { /* Single socket is in use. Use 1 block with buf_num frames. */