From: kernel test robot <lkp@intel.com>
To: kbuild-all@lists.01.org
Subject: Re: [RFC PATCH] fix xfrm MTU regression
Date: Fri, 30 Apr 2021 04:37:45 +0800 [thread overview]
Message-ID: <202104300409.iAhWmxup-lkp@intel.com> (raw)
In-Reply-To: <20210429170254.5grfgsz2hgy2qjhk@dwarf.suse.cz>
[-- Attachment #1: Type: text/plain, Size: 16600 bytes --]
Hi Jiri,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on linus/master]
[also build test WARNING on v5.12 next-20210429]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Jiri-Bohac/fix-xfrm-MTU-regression/20210430-010412
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git d72cd4ad4174cfd2257c426ad51e4f53bcfde9c9
config: x86_64-randconfig-a015-20210429 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 9131a078901b00e68248a27a4f8c4b11bb1db1ae)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# https://github.com/0day-ci/linux/commit/f556543e005a1eb6567fc299e60f7d92dc508f88
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Jiri-Bohac/fix-xfrm-MTU-regression/20210430-010412
git checkout f556543e005a1eb6567fc299e60f7d92dc508f88
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> net/ipv6/ip6_output.c:1467:6: warning: variable 'headersize' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
if (mtu < fragheaderlen ||
^~~~~~~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1501:27: note: uninitialized use occurs here
pmtu = max_t(int, mtu - headersize + sizeof(struct ipv6hdr), 0);
^~~~~~~~~~
include/linux/minmax.h:118:48: note: expanded from macro 'max_t'
#define max_t(type, x, y) __careful_cmp((type)(x), (type)(y), >)
^
include/linux/minmax.h:44:14: note: expanded from macro '__careful_cmp'
__cmp_once(x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y), op))
^
include/linux/minmax.h:37:25: note: expanded from macro '__cmp_once'
typeof(x) unique_x = (x); \
^
net/ipv6/ip6_output.c:1467:2: note: remove the 'if' if its condition is always false
if (mtu < fragheaderlen ||
^~~~~~~~~~~~~~~~~~~~~~~~~~
>> net/ipv6/ip6_output.c:1467:6: warning: variable 'headersize' is used uninitialized whenever '||' condition is true [-Wsometimes-uninitialized]
if (mtu < fragheaderlen ||
^~~~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1501:27: note: uninitialized use occurs here
pmtu = max_t(int, mtu - headersize + sizeof(struct ipv6hdr), 0);
^~~~~~~~~~
include/linux/minmax.h:118:48: note: expanded from macro 'max_t'
#define max_t(type, x, y) __careful_cmp((type)(x), (type)(y), >)
^
include/linux/minmax.h:44:14: note: expanded from macro '__careful_cmp'
__cmp_once(x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y), op))
^
include/linux/minmax.h:37:25: note: expanded from macro '__cmp_once'
typeof(x) unique_x = (x); \
^
net/ipv6/ip6_output.c:1467:6: note: remove the '||' if its condition is always false
if (mtu < fragheaderlen ||
^~~~~~~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1444:41: note: initialize the variable 'headersize' to silence this warning
unsigned int maxnonfragsize, headersize;
^
= 0
2 warnings generated.
vim +1467 net/ipv6/ip6_output.c
1419
1420 static int __ip6_append_data(struct sock *sk,
1421 struct flowi6 *fl6,
1422 struct sk_buff_head *queue,
1423 struct inet_cork *cork,
1424 struct inet6_cork *v6_cork,
1425 struct page_frag *pfrag,
1426 int getfrag(void *from, char *to, int offset,
1427 int len, int odd, struct sk_buff *skb),
1428 void *from, int length, int transhdrlen,
1429 unsigned int flags, struct ipcm6_cookie *ipc6)
1430 {
1431 struct sk_buff *skb, *skb_prev = NULL;
1432 unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu;
1433 struct ubuf_info *uarg = NULL;
1434 int exthdrlen = 0;
1435 int dst_exthdrlen = 0;
1436 int hh_len;
1437 int copy;
1438 int err;
1439 int offset = 0;
1440 u32 tskey = 0;
1441 struct rt6_info *rt = (struct rt6_info *)cork->dst;
1442 struct ipv6_txoptions *opt = v6_cork->opt;
1443 int csummode = CHECKSUM_NONE;
1444 unsigned int maxnonfragsize, headersize;
1445 unsigned int wmem_alloc_delta = 0;
1446 bool paged, extra_uref = false;
1447
1448 skb = skb_peek_tail(queue);
1449 if (!skb) {
1450 exthdrlen = opt ? opt->opt_flen : 0;
1451 dst_exthdrlen = rt->dst.header_len - rt->rt6i_nfheader_len;
1452 }
1453
1454 paged = !!cork->gso_size;
1455 mtu = cork->gso_size ? IP6_MAX_MTU : cork->fragsize;
1456 orig_mtu = mtu;
1457
1458 if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP &&
1459 sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
1460 tskey = sk->sk_tskey++;
1461
1462 hh_len = LL_RESERVED_SPACE(rt->dst.dev);
1463
1464 fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len +
1465 (opt ? opt->opt_nflen : 0);
1466
> 1467 if (mtu < fragheaderlen ||
1468 ((mtu - fragheaderlen) & ~7) + fragheaderlen < sizeof(struct frag_hdr))
1469 goto emsgsize;
1470
1471 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
1472 sizeof(struct frag_hdr);
1473
1474 headersize = sizeof(struct ipv6hdr) +
1475 (opt ? opt->opt_flen + opt->opt_nflen : 0) +
1476 (dst_allfrag(&rt->dst) ?
1477 sizeof(struct frag_hdr) : 0) +
1478 rt->rt6i_nfheader_len;
1479
1480 /* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit
1481 * the first fragment
1482 */
1483 if (headersize + transhdrlen > mtu)
1484 goto emsgsize;
1485
1486 if (cork->length + length > mtu - headersize && ipc6->dontfrag &&
1487 (sk->sk_protocol == IPPROTO_UDP ||
1488 sk->sk_protocol == IPPROTO_RAW)) {
1489 ipv6_local_rxpmtu(sk, fl6, mtu - headersize +
1490 sizeof(struct ipv6hdr));
1491 goto emsgsize;
1492 }
1493
1494 if (ip6_sk_ignore_df(sk))
1495 maxnonfragsize = sizeof(struct ipv6hdr) + IPV6_MAXPLEN;
1496 else
1497 maxnonfragsize = mtu;
1498
1499 if (cork->length + length > maxnonfragsize - headersize) {
1500 emsgsize:
1501 pmtu = max_t(int, mtu - headersize + sizeof(struct ipv6hdr), 0);
1502 ipv6_local_error(sk, EMSGSIZE, fl6, pmtu);
1503 return -EMSGSIZE;
1504 }
1505
1506 /* CHECKSUM_PARTIAL only with no extension headers and when
1507 * we are not going to fragment
1508 */
1509 if (transhdrlen && sk->sk_protocol == IPPROTO_UDP &&
1510 headersize == sizeof(struct ipv6hdr) &&
1511 length <= mtu - headersize &&
1512 (!(flags & MSG_MORE) || cork->gso_size) &&
1513 rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
1514 csummode = CHECKSUM_PARTIAL;
1515
1516 if (flags & MSG_ZEROCOPY && length && sock_flag(sk, SOCK_ZEROCOPY)) {
1517 uarg = msg_zerocopy_realloc(sk, length, skb_zcopy(skb));
1518 if (!uarg)
1519 return -ENOBUFS;
1520 extra_uref = !skb_zcopy(skb); /* only ref on new uarg */
1521 if (rt->dst.dev->features & NETIF_F_SG &&
1522 csummode == CHECKSUM_PARTIAL) {
1523 paged = true;
1524 } else {
1525 uarg->zerocopy = 0;
1526 skb_zcopy_set(skb, uarg, &extra_uref);
1527 }
1528 }
1529
1530 /*
1531 * Let's try using as much space as possible.
1532 * Use MTU if total length of the message fits into the MTU.
1533 * Otherwise, we need to reserve fragment header and
1534 * fragment alignment (= 8-15 octects, in total).
1535 *
1536 * Note that we may need to "move" the data from the tail
1537 * of the buffer to the new fragment when we split
1538 * the message.
1539 *
1540 * FIXME: It may be fragmented into multiple chunks
1541 * at once if non-fragmentable extension headers
1542 * are too large.
1543 * --yoshfuji
1544 */
1545
1546 cork->length += length;
1547 if (!skb)
1548 goto alloc_new_skb;
1549
1550 while (length > 0) {
1551 /* Check if the remaining data fits into current packet. */
1552 copy = (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - skb->len;
1553 if (copy < length)
1554 copy = maxfraglen - skb->len;
1555
1556 if (copy <= 0) {
1557 char *data;
1558 unsigned int datalen;
1559 unsigned int fraglen;
1560 unsigned int fraggap;
1561 unsigned int alloclen;
1562 unsigned int pagedlen;
1563 alloc_new_skb:
1564 /* There's no room in the current skb */
1565 if (skb)
1566 fraggap = skb->len - maxfraglen;
1567 else
1568 fraggap = 0;
1569 /* update mtu and maxfraglen if necessary */
1570 if (!skb || !skb_prev)
1571 ip6_append_data_mtu(&mtu, &maxfraglen,
1572 fragheaderlen, skb, rt,
1573 orig_mtu);
1574
1575 skb_prev = skb;
1576
1577 /*
1578 * If remaining data exceeds the mtu,
1579 * we know we need more fragment(s).
1580 */
1581 datalen = length + fraggap;
1582
1583 if (datalen > (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen)
1584 datalen = maxfraglen - fragheaderlen - rt->dst.trailer_len;
1585 fraglen = datalen + fragheaderlen;
1586 pagedlen = 0;
1587
1588 if ((flags & MSG_MORE) &&
1589 !(rt->dst.dev->features&NETIF_F_SG))
1590 alloclen = mtu;
1591 else if (!paged)
1592 alloclen = fraglen;
1593 else {
1594 alloclen = min_t(int, fraglen, MAX_HEADER);
1595 pagedlen = fraglen - alloclen;
1596 }
1597
1598 alloclen += dst_exthdrlen;
1599
1600 if (datalen != length + fraggap) {
1601 /*
1602 * this is not the last fragment, the trailer
1603 * space is regarded as data space.
1604 */
1605 datalen += rt->dst.trailer_len;
1606 }
1607
1608 alloclen += rt->dst.trailer_len;
1609 fraglen = datalen + fragheaderlen;
1610
1611 /*
1612 * We just reserve space for fragment header.
1613 * Note: this may be overallocation if the message
1614 * (without MSG_MORE) fits into the MTU.
1615 */
1616 alloclen += sizeof(struct frag_hdr);
1617
1618 copy = datalen - transhdrlen - fraggap - pagedlen;
1619 if (copy < 0) {
1620 err = -EINVAL;
1621 goto error;
1622 }
1623 if (transhdrlen) {
1624 skb = sock_alloc_send_skb(sk,
1625 alloclen + hh_len,
1626 (flags & MSG_DONTWAIT), &err);
1627 } else {
1628 skb = NULL;
1629 if (refcount_read(&sk->sk_wmem_alloc) + wmem_alloc_delta <=
1630 2 * sk->sk_sndbuf)
1631 skb = alloc_skb(alloclen + hh_len,
1632 sk->sk_allocation);
1633 if (unlikely(!skb))
1634 err = -ENOBUFS;
1635 }
1636 if (!skb)
1637 goto error;
1638 /*
1639 * Fill in the control structures
1640 */
1641 skb->protocol = htons(ETH_P_IPV6);
1642 skb->ip_summed = csummode;
1643 skb->csum = 0;
1644 /* reserve for fragmentation and ipsec header */
1645 skb_reserve(skb, hh_len + sizeof(struct frag_hdr) +
1646 dst_exthdrlen);
1647
1648 /*
1649 * Find where to start putting bytes
1650 */
1651 data = skb_put(skb, fraglen - pagedlen);
1652 skb_set_network_header(skb, exthdrlen);
1653 data += fragheaderlen;
1654 skb->transport_header = (skb->network_header +
1655 fragheaderlen);
1656 if (fraggap) {
1657 skb->csum = skb_copy_and_csum_bits(
1658 skb_prev, maxfraglen,
1659 data + transhdrlen, fraggap);
1660 skb_prev->csum = csum_sub(skb_prev->csum,
1661 skb->csum);
1662 data += fraggap;
1663 pskb_trim_unique(skb_prev, maxfraglen);
1664 }
1665 if (copy > 0 &&
1666 getfrag(from, data + transhdrlen, offset,
1667 copy, fraggap, skb) < 0) {
1668 err = -EFAULT;
1669 kfree_skb(skb);
1670 goto error;
1671 }
1672
1673 offset += copy;
1674 length -= copy + transhdrlen;
1675 transhdrlen = 0;
1676 exthdrlen = 0;
1677 dst_exthdrlen = 0;
1678
1679 /* Only the initial fragment is time stamped */
1680 skb_shinfo(skb)->tx_flags = cork->tx_flags;
1681 cork->tx_flags = 0;
1682 skb_shinfo(skb)->tskey = tskey;
1683 tskey = 0;
1684 skb_zcopy_set(skb, uarg, &extra_uref);
1685
1686 if ((flags & MSG_CONFIRM) && !skb_prev)
1687 skb_set_dst_pending_confirm(skb, 1);
1688
1689 /*
1690 * Put the packet on the pending queue
1691 */
1692 if (!skb->destructor) {
1693 skb->destructor = sock_wfree;
1694 skb->sk = sk;
1695 wmem_alloc_delta += skb->truesize;
1696 }
1697 __skb_queue_tail(queue, skb);
1698 continue;
1699 }
1700
1701 if (copy > length)
1702 copy = length;
1703
1704 if (!(rt->dst.dev->features&NETIF_F_SG) &&
1705 skb_tailroom(skb) >= copy) {
1706 unsigned int off;
1707
1708 off = skb->len;
1709 if (getfrag(from, skb_put(skb, copy),
1710 offset, copy, off, skb) < 0) {
1711 __skb_trim(skb, off);
1712 err = -EFAULT;
1713 goto error;
1714 }
1715 } else if (!uarg || !uarg->zerocopy) {
1716 int i = skb_shinfo(skb)->nr_frags;
1717
1718 err = -ENOMEM;
1719 if (!sk_page_frag_refill(sk, pfrag))
1720 goto error;
1721
1722 if (!skb_can_coalesce(skb, i, pfrag->page,
1723 pfrag->offset)) {
1724 err = -EMSGSIZE;
1725 if (i == MAX_SKB_FRAGS)
1726 goto error;
1727
1728 __skb_fill_page_desc(skb, i, pfrag->page,
1729 pfrag->offset, 0);
1730 skb_shinfo(skb)->nr_frags = ++i;
1731 get_page(pfrag->page);
1732 }
1733 copy = min_t(int, copy, pfrag->size - pfrag->offset);
1734 if (getfrag(from,
1735 page_address(pfrag->page) + pfrag->offset,
1736 offset, copy, skb->len, skb) < 0)
1737 goto error_efault;
1738
1739 pfrag->offset += copy;
1740 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
1741 skb->len += copy;
1742 skb->data_len += copy;
1743 skb->truesize += copy;
1744 wmem_alloc_delta += copy;
1745 } else {
1746 err = skb_zerocopy_iter_dgram(skb, from, copy);
1747 if (err < 0)
1748 goto error;
1749 }
1750 offset += copy;
1751 length -= copy;
1752 }
1753
1754 if (wmem_alloc_delta)
1755 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1756 return 0;
1757
1758 error_efault:
1759 err = -EFAULT;
1760 error:
1761 net_zcopy_put_abort(uarg, extra_uref);
1762 cork->length -= length;
1763 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
1764 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
1765 return err;
1766 }
1767
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 33314 bytes --]
next prev parent reply other threads:[~2021-04-29 20:37 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-29 17:02 [RFC PATCH] fix xfrm MTU regression Jiri Bohac
2021-04-29 19:48 ` Sabrina Dubroca
2021-04-29 20:25 ` Jiri Bohac
2021-05-01 10:23 ` Sabrina Dubroca
2021-04-29 20:37 ` kernel test robot [this message]
2021-04-30 5:36 ` [RFC PATCH v2] " Jiri Bohac
-- strict thread matches above, loose matches on Subject: below --
2021-04-29 23:17 [RFC PATCH] " kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202104300409.iAhWmxup-lkp@intel.com \
--to=lkp@intel.com \
--cc=kbuild-all@lists.01.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.