Skip to content

Commit

Permalink
numa: introduce --numa-distance
Browse files Browse the repository at this point in the history
Introduce a new option `--numa-distance SRC,DST,VAL` to define the
distance cost between two NUMA nodes and simulate non-uniform memory
access.

Signed-off-by: Andrea Righi <[email protected]>
  • Loading branch information
arighi committed Dec 12, 2024
1 parent e499d36 commit 2b9c396
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
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 not args.numa:
arg_fail("error: --numa-distance can be used only with --numa", show_usage=False)
if args.numa_distance is not None:
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
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

0 comments on commit 2b9c396

Please sign in to comment.