From f1a455a17fcdf181fea10c774c2e73d3a6c36325 Mon Sep 17 00:00:00 2001 From: "randomizedcoder dave.seddon.ca@gmail.com" Date: Thu, 29 Oct 2026 21:46:02 -0700 Subject: [PATCH] Ignore unknown link speed in homa_qdev_update_sysctl Drivers that don't know the link speed, such as virtio_net, report SPEED_UNKNOWN (-1) from get_link_ksettings. homa_qdev_update_sysctl used it as is, giving link_mbps -1 and a negative max_nic_queue_bytes, so every deferrable packet was deferred and the pacer never sent it: with the homa qdisc on a virtio NIC, large Homa messages and TCP stalled. A speed of 0 would divide by zero. Fall back to homa->link_mbps in both cases. Found by running two VMs with the homa qdisc on their virtio NICs. Co-Authored-By: Claude Opus 5.5 --- homa_qdisc.c | 4 +++- test/unit_homa_qdisc.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/homa_qdisc.c b/homa_qdisc.c index b84ef03c..12d174c2 100755 --- a/homa_qdisc.c +++ b/homa_qdisc.c @@ -1400,7 +1400,9 @@ void homa_qdev_update_sysctl(struct homa_qdisc_dev *qdev) qdev->link_mbps = homa->link_mbps; ops = qdev->dev->ethtool_ops; if (ops && ops->get_link_ksettings) { - if (ops->get_link_ksettings(qdev->dev, &ksettings) == 0) + if (ops->get_link_ksettings(qdev->dev, &ksettings) == 0 && + ksettings.base.speed != 0 && + ksettings.base.speed != SPEED_UNKNOWN) qdev->link_mbps = ksettings.base.speed; } diff --git a/test/unit_homa_qdisc.c b/test/unit_homa_qdisc.c index 9ea5bb8f..1efa3250 100644 --- a/test/unit_homa_qdisc.c +++ b/test/unit_homa_qdisc.c @@ -2502,6 +2502,22 @@ TEST_F(homa_qdisc, homa_qdev_update_sysctl__cant_get_link_speed_from_dev) homa_qdisc_qdev_put(qdev); } +TEST_F(homa_qdisc, homa_qdev_update_sysctl__link_speed_unknown) +{ + struct homa_qdisc_dev *qdev; + + qdev = homa_qdisc_qdev_get(self->dev); + EXPECT_FALSE(IS_ERR(qdev)); + + /* Some drivers, such as virtio_net, don't know the link speed. */ + self->homa.link_mbps = 16000; + mock_link_mbps = SPEED_UNKNOWN; + homa_qdev_update_sysctl(qdev); + EXPECT_EQ(16000, qdev->link_mbps); + EXPECT_EQ(529583, qdev->cycles_per_mibyte); + + homa_qdisc_qdev_put(qdev); +} TEST_F(homa_qdisc, homa_qdisc_update_sysctl_deps__clamp_values) {