Skip to content

NO-JIRA: e2e: fix: restart tuned pod after irqbalance test to prevent cpuset pollution - #1575

Open
Tal-or wants to merge 1 commit into
openshift:mainfrom
Tal-or:fix-infra-pod-cpuset-test
Open

NO-JIRA: e2e: fix: restart tuned pod after irqbalance test to prevent cpuset pollution#1575
Tal-or wants to merge 1 commit into
openshift:mainfrom
Tal-or:fix-infra-pod-cpuset-test

Conversation

@Tal-or

@Tal-or Tal-or commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

The irqbalance test Should not overwrite the banned CPU set on tuned restart creates a guaranteed pod (exclusive CPUs), then restarts the tuned pod while that guaranteed pod is still running.
The new tuned process starts with a narrowed CPU affinity mask (missing the exclusive CPUs).
When the guaranteed pod is later cleaned up, the cgroup cpuset expands but the tuned process's sched_setaffinity mask stays narrow.

If the cpu_management.go Ordered block runs after irqbalance.go, test test_id:87722 reads the tuned pod's stale process affinity via taskset and fails because it doesn't match the full online CPU set.

Fix: restart the tuned pod in the irqbalance test's defer cleanup after the guaranteed pod is deleted, so the tuned process picks up the current (full) default cpuset.

Summary by CodeRabbit

  • Bug Fixes
    • Improved performance test cleanup by restoring CPU affinity and recreating the tuned pod after checks.
    • Added readiness validation for the replacement pod before continuing, improving test reliability and reducing failures caused by incomplete pod recovery.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Walkthrough

The IRQ balance test cleanup now marks itself as a Ginkgo helper, deletes and recreates the tuned pod, waits through TunedForNode, restores CPU affinity, and logs restart completion.

Changes

IRQ balance cleanup

