From: fengchengwen <fengchengwen@huawei.com>
To: "dev@dpdk.org" <dev@dpdk.org>, Dengdui Huang <huangdengdui@huawei.com>
Subject: Strict aliasing problem with rte_eth_linkstatus_set()
Date: Wed, 10 Apr 2024 17:33:53 +0800 [thread overview]
Message-ID: <8175c905-e661-b910-7f20-59b6ab605c38@huawei.com> (raw)
Hi All,
We have a problem introduced by a compiler upgrade (from gcc10 to gcc12.3), we've done some
research but haven't been able to figure out why. We'd like the community's help.
Environment:
1. Source: DPDK 23.11
2. GCC: 12.3.1 [1]
3. Compiled with target kunpeng SoC (ARM64)
4. Run on kunpeng SoC
Problem & Debug:
1. We found the hns3 driver fails to update the link status. The corresponding function is
hns3_update_linkstatus_and_event [2], and we found the rte_eth_linkstatus_set [3] always return zero.
2. After disassembly the hns3_update_linkstatus_and_event, and found rte_eth_linkstatus_set's
rte_atomic_exchange_explicit return to xzr register (which is zero register):
1239fec: 3900f3e0 strb w0, [sp, #60]
1239ff0: 9101a041 add x1, x2, #0x68 ---x2 seem not the variable new_link
1239ff4: f8ff8022 swpal xzr, x2, [x1] ---this instr corresponding rte_atomic_exchange_explicit,
it will place the resut in xzr which always zero,
and this will lead to rte_eth_linkstatus_set return 0.
1239ff8: 3940f3e0 ldrb w0, [sp, #60]
1239ffc: d3609c41 ubfx x1, x2, #32, #8
123a000: 4a010000 eor w0, w0, w1
123a004: 36100080 tbz w0, #2, 123a014 <hns3_update_linkstatus_and_event+0xd4>
3. We checked other "ret = rte_eth_linkstatus_set" calls, and can't find similar problem.
4. After reading a lot of documents, we preliminarily think that the problem is caused by -fstrict-aliasing
(which was enabled default with O2 or O3), if compiled with -fno-strict-aliasing, then this problem don't
exist. We guest this maybe strict-aliasing's bug which only happened in our function.
5. We also try to use union to avoid such aliasing in rte_eth_linkstatus_set, we changed the struct
rte_eth_link define, and it works:
-__extension__
-struct __rte_aligned(8) rte_eth_link { /**< aligned for atomic64 read/write */
- uint32_t link_speed; /**< RTE_ETH_SPEED_NUM_ */
- uint16_t link_duplex : 1; /**< RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
- uint16_t link_autoneg : 1; /**< RTE_ETH_LINK_[AUTONEG/FIXED] */
- uint16_t link_status : 1; /**< RTE_ETH_LINK_[DOWN/UP] */
+struct rte_eth_link { /**< aligned for atomic64 read/write */
+ union {
+ uint64_t val64;
+ struct {
+ uint32_t link_speed; /**< RTE_ETH_SPEED_NUM_ */
+ uint16_t link_duplex : 1; /**< RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
+ uint16_t link_autoneg : 1; /**< RTE_ETH_LINK_[AUTONEG/FIXED] */
+ uint16_t link_status : 1; /**< RTE_ETH_LINK_[DOWN/UP] */
+ };
+ };
};
the corresponding rte_eth_linkstatus_set:
@@ -1674,18 +1674,13 @@ static inline int
rte_eth_linkstatus_set(struct rte_eth_dev *dev,
const struct rte_eth_link *new_link)
{
- RTE_ATOMIC(uint64_t) *dev_link = (uint64_t __rte_atomic *)&(dev->data->dev_link);
- union {
- uint64_t val64;
- struct rte_eth_link link;
- } orig;
-
- RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
+ struct rte_eth_link old_link;
- orig.val64 = rte_atomic_exchange_explicit(dev_link, *(const uint64_t *)new_link,
+ old_link.val64 = rte_atomic_exchange_explicit(&dev->data->dev_link.val64,
+ new_link->val64,
rte_memory_order_seq_cst);
- return (orig.link.link_status == new_link->link_status) ? -1 : 0;
+ return (old_link.link_status == new_link->link_status) ? -1 : 0;
}
6. BTW: the linux kernel enabled "-fno-strict-aliasing" default, please see [4] for more.
Last: We think there are two ways to solve this problem.
1. Add the compilation option '-fno-strict-aliasing' for hold DPDK project.
2. Use union to avoid such aliasing in rte_eth_linkstatus_set (please see above).
PS: We prefer first way.
Hope for more discuess.
Thanks
[1] https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads/12-3-rel1
[2] void
hns3_update_linkstatus_and_event(struct hns3_hw *hw, bool query)
{
struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id];
struct rte_eth_link new_link;
int ret;
if (query)
hns3_update_port_link_info(dev);
memset(&new_link, 0, sizeof(new_link));
hns3_setup_linkstatus(dev, &new_link);
ret = rte_eth_linkstatus_set(dev, &new_link);
if (ret == 0 && dev->data->dev_conf.intr_conf.lsc != 0)
hns3_start_report_lse(dev);
}
[3] static inline int
rte_eth_linkstatus_set(struct rte_eth_dev *dev,
const struct rte_eth_link *new_link)
{
RTE_ATOMIC(uint64_t) *dev_link = (uint64_t __rte_atomic *)&(dev->data->dev_link);
union {
uint64_t val64;
struct rte_eth_link link;
} orig;
RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
orig.val64 = rte_atomic_exchange_explicit(dev_link, *(const uint64_t *)new_link,
rte_memory_order_seq_cst);
return (orig.link.link_status == new_link->link_status) ? -1 : 0;
}
[4] https://lore.kernel.org/all/b3itcd$2bi$1@penguin.transmeta.com/
next reply other threads:[~2024-04-10 9:33 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-10 9:33 fengchengwen [this message]
2024-04-10 10:30 ` Morten Brørup
2024-04-10 15:57 ` Ferruh Yigit
2024-04-11 2:03 ` fengchengwen
2024-04-10 15:27 ` Stephen Hemminger
2024-04-10 15:58 ` Ferruh Yigit
2024-04-10 17:54 ` Morten Brørup
2024-04-10 19:58 ` Tyler Retzlaff
2024-04-11 3:20 ` fengchengwen
2024-04-10 21:18 ` Stephen Hemminger
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=8175c905-e661-b910-7f20-59b6ab605c38@huawei.com \
--to=fengchengwen@huawei.com \
--cc=dev@dpdk.org \
--cc=huangdengdui@huawei.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).