net/virtio: fix 32-bit build with gcc 6
authorFerruh Yigit <ferruh.yigit@intel.com>
Thu, 7 Jul 2016 13:49:08 +0000 (14:49 +0100)
committerYuanhan Liu <yuanhan.liu@linux.intel.com>
Mon, 11 Jul 2016 05:41:09 +0000 (07:41 +0200)
This is for target i686-native-linuxapp-gcc and gcc6,

Compilation error is:

In file included from
  include/rte_mempool.h:77:0, from
  drivers/net/virtio/virtio_rxtx_simple.c:
In function `virtio_xmit_pkts_simple':
  include/rte_memcpy.h:551:2: error:
    array subscript is above array bounds
      rte_mov16((uint8_t *)dst + 1 * 16, (const uint8_t *)src + 1 * 16);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Call stack is as following:

virtio_xmit_pkts_simple
  virtio_xmit_cleanup
    rte_mempool_put_bulk
      rte_mempool_generic_put
        __mempool_generic_put
  rte_memcpy

The array used as source buffer in virtio_xmit_cleanup (free) is a
pointer array with 32 elements, in 32bit this makes 128 bytes.

in rte_memcpy() implementation, there a code piece as following:
if (size > 256) {
    rte_move128(...);
    rte_move128(...); <--- [1]
    ....
}

The compiler traces the array all through the call stack and knows the
size of array is 128 and generates a warning on above [1] which tries to
access beyond byte 128.
But unfortunately it ignores the "(size > 256)" check.

Giving a hint to compiler that variable "size" is related to the size of
the source buffer fixes compiler warning.

Fixes: 863bfb474493 ("mempool: optimize copy in cache")

Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
drivers/net/virtio/virtio_rxtx_simple.c

index 242ad90..d8fcc15 100644 (file)
@@ -301,7 +301,7 @@ static inline void
 virtio_xmit_cleanup(struct virtqueue *vq)
 {
        uint16_t i, desc_idx;
-       int nb_free = 0;
+       uint32_t nb_free = 0;
        struct rte_mbuf *m, *free[VIRTIO_TX_MAX_FREE_BUF_SZ];
 
        desc_idx = (uint16_t)(vq->vq_used_cons_idx &
@@ -319,13 +319,16 @@ virtio_xmit_cleanup(struct virtqueue *vq)
                                        free[nb_free++] = m;
                                else {
                                        rte_mempool_put_bulk(free[0]->pool,
-                                               (void **)free, nb_free);
+                                               (void **)free,
+                                               RTE_MIN(RTE_DIM(free),
+                                                       nb_free));
                                        free[0] = m;
                                        nb_free = 1;
                                }
                        }
                }
-               rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free);
+               rte_mempool_put_bulk(free[0]->pool, (void **)free,
+                       RTE_MIN(RTE_DIM(free), nb_free));
        } else {
                for (i = 1; i < VIRTIO_TX_FREE_NR; i++) {
                        m = (struct rte_mbuf *)vq->vq_descx[desc_idx++].cookie;