Skip to content

Conversation

@Anushree-Mathur
Copy link
Contributor

@Anushree-Mathur Anushree-Mathur commented Jan 7, 2026

Added a function to identify a nodeset consisting of only those numa node ids which has memory allocated to it.

This function is then used to retrieve the filtered NUMA nodeset, which is subsequently employed for hugepage memory backing. This ensures that hugepages are allocated only from nodes with actual memory resources. For example:
Host has 2 numa nodes with id as 0 and 4, but only numa node 4 has memory so that will be used to back the memory being used as a nodeset.
Signed-off-by: Anushree-Mathur [email protected]

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Improved guest NUMA node detection to accurately identify memory-enabled nodes, enabling more intelligent memory pinning support when hugepage functionality is enabled.
    • Enhanced fallback behavior for memory pinning configuration, providing smarter defaults when user-specified settings are unavailable.

✏️ Tip: You can customize this high-level summary in your review settings.

…d as nodeset!

Added a function to identify a nodeset consisting of only those
numa node ids which has memory allocated to it.

This function is then used to retrieve the filtered NUMA nodeset,
which is subsequently employed for hugepage memory backing. This
ensures that hugepages are allocated only from nodes with actual
memory resources. For example:
Host has 2 numa nodes with id as 0 and 4, but only numa node 4 has memory
so that will be used to back the memory being used as a nodeset.
Signed-off-by: Anushree-Mathur <[email protected]>
@coderabbitai
Copy link

coderabbitai bot commented Jan 7, 2026

Walkthrough

The change modifies the pin_numa function in virttest/libvirt_vm.py to improve guest NUMA node detection. A new helper function get_guest_numa() is introduced to dynamically identify guest NUMA nodes with allocated memory by parsing numactl -H output. This helper replaces the previous fallback behavior that pinned all host NUMA nodes when hugepage_pin is enabled without explicit guest NUMA specification. The existing host NUMA node validation and pinning logic remains unchanged. The subprocess module is imported to support command execution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: a function to filter NUMA node IDs that have allocated memory, which is the core objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@Anushree-Mathur Anushree-Mathur changed the title Function to filter NUMA node ids which has allocated memory! Function to filter NUMA node ids with allocated memory! Jan 7, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @virttest/libvirt_vm.py:
- Around line 677-690: The get_guest_numa function should use
avocado.utils.process instead of subprocess and add error handling: replace
sp.check_output("numactl -H", shell=True) with a call using process.run or
process.system to execute ["numactl", "-H"] without shell, catch
CalledProcessError (or check return code) and return a safe default (e.g., empty
string) or log the error before failing; update parsing to handle empty output
robustly; also remove the unused import subprocess as sp to keep imports
consistent.
🧹 Nitpick comments (1)
virttest/libvirt_vm.py (1)

17-17: Prefer using avocado.utils.process for consistency.

The codebase already imports and uses avocado.utils.process (line 24) for command execution. Using raw subprocess is inconsistent with the established patterns. Consider removing this import and using process.run() or process.getoutput() instead in the new helper function.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8cf2d8c and 30c4c3a.

📒 Files selected for processing (1)
  • virttest/libvirt_vm.py
🧰 Additional context used
🧬 Code graph analysis (1)
virttest/libvirt_vm.py (2)
virttest/remote_commander/remote_runner.py (1)
  • shell (660-676)
virttest/staging/utils_memory.py (1)
  • numa_nodes (94-107)
🪛 GitHub Actions: pre-commit
virttest/libvirt_vm.py

[error] 1206-1206: Trailing whitespace detected on line 1206; pre-commit hook trailing-whitespace fixed the line.

🪛 Ruff (0.14.10)
virttest/libvirt_vm.py

679-679: subprocess call with shell=True seems safe, but may be changed in the future; consider rewriting without shell

(S602)


679-679: Starting a process with a partial executable path

(S607)

Comment on lines +677 to +690
def get_guest_numa():
# Retrieve only NUMA nodes with allocated memory resources
out_numa = sp.check_output("numactl -H", shell=True).decode()
numa_nodes = []
for line in out_numa.splitlines():
line = line.strip()
if line.startswith("node") and "size:" in line:
parts = line.split()
node_id = parts[1]
size_mb = int(parts[3])
if size_mb > 0:
numa_nodes.append(node_id)

return ",".join(numa_nodes)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling and use process module for consistency.

