mbuf: avoid integer promotion in prepend/adj/chain
authorAndy Green <andy@warmcat.com>
Tue, 22 May 2018 01:24:42 +0000 (09:24 +0800)
committerThomas Monjalon <thomas@monjalon.net>
Tue, 22 May 2018 14:32:36 +0000 (16:32 +0200)
GCC 8.1 warned:

In function 'rte_pktmbuf_prepend':
rte_mbuf.h:1908:17: warning: conversion from 'int' to 'uint16_t'
{aka 'short unsigned int'} may change value [-Wconversion]
  m->data_off -= len;
                 ^~~
m->data_off is a uint16_t

        uint16_t data_off;

len (a uint16_t) is promoted to an int using -=.  Do the
subtraction explicitly and cast the result to uint16_t.

The below += or -= changes are solving the same thing.

In function 'rte_pktmbuf_adj':
rte_mbuf.h:1969:17: warning: conversion from 'int' to 'uint16_t'
{aka 'short unsigned int'} may change value [-Wconversion]
  m->data_off += len;
                 ^~~

In function 'rte_pktmbuf_chain':
rte_mbuf.h:2082:19: warning: conversion from 'int' to 'uint16_t'
{aka 'short unsigned int'} may change value [-Wconversion]
  head->nb_segs += tail->nb_segs;
                   ^~~~
Also uint16_t

        uint16_t nb_segs;         /**< Number of segments. */

Fixes: 08b563ffb19d ("mbuf: replace data pointer by an offset")
Fixes: 1a60a0daa6e4 ("mbuf: fix segments number type increase")
Cc: stable@dpdk.org
Signed-off-by: Andy Green <andy@warmcat.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
lib/librte_mbuf/rte_mbuf.h

index 0e89a69..e136d12 100644 (file)
@@ -1908,7 +1908,10 @@ static inline char *rte_pktmbuf_prepend(struct rte_mbuf *m,
        if (unlikely(len > rte_pktmbuf_headroom(m)))
                return NULL;
 
-       m->data_off -= len;
+       /* NB: elaborating the subtraction like this instead of using
+        *     -= allows us to ensure the result type is uint16_t
+        *     avoiding compiler warnings on gcc 8.1 at least */
+       m->data_off = (uint16_t)(m->data_off - len);
        m->data_len = (uint16_t)(m->data_len + len);
        m->pkt_len  = (m->pkt_len + len);
 
@@ -1968,8 +1971,11 @@ static inline char *rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
        if (unlikely(len > m->data_len))
                return NULL;
 
+       /* NB: elaborating the addition like this instead of using
+        *     += allows us to ensure the result type is uint16_t
+        *     avoiding compiler warnings on gcc 8.1 at least */
        m->data_len = (uint16_t)(m->data_len - len);
-       m->data_off += len;
+       m->data_off = (uint16_t)(m->data_off + len);
        m->pkt_len  = (m->pkt_len - len);
        return (char *)m->buf_addr + m->data_off;
 }
@@ -2081,8 +2087,11 @@ static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail
        cur_tail = rte_pktmbuf_lastseg(head);
        cur_tail->next = tail;
 
-       /* accumulate number of segments and total length. */
-       head->nb_segs += tail->nb_segs;
+       /* accumulate number of segments and total length.
+        * NB: elaborating the addition like this instead of using
+        *     -= allows us to ensure the result type is uint16_t
+        *     avoiding compiler warnings on gcc 8.1 at least */
+       head->nb_segs = (uint16_t)(head->nb_segs + tail->nb_segs);
        head->pkt_len += tail->pkt_len;
 
        /* pkt_len is only set in the head */