Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

numa: introduce --numa-distance #206

Merged
merged 1 commit into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,37 @@ Examples
1: 20 10
```

- Run the current kernel creating 4 NUMA nodes of 1GB each and assign
different distance costs between the NUMA nodes to simulate non-uniform
memory access:
```
$ vng -r --cpu 8 -m 4G \
> --numa 1G,cpus=0-1 --numa 1G,cpus=2-3 \
> --numa 1G,cpus=4-5 --numa 1G,cpus=6-7 \
> --numa-distance 0,1=51 --numa-distance 0,2=31 --numa-distance 0,3=41 \
> --numa-distance 1,2=21 --numa-distance 1,3=61 \
> --numa-distance 2,3=11 -- numactl -H
available: 4 nodes (0-3)
node 0 cpus: 0 1
node 0 size: 1006 MB
node 0 free: 974 MB
node 1 cpus: 2 3
node 1 size: 953 MB
node 1 free: 919 MB
node 2 cpus: 4 5
node 2 size: 943 MB
node 2 free: 894 MB
node 3 cpus: 6 7
node 3 size: 1006 MB
node 3 free: 965 MB
node distances:
node 0 1 2 3
0: 10 51 31 41
1: 51 10 21 61
2: 31 21 10 11
3: 41 61 11 10
```

- Run `glxgears` inside a kernel recompiled in the current directory:
```
$ vng -g -- glxgears
Expand Down
12 changes: 12 additions & 0 deletions virtme/commands/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ def make_parser() -> argparse.ArgumentParser:
default=None,
help="Create NUMA nodes in the guest.",
)
g.add_argument(
"--numa-distance",
action="append",
default=None,
help="Define a distance between two NUMA nodes in the guest (src=ID,dst=ID,val=NUM).",
)
g.add_argument(
"--cpus", action="store", default=None, help="Set guest cpu and qemu -smp flag."
)
Expand Down Expand Up @@ -1042,6 +1048,12 @@ def do_it() -> int:
"-numa", f"node,memdev=mem{i}{cpus}"
])

if args.numa_distance:
for arg in args.numa_distance:
qemuargs.extend([
"-numa", f"dist,{arg}"
])

if args.snaps:
if args.root == "/":
snapd_state = "/var/lib/snapd/state.json"
Expand Down
30 changes: 30 additions & 0 deletions virtme_ng/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,15 @@ def make_parser():
+ "This option implicitly disables the microvm architecture."
)

parser.add_argument(
"--numa-distance",
metavar="SRC,DST=VAL",
action="append",
help="Set a distance of VAL between NUMA node SRC_NODE and DST_NODE. "
+ "Use this option multiple times to define multiple distances between NUMA nodes. "
+ "This option is used only together with --numa."
)

parser.add_argument(
"--balloon",
action="store_true",
Expand Down Expand Up @@ -1084,6 +1093,25 @@ def _get_virtme_numa(self, args):
else:
self.virtme_param["numa"] = ""

def _get_virtme_numa_distance(self, args):
if args.numa_distance is not None:
if not args.numa:
arg_fail("error: --numa-distance can be used only with --numa", show_usage=False)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Because the issue is due to a wrong using, maybe show_usable=False is not needed?
But up to you, it is also easy to run vng -h :)

(Same below for the parsing issue).

Copy link
Owner Author

Choose a reason for hiding this comment

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

Yeah, initially I was showing the help, but I thought it was a bit too verbose and it could hide the actual error, so I added show_usage=False. :)

numa_dist_str = ""
for arg in args.numa_distance:
try:
nodes = arg.split('=')
src, dst = nodes[0].split(',')
val = nodes[1]
numa_dist_str += f" --numa-distance src={src},dst={dst},val={val}"
except ValueError:
err_msg = f"error: invalid distance '{arg}', " + \
"NUMA distance string must be in the format SRC,DST=VAL"
arg_fail(err_msg, show_usage=False)
self.virtme_param["numa_distance"] = numa_dist_str
Copy link
Collaborator

Choose a reason for hiding this comment

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

Out of curiosity, why not doing the parsing and moving this "complexity" to virtme-run?

Copy link
Owner Author

Choose a reason for hiding this comment

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

Out of curiosity, why not doing the parsing and moving this "complexity" to virtme-run?

At some point in the future I'd be nice to just drop virtme-run and have only vng. The virtme-run interface is maintained only for backward compatibility with the old virtme tool and vng is like a front-end to the old interface. But ultimately it'd be nice to drop the old interface and just have a front-end to qemu. That's the reason why I usually prefer to add complexity and new abstractions to vng directly.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Out of curiosity, why not doing the parsing and moving this "complexity" to virtme-run?

At some point in the future I'd be nice to just drop virtme-run and have only vng. The virtme-run interface is maintained only for backward compatibility with the old virtme tool and vng is like a front-end to the old interface. But ultimately it'd be nice to drop the old interface and just have a front-end to qemu. That's the reason why I usually prefer to add complexity and new abstractions to vng directly.

Thank you, I see! And that's not what I did in my previous PR :)

Please note that I'm still using virtme-run directly in my automated scripts, mainly because it works, and I don't need vng to build the kernel (I already had that, and when I switched, vng could not build the kernel in a different build dir :) ).

Copy link
Owner Author

Choose a reason for hiding this comment

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

It's ok, a lot of people are still using virtme-run. At some point we could also decide to do a big refactoring, merge everything into a single tool and provide backward compatible aliases. In fact, there's no reason to have a python script that calls another python script, it's just unnecessary overhead, but it's not terrible and we can live with that for now.

else:
self.virtme_param["numa_distance"] = ""

def _get_virtme_balloon(self, args):
if args.balloon:
self.virtme_param["balloon"] = "--balloon"
Expand Down Expand Up @@ -1178,6 +1206,7 @@ def run(self, args):
self._get_virtme_cpus(args)
self._get_virtme_memory(args)
self._get_virtme_numa(args)
self._get_virtme_numa_distance(args)
self._get_virtme_balloon(args)
self._get_virtme_gdb(args)
self._get_virtme_snaps(args)
Expand Down Expand Up @@ -1221,6 +1250,7 @@ def run(self, args):
+ f'{self.virtme_param["cpus"]} '
+ f'{self.virtme_param["memory"]} '
+ f'{self.virtme_param["numa"]} '
+ f'{self.virtme_param["numa_distance"]} '
+ f'{self.virtme_param["balloon"]} '
+ f'{self.virtme_param["gdb"]} '
+ f'{self.virtme_param["snaps"]} '
Expand Down
Loading