Skip to content

Commit 5ba8868

Browse files
committed
aq(4): Distribute RSS over min(rings, 8) with a modulo
aq_if_attach_post() built the RSS indirection table with rss_table[i] = i & (rx_rings_count - 1); which assumes rx_rings_count is a power of two. iflib does not guarantee that (queue counts such as 6, 12 or 24 are possible), so the mask left some queues with no entries and skewed the hash distribution. When rx_rings_count was 0 the (count - 1) underflow also turned the mask into a no-op rather than failing safe. Use a modulo over min(rx_rings_count, HW_ATL_RSS_QUEUES_MAX) instead. The redirection-table field is 3 bits wide, so the hardware can only hash across 8 queues regardless of ring count; capping here keeps the table values in range and complements the bounds fix in aq_hw_rss_set(). Signed-off-by: Nick Price <nick@spun.io>
1 parent f7b158a commit 5ba8868

2 files changed

Lines changed: 10 additions & 2 deletions

File tree

sys/dev/aq/aq_hw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ struct aq_hw {
197197

198198
#define HW_ATL_RSS_INDIRECTION_TABLE_MAX 64U
199199
#define HW_ATL_RSS_HASHKEY_SIZE 40U
200+
/* Redirection-table entries are 3 bits wide, so RSS spans <= 8 queues. */
201+
#define HW_ATL_RSS_QUEUES_MAX 8U
200202

201203
/* PCI core control register */
202204
#define AQ_HW_PCI_REG_CONTROL_6_ADR 0x1014U

sys/dev/aq/aq_main.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,10 +464,16 @@ aq_if_attach_post(if_ctx_t ctx)
464464
}
465465

466466
aq_add_stats_sysctls(softc);
467-
/* RSS */
467+
/*
468+
* RSS: modulo over min(rings, 8) queues. Ring count isn't always a
469+
* power of two, so an AND mask would starve queues; HW caps RSS at 8.
470+
*/
468471
arc4rand(softc->rss_key, HW_ATL_RSS_HASHKEY_SIZE, 0);
472+
uint32_t rss_qs = MIN(softc->rx_rings_count, HW_ATL_RSS_QUEUES_MAX);
473+
if (rss_qs == 0)
474+
rss_qs = 1;
469475
for (int i = ARRAY_SIZE(softc->rss_table); i--;){
470-
softc->rss_table[i] = i & (softc->rx_rings_count - 1);
476+
softc->rss_table[i] = i % rss_qs;
471477
}
472478
exit:
473479
AQ_DBG_EXIT(rc);

0 commit comments

Comments
 (0)