1
0
Fork 0

improve configuration and optimize

This commit is contained in:
Massaki Archambault 2021-03-04 17:03:16 -05:00
parent 0706cb784b
commit 2e0f4c91b4
8 changed files with 160 additions and 59 deletions

View File

@ -5,5 +5,10 @@
- '8086:15b8' # Intel Corporation Ethernet Connection (2) I219-V
- '1002:731f' # Advanced Micro Devices, Inc. [AMD/ATI] Navi 10 [Radeon RX 5700 / 5700 XT]
- '1002:ab38' # Advanced Micro Devices, Inc. [AMD/ATI] Navi 10 HDMI Audio
usb_device_ids:
- '054c:05c4' # Sony Corp. DualShock 4 [CUH-ZCT1x]
- '046d:c539' # Logitech, Inc. USB Receiver
- '046d:c08d' # Logitech, Inc. G502 LIGHTSPEED Wireless Gaming Mouse
kbd_device_path: '/dev/input/by-id/usb-0d3d_USBPS2-event-kbd'
roles:
- win10

View File

@ -1 +1,3 @@
pcie_device_ids: []
usb_device_ids: []
kbd_device_path: ''

View File

@ -1,56 +1,28 @@
#!/bin/bash
prepare() {
systemctl start vm-usb-helper
systemctl start win10-usb
vfio-isolate -u /tmp/win10.undo \
drop-caches \
compact-memory \
irq-affinity mask C1-3,5-7 \
cpuset-create --cpus C0,4 /host.slice \
cpuset-create --cpus C1-3,5-7 -nlb /win10.slice \
move-tasks / /host.slice \
cpu-governor performance C0-7
echo "Defrag RAM"
echo 1 > /proc/sys/vm/compact_memory
for _ in $(seq 5); do
sleep 3
# assign hugepages
sysctl -w vm.nr_hugepages=8192 && break
done
sleep 10
echo "Setup cpuset cgroup for host"
sudo cset set -c 0,4 -s system
sudo cset proc -m -f root -t system
sudo cset proc -k -f root -t system --force
echo "Setup cpumask"
for i in /sys/devices/virtual/workqueue/*/cpumask; do
sudo sh -c "echo 001 > $i"
done;
echo "Setup interrupt affinity"
for i in $(sed -n -e 's/ \([0-9]\+\):.*vfio.*/\1/p' /proc/interrupts); do
sudo sh -c "echo 0,4 > /proc/irq/$i/smp_affinity_list"
done
echo "Set the CPU frequency governor to performance"
for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo performance >$f
done
}
release() {
echo "Restore system"
# irq
for i in $(sed -n -e 's/ \([0-9]\+\):.*vfio.*/\1/p' /proc/interrupts); do
sudo sh -c "echo ff > /proc/irq/$i/smp_affinity"
done
# cpumask
for i in /sys/devices/virtual/workqueue/*/cpumask; do
sudo sh -c "echo ff > $i"
done;
# cpuset
sudo cset set -d system &>/dev/null
for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo powersave >$f
done
systemctl stop vm-usb-helper
vfio-isolate restore /tmp/win10.undo
systemctl stop win10-usb
sysctl -w vm.nr_hugepages=0
}

99
roles/win10/files/vfio-usb Executable file
View File

@ -0,0 +1,99 @@
#!/bin/python3
import os
import sys
import logging
import argparse
import subprocess
from tempfile import NamedTemporaryFile
import evdev
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()
virsh_logger = logging.getLogger('virsh')
usb_xmls = []
def listen():
logger.info('Listening for events on %s', args.evdev_kbd)
device = evdev.InputDevice(args.evdev_kbd)
left_ctrl = False
right_ctrl = False
triggered = False
grabbed = False
for event in device.read_loop():
logger.debug('Got event: %s', event)
if grabbed and event.code != 0:
grabbed = False
on_release()
if event.code == evdev.ecodes.ecodes['KEY_LEFTCTRL']:
left_ctrl = event.value != 0
elif event.code == evdev.ecodes.ecodes['KEY_RIGHTCTRL']:
right_ctrl = event.value != 0
if left_ctrl and right_ctrl:
triggered = True
elif triggered and not left_ctrl and not right_ctrl:
triggered = False
grabbed = True
on_grab()
def on_grab():
logger.info('Grabbed')
for usb_xml in usb_xmls:
invoke_virsh('attach-device', args.domain, usb_xml.name)
def on_release():
logger.info('Released')
for usb_xml in usb_xmls:
invoke_virsh('detach-device', args.domain, usb_xml.name)
def invoke_virsh(subcommand, domain, xml_name):
proc = subprocess.Popen(('virsh', subcommand, domain, xml_name),
encoding='utf8',
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
for line in stdout.strip().splitlines():
virsh_logger.info(line)
for line in stderr.strip().splitlines():
virsh_logger.error(line)
if __name__ == '__main__':
if os.geteuid() != 0:
logger.error('This script must be run as root')
sys.exit(1)
parser = argparse.ArgumentParser()
parser.add_argument('--evdev-kbd',
help='The evdev keyboard device to read eg: /dev/input/...',
required=True)
parser.add_argument('domain',
help='The libvirt domain to attach the usb devices to')
parser.add_argument('usb_ids',
help='The ids of the usb devices to attach, formatted as idVendor:idProduct',
nargs='+')
args = parser.parse_args()
logger.debug(args)
try:
for id_vendor, id_product in [x.split(':') for x in args.usb_ids]:
usb_xml = NamedTemporaryFile('w+')
usb_xml.write('<hostdev mode="subsystem" type="usb" managed="yes">\n')
usb_xml.write(' <source>\n')
usb_xml.write(' <vendor id="0x%s"/>\n' % id_vendor)
usb_xml.write(' <product id="0x%s"/>\n' % id_product)
usb_xml.write('</source>\n')
usb_xml.write('</hostdev>')
usb_xml.seek(0)
logger.debug('Created usb device xml:\n%s', usb_xml.read())
usb_xmls.append(usb_xml)
listen()
finally:
for usb_xml in usb_xmls:
usb_xml.close()

View File

@ -1,6 +1,10 @@
- name: regenerate linux initramfs
command: /usr/bin/mkinitcpio -p linux
- name: reload systemd services
systemd:
daemon_reload: yes
- name: restart libvirtd.service
systemd:
name: libvirtd.service

View File

@ -9,11 +9,35 @@
- restart libvirtd.socket
- restart virtlogd.socket
# TODO
# - name: install required packages from aur
# aur:
# name:
# - vfio-isolate
- name: create hooks directory
file:
path: /etc/libvirt/hooks
state: directory
- name: install qemu hook
copy:
src: hooks/qemu
dest: /etc/libvirt/hooks/qemu
mode: '755'
- name: install vfio-usb
copy:
src: vfio-usb
dest: /usr/bin/vfio-usb
mode: '755'
- name: install win10-usb service
template:
src: win10-usb.service.j2
dest: /etc/systemd/system/win10-usb.service
notify: reload systemd services
- name: configure kernel modules
lineinfile:
path: /etc/mkinitcpio.conf
@ -73,35 +97,22 @@
"/dev/random", "/dev/urandom",
"/dev/ptmx", "/dev/kvm", "/dev/kqemu",
"/dev/rtc","/dev/hpet", "/dev/sev",
"/dev/input/by-path/platform-i8042-serio-0-event-kbd"
"{{ kbd_device_path }}"
]
- name: install domain configuration
copy:
template:
src: win10.xml
dest: /etc/libvirt/qemu/win10.xml
validate: /usr/bin/virt-xml-validate %s
notify: restart libvirtd.service
- name: install qemu hook
copy:
src: hooks/qemu
dest: /etc/libvirt/hooks/qemu
mode: '755'
# - name: configure systemd CPUAffinity
# lineinfile:
# path: /etc/systemd/system.conf
# regexp: '^#?CPUAffinity'
# line: 'CPUAffinity=0 4'
- name: configure pulseaudio tcp socket
lineinfile:
path: /etc/pulse/default.pa
regexp: '^#?load-module module-native-protocol-tcp'
line: 'load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1'
- name: enable libvirtd.socket
systemd:
name: libvirtd.socket

View File

@ -0,0 +1,8 @@
[Unit]
Description=Attach usb devices to vm
[Service]
ExecStart=/usr/bin/vfio-usb win10 --evdev-kbd "{{ kbd_device_path }}" {{ ' '.join(usb_device_ids) }}
Restart=always

View File

@ -163,17 +163,17 @@
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</controller>
<interface type='network'>
<interface type='bridge'>
<mac address='52:54:00:f5:2c:df'/>
<source network='default'/>
<model type='e1000e'/>
<source bridge='virbr0'/>
<model type='virtio'/>
<link state='up'/>
<address type='pci' domain='0x0000' bus='0x08' slot='0x00' function='0x0'/>
</interface>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<graphics type='spice'>
<listen type='socket' socket='/tmp/spice-win10.sock'/>
<listen type='socket' socket='/tmp/win10-spice.sock'/>
<image compression='off' />
<mouse mode='server'/>
<filetransfer enable='no'/>
@ -217,7 +217,7 @@
<qemu:commandline>
<!-- keyboard evdev passthrough -->
<qemu:arg value='-object'/>
<qemu:arg value='input-linux,id=kbd1,evdev=/dev/input/by-path/platform-i8042-serio-0-event-kbd,grab_all=off,repeat=on'/>
<qemu:arg value='input-linux,id=kbd1,evdev={{ kbd_device_path }},grab_all=off,repeat=on'/>
<!-- audio passthrough -->
<qemu:arg value='-audiodev'/>
<qemu:arg value="driver=pa,id=hda,server=/run/user/1000/pulse/native,out.buffer-length=2000,timer-period=1000"/>