Layer / File(s) Summary
Tuned pod cleanup and restart
test/e2e/performanceprofile/functests/1_performance/irqbalance.go
Cleanup registers as a Ginkgo helper, validates tuned pod deletion, recreates the pod through TunedForNode, restores CPU affinity, and logs restart completion.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: yanirq, jmencak


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error The added By and testlog.Infof calls interpolate targetNode.Name into Ginkgo logs; Kubernetes node names can expose internal hostnames. Avoid logging targetNode.Name. Use a generic restart message or a reviewed, non-identifying node label.
✅ Passed checks (14 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed No test titles were added or modified in this PR. All existing test titles are static and contain no dynamic values such as pod names, timestamps, UUIDs, node names, or IP addresses.
Test Structure And Quality ✅ Passed The PR adds cleanup logic that registers the defer as a Ginkgo helper, restarts the tuned pod after test completion, includes appropriate timeouts via nodes.TunedForNode() and pods.DeleteAndSync(),...
Microshift Test Compatibility ✅ Passed The diff adds cleanup inside an existing DescribeTable; it adds no new Ginkgo test and uses core Pod/Node helpers, with no newly introduced unavailable MicroShift API.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The commit adds cleanup code to an existing DescribeTable; it adds no Ginkgo test and the test targets one worker node, so it makes no listed multi-node assumption.
Topology-Aware Scheduling Compatibility ✅ Passed The PR modifies only an e2e test cleanup. It adds no deployment, operator, controller, replica, affinity, toleration, spread, or PDB scheduling constraints.
Ote Binary Stdout Contract ✅ Passed Modified code in defer cleanup (lines 241-249) uses By() and testlog.Infof(), both writing to GinkgoWriter, and resides inside test case block—compliant with OTE stdout contract.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The patch only adds cleanup to an existing DescribeTable test; the added code uses cluster pod APIs and contains no IPv4 literals or external connectivity.
No-Weak-Crypto ✅ Passed The commit adds only pod cleanup and logging in irqbalance.go; its added lines and imports contain no weak crypto, custom crypto, or secret comparison.
Container-Privileges ✅ Passed PR modifies only a Go test file (irqbalance.go) with no container/K8s manifest changes. No privileged: true, hostPID, hostNetwork, hostIPC, SYS_ADMIN, or allowPrivilegeEscalation configurations are...
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: restarting the tuned pod after the irqbalance test to prevent cpuset pollution.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@qodo-for-rh-openshift

Copy link
Copy Markdown

PR Summary by Qodo

E2E: Restart tuned pod in IRQBalance cleanup to avoid stale CPU affinity

🐞 Bug fix 🧪 Tests 🕐 10-20 Minutes

Grey Divider

AI Description

• Add a cleanup restart of the tuned pod after the guaranteed test pod is deleted.
• Prevent tuned from keeping a narrowed sched_setaffinity mask after exclusive-CPU tests.
• Avoid cross-test cpuset/affinity “pollution” that can fail later CPU management checks.
Diagram

graph TD
  A["IRQBalance E2E test"] --> B["Guaranteed pod (exclusive CPUs)"] --> C["Restart tuned during test"] --> D["Tuned affinity becomes narrow"] --> E["Guaranteed pod deleted"] --> F["Default cpuset expands"] --> G["Cleanup: restart tuned again"] --> H["Tuned affinity reset clean"]
  H --> I["Later E2E reads affinity (taskset)"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Avoid restarting tuned while exclusive CPUs are held
  • ➕ Eliminates the root cause (tuned starting with a constrained affinity) rather than compensating later
  • ➕ Reduces churn in the tuned daemonset during the test
  • ➖ May require reworking the test’s intent/coverage (it explicitly validates behavior across tuned restart)
  • ➖ Harder to guarantee equivalent validation without a restart at the critical moment
2. Reset tuned process affinity without a pod restart
  • ➕ Less disruptive than deleting the tuned pod
  • ➕ Targets only the problematic state (sched_setaffinity)
  • ➖ Requires privileged in-pod operations or node-level manipulation, increasing complexity and risk
  • ➖ More brittle across tuned versions/process layouts than a clean restart
3. Isolate/serialize CPU-management-affinity validations across suites
  • ➕ Reduces cross-test interference without changing test semantics
  • ➖ Longer suite runtime and more ordering constraints
  • ➖ Doesn’t fix the underlying state leak; just hides it

Recommendation: The chosen approach (restarting tuned in the test’s deferred cleanup after deleting the guaranteed pod) is the best tradeoff: it preserves the test’s restart coverage while ensuring the node returns to a clean baseline for subsequent tests. Alternatives either weaken the test’s purpose or add operational complexity.

Files changed (1) +10 / -0

Tests (1) +10 / -0
irqbalance.goRestart tuned in deferred cleanup to reset CPU affinity after exclusive-CPU pod +10/-0

Restart tuned in deferred cleanup to reset CPU affinity after exclusive-CPU pod

• Adds a deferred cleanup step that deletes and waits for the tuned pod to restart after the guaranteed test pod is removed. This ensures tuned reinitializes with the current full default cpuset/CPU affinity, preventing later E2E tests from observing a stale narrowed affinity mask.

test/e2e/performanceprofile/functests/1_performance/irqbalance.go

@openshift-ci

openshift-ci Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Tal-or
Once this PR has been reviewed and has the lgtm label, please assign ffromani for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@Tal-or Tal-or changed the title E2E: Restart tuned pod after irqbalance test to prevent cpuset pollution e2e: fix: Restart tuned pod after irqbalance test to prevent cpuset pollution Aug 4, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
test/e2e/performanceprofile/functests/1_performance/irqbalance.go (1)

246-246: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Pass a bounded context to the cleanup API call.

context.TODO() has no cancellation or deadline. A blocked Kubernetes delete request can outlive the test timeout. Use the test context or create a finite cleanup context. Pass the same context through nodes.TunedForNode instead of creating another context.TODO() in that helper.

As per path instructions: Go code must use context.Context for cancellation and timeouts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/performanceprofile/functests/1_performance/irqbalance.go` at line
246, Update the cleanup flow around pods.DeleteAndSync to use the test’s bounded
context instead of context.TODO(), and propagate that same context through
nodes.TunedForNode rather than creating another TODO context in the helper.
Ensure the Kubernetes deletion and tuned-pod lookup honor cancellation and
deadlines via context.Context.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/e2e/performanceprofile/functests/1_performance/irqbalance.go`:
- Around line 247-248: The call to nodes.TunedForNode can return a pod before
its containers are actually ready, causing the testlog.Infof at line 248 to log
false success when Status.ContainerStatuses is still empty. Add an explicit
readiness check (such as a PodReady wait) after the TunedForNode call completes
and before the testlog.Infof call to verify that the pod's container statuses
are populated and the containers are ready, ensuring the restart success is only
logged when TuneD is truly running.
- Around line 240-248: The TuneD restart currently runs in the normal control
flow and can be skipped when final-state assertions fail. Move the deletion and
synchronization logic for the tuned pod identified by TunedForNode into an
independent cleanup handler that executes after test-pod deletion, so it still
runs when Ginkgo Fail/Expect aborts the main flow; preserve the existing restart
and clean-affinity behavior.

---

Nitpick comments:
In `@test/e2e/performanceprofile/functests/1_performance/irqbalance.go`:
- Line 246: Update the cleanup flow around pods.DeleteAndSync to use the test’s
bounded context instead of context.TODO(), and propagate that same context
through nodes.TunedForNode rather than creating another TODO context in the
helper. Ensure the Kubernetes deletion and tuned-pod lookup honor cancellation
and deadlines via context.Context.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e6c3fed8-cdad-4eb6-be6a-e26ba28d68c3

📥 Commits

Reviewing files that changed from the base of the PR and between 215d1ea and a741c3e.

📒 Files selected for processing (1)
  • test/e2e/performanceprofile/functests/1_performance/irqbalance.go

Comment thread test/e2e/performanceprofile/functests/1_performance/irqbalance.go
Comment on lines +247 to +248
nodes.TunedForNode(targetNode, RunningOnSingleNode)
testlog.Infof("tuned pod restarted on node %q with clean CPU affinity", targetNode.Name)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Require a real readiness check before logging the restart.

At Line 247, nodes.TunedForNode can return a pod while Status.ContainerStatuses is empty. Its polling loop then succeeds without checking readiness. A newly recreated pod can reach this state before TuneD is ready. Line 248 can log false success, and the next test can start too early.

Update TunedForNode to require populated container statuses and ready containers, or use an explicit PodReady wait here.

Suggested helper guard
        if len(tunedList.Items) == 0 {
            return false
        }
+       if len(tunedList.Items[0].Status.ContainerStatuses) == 0 {
+           return false
+       }
        for _, s := range tunedList.Items[0].Status.ContainerStatuses {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/performanceprofile/functests/1_performance/irqbalance.go` around
lines 247 - 248, The call to nodes.TunedForNode can return a pod before its
containers are actually ready, causing the testlog.Infof at line 248 to log
false success when Status.ContainerStatuses is still empty. Add an explicit
readiness check (such as a PodReady wait) after the TunedForNode call completes
and before the testlog.Infof call to verify that the pod's container statuses
are populated and the containers are ready, ensuring the restart success is only
logged when TuneD is truly running.

@qodo-for-rh-openshift

qodo-for-rh-openshift Bot commented Aug 4, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Cleanup assertions obscure failures 🐞 Bug ☼ Reliability
Description
The new tuned restart runs inside a Go defer and uses Expect(...) plus nodes.TunedForNode(...)
(which asserts via Eventually(...).Should(...)), so a cleanup problem can add secondary failures
that obscure the original test failure context.
This makes diagnosing the primary failure harder when the spec is already failing and the cleanup
path hits transient tuned/API issues.
Code

test/e2e/performanceprofile/functests/1_performance/irqbalance.go[R244-247]

+				By(fmt.Sprintf("restarting tuned pod on %s to restore clean CPU affinity", targetNode.Name))
+				tunedPod := nodes.TunedForNode(targetNode, RunningOnSingleNode)
+				Expect(pods.DeleteAndSync(context.TODO(), testclient.DataPlaneClient, tunedPod)).To(Succeed(), "failed to delete tuned pod on node %q", targetNode.Name)
+				nodes.TunedForNode(targetNode, RunningOnSingleNode)
Relevance

●●● Strong

Team previously accepted softening DeferCleanup failures (log/warn, bounded cleanup) to avoid
obscuring test failures.

PR-#1556

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The added tuned restart is executed in a deferred cleanup and includes assertions; additionally,
nodes.TunedForNode asserts internally using Eventually(...).Should(...), increasing the chance
of secondary failures during cleanup.

test/e2e/performanceprofile/functests/1_performance/irqbalance.go[225-249]
test/e2e/performanceprofile/functests/utils/nodes/nodes.go[379-405]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The tuned restart logic was added inside a Go `defer` and contains multiple assertions (`Expect(...)` and the assertion inside `nodes.TunedForNode`). If the spec already failed, a cleanup failure can add additional failures and make the original failure harder to interpret.

## Issue Context
`nodes.TunedForNode` performs an `Eventually(...).Should(...)` assertion internally and can wait for a long time before failing. Executing this in a Go `defer` means failures are not clearly separated as cleanup failures.

## Fix Focus Areas
- test/e2e/performanceprofile/functests/1_performance/irqbalance.go[225-249]

## Suggested fix
Convert the Go `defer func() { ... }()` cleanup to Ginkgo `DeferCleanup(...)` so failures are attributed to cleanup rather than confusing the primary assertion failure. Use the `cleanupCtx` parameter (or a derived context with timeout) for API calls, and consider recording/logging errors in cleanup separately from the main test expectations if you want to preserve the original failure signal.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Cleanup can block too long 🐞 Bug ➹ Performance
Description
The added tuned restart cleanup does two nodes.TunedForNode(...) waits (up to 480s each) plus a
pod deletion wait (up to 120s), so a single spec’s cleanup can be delayed by many minutes when tuned
is slow/unhealthy.
This can significantly slow feedback in failure scenarios and make unrelated failures take much
longer to complete.
Code

test/e2e/performanceprofile/functests/1_performance/irqbalance.go[R245-248]

+				tunedPod := nodes.TunedForNode(targetNode, RunningOnSingleNode)
+				Expect(pods.DeleteAndSync(context.TODO(), testclient.DataPlaneClient, tunedPod)).To(Succeed(), "failed to delete tuned pod on node %q", targetNode.Name)
+				nodes.TunedForNode(targetNode, RunningOnSingleNode)
+				testlog.Infof("tuned pod restarted on node %q with clean CPU affinity", targetNode.Name)
Relevance

●●● Strong

Historical precedent favors bounding cleanup operations to prevent long/stalled DeferCleanup delays.

PR-#1556

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The cleanup calls nodes.TunedForNode twice; each call can wait up to 480 seconds. It also calls
pods.DeleteAndSync, which waits up to 120 seconds for deletion, so worst-case cleanup delay is
substantial.

test/e2e/performanceprofile/functests/1_performance/irqbalance.go[240-249]
test/e2e/performanceprofile/functests/utils/nodes/nodes.go[35-38]
test/e2e/performanceprofile/functests/utils/nodes/nodes.go[379-405]
test/e2e/performanceprofile/functests/utils/pods/pods.go[35-37]
test/e2e/performanceprofile/functests/utils/pods/pods.go[100-121]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new cleanup performs:
- `nodes.TunedForNode(...)` (waits up to `testTimeout=480s`)
- `pods.DeleteAndSync(...)` (waits up to `DefaultDeletionTimeout=120s`)
- another `nodes.TunedForNode(...)` (another up to 480s)

In failure scenarios, this can delay cleanup completion by a large amount.

## Issue Context
`nodes.TunedForNode` is implemented with `Eventually(..., cluster.ComputeTestTimeout(testTimeout*time.Second, sno), ...)` and `testTimeout` is 480 seconds.

## Fix Focus Areas
- test/e2e/performanceprofile/functests/1_performance/irqbalance.go[240-248]
- test/e2e/performanceprofile/functests/utils/nodes/nodes.go[35-38]
- test/e2e/performanceprofile/functests/utils/nodes/nodes.go[379-405]

## Suggested fix
In the cleanup, avoid the first long readiness wait before deletion:
- List the tuned pods for the node once (no `Eventually`), delete what you find (handling NotFound / empty list gracefully), then do a single `nodes.TunedForNode(...)` wait to ensure tuned is back.
- Alternatively, add a new helper like `nodes.TunedForNodeWithTimeout(node, sno, timeout)` and use a shorter timeout specifically for cleanup.

Also consider running the cleanup under a bounded context (`cleanupCtx` from `DeferCleanup`, optionally wrapped with `context.WithTimeout`) so the cleanup can’t stall indefinitely if the API server is degraded.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment on lines +244 to +247
By(fmt.Sprintf("restarting tuned pod on %s to restore clean CPU affinity", targetNode.Name))
tunedPod := nodes.TunedForNode(targetNode, RunningOnSingleNode)
Expect(pods.DeleteAndSync(context.TODO(), testclient.DataPlaneClient, tunedPod)).To(Succeed(), "failed to delete tuned pod on node %q", targetNode.Name)
nodes.TunedForNode(targetNode, RunningOnSingleNode)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

1. Cleanup assertions obscure failures 🐞 Bug ☼ Reliability

The new tuned restart runs inside a Go defer and uses Expect(...) plus nodes.TunedForNode(...)
(which asserts via Eventually(...).Should(...)), so a cleanup problem can add secondary failures
that obscure the original test failure context.
This makes diagnosing the primary failure harder when the spec is already failing and the cleanup
path hits transient tuned/API issues.
Agent Prompt
## Issue description
The tuned restart logic was added inside a Go `defer` and contains multiple assertions (`Expect(...)` and the assertion inside `nodes.TunedForNode`). If the spec already failed, a cleanup failure can add additional failures and make the original failure harder to interpret.

## Issue Context
`nodes.TunedForNode` performs an `Eventually(...).Should(...)` assertion internally and can wait for a long time before failing. Executing this in a Go `defer` means failures are not clearly separated as cleanup failures.

## Fix Focus Areas
- test/e2e/performanceprofile/functests/1_performance/irqbalance.go[225-249]

## Suggested fix
Convert the Go `defer func() { ... }()` cleanup to Ginkgo `DeferCleanup(...)` so failures are attributed to cleanup rather than confusing the primary assertion failure. Use the `cleanupCtx` parameter (or a derived context with timeout) for API calls, and consider recording/logging errors in cleanup separately from the main test expectations if you want to preserve the original failure signal.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +245 to +248
tunedPod := nodes.TunedForNode(targetNode, RunningOnSingleNode)
Expect(pods.DeleteAndSync(context.TODO(), testclient.DataPlaneClient, tunedPod)).To(Succeed(), "failed to delete tuned pod on node %q", targetNode.Name)
nodes.TunedForNode(targetNode, RunningOnSingleNode)
testlog.Infof("tuned pod restarted on node %q with clean CPU affinity", targetNode.Name)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

2. Cleanup can block too long 🐞 Bug ➹ Performance

The added tuned restart cleanup does two nodes.TunedForNode(...) waits (up to 480s each) plus a
pod deletion wait (up to 120s), so a single spec’s cleanup can be delayed by many minutes when tuned
is slow/unhealthy.
This can significantly slow feedback in failure scenarios and make unrelated failures take much
longer to complete.
Agent Prompt
## Issue description
The new cleanup performs:
- `nodes.TunedForNode(...)` (waits up to `testTimeout=480s`)
- `pods.DeleteAndSync(...)` (waits up to `DefaultDeletionTimeout=120s`)
- another `nodes.TunedForNode(...)` (another up to 480s)

In failure scenarios, this can delay cleanup completion by a large amount.

## Issue Context
`nodes.TunedForNode` is implemented with `Eventually(..., cluster.ComputeTestTimeout(testTimeout*time.Second, sno), ...)` and `testTimeout` is 480 seconds.

## Fix Focus Areas
- test/e2e/performanceprofile/functests/1_performance/irqbalance.go[240-248]
- test/e2e/performanceprofile/functests/utils/nodes/nodes.go[35-38]
- test/e2e/performanceprofile/functests/utils/nodes/nodes.go[379-405]

## Suggested fix
In the cleanup, avoid the first long readiness wait before deletion:
- List the tuned pods for the node once (no `Eventually`), delete what you find (handling NotFound / empty list gracefully), then do a single `nodes.TunedForNode(...)` wait to ensure tuned is back.
- Alternatively, add a new helper like `nodes.TunedForNodeWithTimeout(node, sno, timeout)` and use a shorter timeout specifically for cleanup.

Also consider running the cleanup under a bounded context (`cleanupCtx` from `DeferCleanup`, optionally wrapped with `context.WithTimeout`) so the cleanup can’t stall indefinitely if the API server is degraded.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

The irqbalance test "Should not overwrite the banned CPU set on tuned
restart" creates a guaranteed pod (exclusive CPUs), then restarts the
tuned pod while that guaranteed pod is still running. The new tuned
process starts with a narrowed CPU affinity mask (missing the exclusive
CPUs). When the guaranteed pod is later cleaned up, the cgroup cpuset
expands but the tuned process's sched_setaffinity mask stays narrow.

If the cpu_management.go Ordered block runs after irqbalance.go, test
test_id:87722 reads the tuned pod's stale process affinity via taskset
and fails because it doesn't match the full online CPU set.

Fix: restart the tuned pod in the irqbalance test's defer cleanup after
the guaranteed pod is deleted, so the tuned process picks up the current
(full) default cpuset.

AIA Human-AI blend, Content edits, Human-initiated, Reviewed, Claude Opus 4.6 v1.0
Signed-off-by: titzhak <titzhak@redhat.com>
@Tal-or
Tal-or force-pushed the fix-infra-pod-cpuset-test branch from a741c3e to ff1c580 Compare August 4, 2026 15:28
@yanirq

yanirq commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 4, 2026
@Tal-or

Tal-or commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

/retest
infra issue

@Tal-or Tal-or changed the title e2e: fix: Restart tuned pod after irqbalance test to prevent cpuset pollution e2e: fix: restart tuned pod after irqbalance test to prevent cpuset pollution Aug 5, 2026
@openshift-ci

openshift-ci Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

@Tal-or: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@Tal-or Tal-or changed the title e2e: fix: restart tuned pod after irqbalance test to prevent cpuset pollution NO-JIRA: e2e: fix: restart tuned pod after irqbalance test to prevent cpuset pollution Aug 5, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Aug 5, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@Tal-or: This pull request explicitly references no jira issue.

Details

In response to this:

The irqbalance test Should not overwrite the banned CPU set on tuned restart creates a guaranteed pod (exclusive CPUs), then restarts the tuned pod while that guaranteed pod is still running.
The new tuned process starts with a narrowed CPU affinity mask (missing the exclusive CPUs).
When the guaranteed pod is later cleaned up, the cgroup cpuset expands but the tuned process's sched_setaffinity mask stays narrow.

If the cpu_management.go Ordered block runs after irqbalance.go, test test_id:87722 reads the tuned pod's stale process affinity via taskset and fails because it doesn't match the full online CPU set.

Fix: restart the tuned pod in the irqbalance test's defer cleanup after the guaranteed pod is deleted, so the tuned process picks up the current (full) default cpuset.

Summary by CodeRabbit

  • Bug Fixes
  • Improved performance test cleanup by restoring CPU affinity and recreating the tuned pod after checks.
  • Added readiness validation for the replacement pod before continuing, improving test reliability and reducing failures caused by incomplete pod recovery.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@Tal-or

Tal-or commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

/verified by @Tal-or

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Aug 5, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@Tal-or: This PR has been marked as verified by @Tal-or.

Details

In response to this:

/verified by @Tal-or

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@MarSik

MarSik commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Hmm, shouldn't the real fix be in the place where tuned detects the available cpus? Because if Tuned pod starts after a guaranteed pod on a real cluster deployment and this happens then we will have a misconfigured system too, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants