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. */

Reply via email to