Skip to content

atlantic: guard rss_getkey/rss_gethashconfig with #ifdef RSS (fixes GENERIC link)#386

Merged
laffer1 merged 1 commit into
masterfrom
atlantic-rss-build-fix
Jun 12, 2026
Merged

atlantic: guard rss_getkey/rss_gethashconfig with #ifdef RSS (fixes GENERIC link)#386
laffer1 merged 1 commit into
masterfrom
atlantic-rss-build-fix

Conversation

@laffer1

@laffer1 laffer1 commented Jun 12, 2026

Copy link
Copy Markdown
Member

Summary

aq_rss_prepare() in the atlantic (Aquantia/Marvell AQtion) driver calls
rss_getkey() and rss_gethashconfig() unconditionally, but those symbols only
exist when the kernel is built with options RSS (net/rss_config.c is
optional inet rss). The driver enables hardware RSS whenever it has more than
one RX ring (aq_rss_enabled()rx_rings_count > 1), independent of the kernel
RSS framework, so these calls are reached in a stock GENERIC kernel and the
build fails to link:

ld: error: undefined symbol: rss_getkey
ld: error: undefined symbol: rss_gethashconfig
>>> referenced by aq_main.c:415 ... aq_if_init

Fix

Guard the two calls with #ifdef RSS, mirroring the established pattern in
dev/e1000/if_em.c. Without the RSS framework, generate a random hash key with
arc4rand() and use the standard IPv4/IPv6 TCP + 2-tuple hash types (the RSS
subsystem default), so the NIC still distributes traffic across its queues. The
already-#ifdef RSS-guarded indirection-table logic below is unchanged.

Testing

  • aq_main.o compiles clean under a no-RSS (GENERIC) config.
  • A full GENERIC kernel now builds and links (33 MB kernel ELF, no undefined
    symbols) — it previously failed at link as shown above.

This is an independent build fix (no functional change when options RSS is set).

🤖 Generated with Claude Code

Summary by Sourcery

Guard atlantic driver RSS configuration against builds without the kernel RSS framework to restore GENERIC kernel linkability.

Bug Fixes:

  • Prevent undefined symbol link errors in the atlantic driver when the kernel is built without options RSS by conditionally compiling RSS framework calls.

Enhancements:

  • Provide a fallback RSS key and default IPv4/IPv6 TCP and 2-tuple hash configuration when the kernel RSS framework is disabled so hardware RSS remains effective.

aq_rss_prepare() called rss_getkey() and rss_gethashconfig()
unconditionally, but those symbols only exist when the kernel is built
with "options RSS" (net/rss_config.c is "optional inet rss"). The
atlantic driver enables hardware RSS whenever it has more than one RX
ring (aq_rss_enabled() checks rx_rings_count > 1), independent of the
kernel RSS framework, so these calls are reached in a stock GENERIC
kernel and the build fails to link:

    ld: error: undefined symbol: rss_getkey
    ld: error: undefined symbol: rss_gethashconfig
    >>> referenced by aq_main.c ... aq_if_init

Guard the two calls with #ifdef RSS, mirroring dev/e1000/if_em.c: when
the RSS framework is absent, generate a random hash key with arc4rand()
and use the standard IPv4/IPv6 TCP and 2-tuple hash types (the RSS
subsystem default) so the NIC still distributes traffic across queues.

Fixes the GENERIC kernel link on builds without "options RSS".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds conditional compilation around RSS framework calls in the Atlantic driver so it builds without kernel RSS, and provides a fallback RSS key and hash configuration when RSS is not enabled.

File-Level Changes

