Skip to content

Commit 9866b5a

Browse files
Advance next_qdisc in homa_qdisc_destroy
* homa_qdisc_xmit_deferred_tcp keeps a round-robin cursor, qdev->next_qdisc, that can point at a qdisc's defer_links. homa_qdisc_destroy unlinked the qdisc without moving the cursor, so if other qdiscs still had deferred packets the pacer would next use the destroyed (and soon freed) qdisc. * Move the cursor past the qdisc before unlinking it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 4bd0275 commit 9866b5a

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

‎homa_qdisc.c‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@ void homa_qdisc_destroy(struct Qdisc *qdisc)
473473
while (!skb_queue_empty(&q->deferred_tcp))
474474
kfree_skb_reason(__skb_dequeue(&q->deferred_tcp),
475475
SKB_DROP_REASON_QDISC_DROP);
476+
if (q->qdev->next_qdisc == &q->defer_links)
477+
q->qdev->next_qdisc = q->defer_links.next;
476478
list_del_init(&q->defer_links);
477479
homa_qdisc_unlock_qdev(q->qdev);
478480
homa_qdisc_qdev_put(q->qdev);

‎test/unit_homa_qdisc.c‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,34 @@ TEST_F(homa_qdisc, homa_qdisc_destroy)
484484
kfree(qdisc);
485485
kfree(qdisc2);
486486
}
487+
TEST_F(homa_qdisc, homa_qdisc_destroy__advance_next_qdisc)
488+
{
489+
struct Qdisc *qdisc, *qdisc2;
490+
struct homa_qdisc_dev *qdev;
491+
struct homa_qdisc *q, *q2;
492+
493+
qdisc = mock_alloc_qdisc(&mock_net_queue);
494+
EXPECT_EQ(0, homa_qdisc_init(qdisc, NULL, NULL));
495+
q = qdisc_priv(qdisc);
496+
qdisc2 = mock_alloc_qdisc(&mock_net_queue);
497+
EXPECT_EQ(0, homa_qdisc_init(qdisc2, NULL, NULL));
498+
q2 = qdisc_priv(qdisc2);
499+
qdev = q->qdev;
500+
501+
homa_qdisc_defer_tcp(q, mock_tcp_skb(&self->addr, &self->addr2, 5000,
502+
1000));
503+
homa_qdisc_defer_tcp(q2, mock_tcp_skb(&self->addr, &self->addr2, 6000,
504+
1100));
505+
qdev->next_qdisc = &q2->defer_links;
506+
507+
/* The pacer must not be left pointing at the destroyed qdisc. */
508+
homa_qdisc_destroy(qdisc2);
509+
EXPECT_EQ(&qdev->deferred_qdiscs, qdev->next_qdisc);
510+
511+
homa_qdisc_destroy(qdisc);
512+
kfree(qdisc);
513+
kfree(qdisc2);
514+
}
487515

488516
TEST_F(homa_qdisc, homa_qdisc_add_queued__no_lag)
489517
{

0 commit comments

Comments
 (0)