This function has several issues:

  1. Missing error handling: If numactl is not installed or fails, sp.check_output raises CalledProcessError, causing VM creation to fail with an unhelpful traceback.

  2. Inconsistent with codebase patterns: The codebase uses avocado.utils.process for command execution. See virttest/staging/utils_memory.py for a similar pattern.

  3. Unnecessary shell=True: The command doesn't use shell features, so shell=True is not needed (flagged by static analysis S602/S607).

🔧 Suggested fix using process module with error handling
         def get_guest_numa():
             # Retrieve only NUMA nodes with allocated memory resources
-            out_numa = sp.check_output("numactl -H", shell=True).decode()
+            try:
+                result = process.run("numactl -H", shell=False, verbose=False)
+                out_numa = result.stdout_text
+            except process.CmdError as e:
+                LOG.warning("Failed to get NUMA info via numactl: %s", e)
+                return ""
             numa_nodes = []
             for line in out_numa.splitlines():
                 line = line.strip()
                 if line.startswith("node") and "size:" in line:
                     parts = line.split()
                     node_id = parts[1]
                     size_mb = int(parts[3])
                     if size_mb > 0:
                         numa_nodes.append(node_id)
 
             return ",".join(numa_nodes)

With this change, you can also remove the import subprocess as sp at line 17.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.14.10)

679-679: subprocess call with shell=True seems safe, but may be changed in the future; consider rewriting without shell

(S602)


679-679: Starting a process with a partial executable path

(S607)

🤖 Prompt for AI Agents
In @virttest/libvirt_vm.py around lines 677 - 690, The get_guest_numa function
should use avocado.utils.process instead of subprocess and add error handling:
replace sp.check_output("numactl -H", shell=True) with a call using process.run
or process.system to execute ["numactl", "-H"] without shell, catch
CalledProcessError (or check return code) and return a safe default (e.g., empty
string) or log the error before failing; update parsing to handle empty output
robustly; also remove the unused import subprocess as sp to keep imports
consistent.

Comment on lines 1206 to 1212
guest_numa = str(params.get("hugepage_pinned_numa"))
if guest_numa == "None":
# if user didn't mention hugepage_pinnned_numa use
# numa_nodes to back all the numa nodes.
guest_numa = int(params.get("numa_nodes", 2))
guest_numa = ",".join(map(str, list(range(guest_numa))))
# numa_nodes which has memory allocated, to back all
# the numa nodes.
guest_numa = get_guest_numa()
virt_install_cmd += pin_hugepage(help_text, hp_size, guest_numa)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix trailing whitespace and handle empty get_guest_numa() return.

  1. Line 1209 has trailing whitespace (flagged by pre-commit CI).

  2. If get_guest_numa() returns an empty string (e.g., numactl fails or no nodes have memory), passing an empty guest_numa to pin_hugepage() may produce invalid configuration.

🔧 Suggested fix
                 if guest_numa == "None":
                     # if user didn't mention hugepage_pinnned_numa use
-                    # numa_nodes which has memory allocated, to back all 
+                    # numa_nodes which has memory allocated, to back all
                     # the numa nodes.
                     guest_numa = get_guest_numa()
+                if not guest_numa:
+                    LOG.error("No NUMA nodes with allocated memory found for hugepage pinning")
+                else:
-                virt_install_cmd += pin_hugepage(help_text, hp_size, guest_numa)
+                    virt_install_cmd += pin_hugepage(help_text, hp_size, guest_numa)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
guest_numa = str(params.get("hugepage_pinned_numa"))
if guest_numa == "None":
# if user didn't mention hugepage_pinnned_numa use
# numa_nodes to back all the numa nodes.
guest_numa = int(params.get("numa_nodes", 2))
guest_numa = ",".join(map(str, list(range(guest_numa))))
# numa_nodes which has memory allocated, to back all
# the numa nodes.
guest_numa = get_guest_numa()
virt_install_cmd += pin_hugepage(help_text, hp_size, guest_numa)
guest_numa = str(params.get("hugepage_pinned_numa"))
if guest_numa == "None":
# if user didn't mention hugepage_pinnned_numa use
# numa_nodes which has memory allocated, to back all
# the numa nodes.
guest_numa = get_guest_numa()
if not guest_numa:
LOG.error("No NUMA nodes with allocated memory found for hugepage pinning")
else:
virt_install_cmd += pin_hugepage(help_text, hp_size, guest_numa)
🧰 Tools
🪛 GitHub Actions: pre-commit

[error] 1206-1206: Trailing whitespace detected on line 1206; pre-commit hook trailing-whitespace fixed the line.

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