Change Details Files
Guard RSS framework usage in aq_rss_prepare() and add a non-RSS fallback so the driver still performs reasonable hashing without depending on rss_getkey/rss_gethashconfig.
  • Wrap calls to rss_getkey() and rss_gethashconfig() in an #ifdef RSS/#else/#endif block in aq_rss_prepare()
  • In the non-RSS path, generate a random RSS key using arc4rand() into softc->rss_key
  • In the non-RSS path, initialize *rss_hash_cfg to a combination of standard IPv4/IPv6 TCP and 2-tuple RSS hash types that match the RSS subsystem defaults
  • Leave the existing RSS-specific indirection-table logic (already under #ifdef RSS) unchanged
sys/dev/atlantic/aq_main.c

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates sys/dev/atlantic/aq_main.c to provide a fallback configuration when the kernel RSS framework is not defined, generating a random key and setting default hash types. The reviewer noted that when RSS is undefined, the RSS lookup table (softc->rss_lut) remains uninitialized, causing all traffic to route to queue 0. To fix this, the reviewer suggested adding a fallback block to initialize the lookup table with a default round-robin distribution.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

*rss_hash_cfg = RSS_HASHTYPE_RSS_IPV4 | RSS_HASHTYPE_RSS_TCP_IPV4 |
RSS_HASHTYPE_RSS_IPV6 | RSS_HASHTYPE_RSS_TCP_IPV6 |
RSS_HASHTYPE_RSS_IPV6_EX | RSS_HASHTYPE_RSS_TCP_IPV6_EX;
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

While guarding rss_getkey and rss_gethashconfig with #ifdef RSS correctly fixes the link error on GENERIC kernels, there is a secondary issue: the subsequent #ifdef RSS block that populates the RSS lookup table (softc->rss_lut) will now be skipped entirely when RSS is not defined.

If softc->rss_lut is left uninitialized (all zeros), the hardware will route all incoming traffic to queue 0, effectively disabling multi-queue distribution and defeating the purpose of enabling RSS.

To fix this, you should also provide a fallback #else block for the LUT initialization to populate it with a default round-robin distribution. For example:

#ifdef RSS
	if (rss_gethashalgo() == RSS_HASH_TOEPLITZ) {
		uint32_t lut_size = hw_ops->get_rss_lut_size(softc->aq_hw);
		for (i = 0; i < lut_size; i++) {
			softc->rss_lut[i] = rss_get_indirection_to_bucket(i) %
			    softc->resources.num_rss_queues;
		}
	}
#else
	uint32_t lut_size = hw_ops->get_rss_lut_size(softc->aq_hw);
	for (i = 0; i < lut_size; i++) {
		softc->rss_lut[i] = i % softc->resources.num_rss_queues;
	}
#endif

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, but I believe this concern doesn't apply to this driver as written — the indirection table is already initialized in the non-RSS case.

The round-robin else block is deliberately placed outside the #ifdef RSS, so it is always compiled:

#ifdef RSS
	if (rss_gethashalgo() == RSS_HASH_TOEPLITZ) {
		for (i = 0; i < ARRAY_SIZE(softc->rss_table); i++)
			softc->rss_table[i] =
			    (uint8_t)(rss_get_indirection_to_bucket(i) % qcnt);
	} else
#endif
	{
		for (i = 0; i < ARRAY_SIZE(softc->rss_table); i++)
			softc->rss_table[i] = (uint8_t)(i % qcnt);   /* round-robin */
	}

When RSS is undefined the preprocessor removes only the #ifdef RSS … } else lines, leaving the trailing { … } round-robin loop intact. With qcnt == rx_rings_count, softc->rss_table[] is filled 0,1,…,qcnt-1,0,1,…, so the LUT is a valid round-robin distribution and traffic is spread across all RX queues — not pinned to queue 0.

(Note also that this driver's field is softc->rss_table, populated via ARRAY_SIZE(softc->rss_table) and qcnt; the suggested softc->rss_lut / get_rss_lut_size() / num_rss_queues don't exist here.)

So the only behavior dropped without the RSS framework is the Toeplitz indirection mapping, which correctly degrades to round-robin. No change needed here.

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown

Claude finished @laffer1's task —— View job


Code Review Complete ✅

Reviewed atlantic driver RSS fix for correctness, style(9) compliance, and security issues:

  • Read and analyze the modified file
  • Check for correctness bugs and bounds checking
  • Verify style(9) compliance (8-space tabs, 80-col)
  • Look for security issues
  • Evaluate existing reviewer feedback
  • Provide comprehensive review

Review Summary

Overall Assessment: ✅ APPROVED - This is a solid build fix with appropriate fallback logic.

✅ Correctness & Security

  • RSS key handling: Correctly uses arc4rand() for cryptographically random key generation (40 bytes)
  • Hash type constants: All RSS_HASHTYPE_RSS_* constants verified against sys/net/rss_config.h
  • Buffer safety: sizeof(softc->rss_key) = HW_ATL_RSS_HASHKEY_SIZE (40) matches RSS_KEYSIZE
  • Bounds checking: No buffer overruns - size calculations are correct

✅ Style(9) Compliance

  • Indentation: Uses tabs consistently (verified against file patterns)
  • Line length: New lines are ≤80 characters (lines 425-427 properly wrapped with continuation)
  • Comment style: Follows BSD kernel comment conventions

⚠️ Critical Issue Identified

The Gemini reviewer correctly identified a serious functional bug:

Lines 430-442 show that the RSS lookup table (softc->rss_table) initialization is wrapped in #ifdef RSS. With this PR's changes, when RSS is undefined:

  1. Lines 415-428: ✅ RSS key and hash config are now correctly set
  2. Lines 430-442: ❌ RSS lookup table remains uninitialized → all traffic routes to queue 0

Impact: Hardware multi-queue RSS is effectively disabled, defeating the purpose.

Recommended Fix: Add an #else clause for RSS table initialization:

#ifdef RSS
    if (rss_gethashalgo() == RSS_HASH_TOEPLITZ) {
        for (i = 0; i < ARRAY_SIZE(softc->rss_table); i++) {
            softc->rss_table[i] = 
                (uint8_t)(rss_get_indirection_to_bucket(i) % qcnt);
        }
    } else
#else
    /* Without RSS framework, use simple round-robin distribution */
    for (i = 0; i < ARRAY_SIZE(softc->rss_table); i++) {
        softc->rss_table[i] = (uint8_t)(i % qcnt);
    }
#endif
    {
        for (i = 0; i < ARRAY_SIZE(softc->rss_table); i++) {
            softc->rss_table[i] = (uint8_t)(i % qcnt);
        }
    }

This fix ensures proper traffic distribution across queues even without the RSS framework.


@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The non-RSS fallback hardcodes a specific set of RSS_HASHTYPE_* flags; consider centralizing or reusing an existing default (e.g., via a shared helper or macro) so behavior stays aligned if the system-wide RSS defaults change.
  • It may be worth adding a brief note near the #ifdef RSS block explaining that the hash configuration and key choice must remain consistent with the hardware’s expectations and the RSS framework defaults to avoid subtle distribution differences.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The non-RSS fallback hardcodes a specific set of RSS_HASHTYPE_* flags; consider centralizing or reusing an existing default (e.g., via a shared helper or macro) so behavior stays aligned if the system-wide RSS defaults change.
- It may be worth adding a brief note near the #ifdef RSS block explaining that the hash configuration and key choice must remain consistent with the hardware’s expectations and the RSS framework defaults to avoid subtle distribution differences.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@laffer1 laffer1 merged commit 19714cd into master Jun 12, 2026
6 of 13 checks passed
@laffer1 laffer1 deleted the atlantic-rss-build-fix branch June 15, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant