700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 解决qemu虚拟机无法设置分辨率的问题

解决qemu虚拟机无法设置分辨率的问题

时间:2020-04-27 23:27:27

相关推荐

解决qemu虚拟机无法设置分辨率的问题

问题描述:

在虚拟机中进行修改分辨率测试,结果如下:

在win7中测试设置ok。

在Centos7、Ubuntu16.04、Ubuntu18.04中测试均不行。

系统中设置分辨率也只有win7有效,其余均无效,怀疑是QXL驱动问题。

问题排查分析如下:

查看日志中出现如下报错

Jul 2 15:22:28 Ubuntu1604 kernel: [ 6288.266180] qxl 0000:00:02.0: object_init failed for (4104192, 0x00000002)

Jul 2 15:22:28 Ubuntu1604 kernel: [ 6288.266190] [drm:qxl_gem_object_create [qxl]] ERROR Failed to allocate GEM object (4101120, 2, 4096, -12)

Jul 2 15:22:28 Ubuntu1604 kernel: [ 6288.266194] [drm:qxl_alloc_surf_ioctl [qxl]] ERROR qxl_alloc_surf_ioctl: failed to create gem ret=-12

首先对Linux中分辨率设置执行流程进行分析:

1)xorg自动识别pci显卡并使用相应驱动

xorg-server首先会获取到该pci设备的vendor_id,之后对其进行判断,当其值为0x1b36时判断为qxl

显卡设备,并在/usr/lib/xorg/modules/driver中寻找该设备的应用层驱动,qxl应用层驱动名为qxl_drv.so。

2)xorg中的分辨率设置执行流程

3)xf86-qxl中的分辨率设置执行流程

libdrm中的分辨率设置执行流程 kernel中的分辨率设置执行流程

主要出错点在ttm_bo_init中的drm_vma_offset_add,而分配size由drmmode_xf86crtc_resize决定并传入,分配该内存主要用于应用层和内核共享的famebuffer的内存区域,用于xorg存储图像,内核读取。

计算公式如下:

size = (width * cpp + 1) * height

其中cpp = (scrn->bitsPerPixel + 7) / 8

其中bpp一般为32,由于分配该存储空间之时前一段存储空间尚未销毁,实际大小粗略计算为

1920 × 4 × 1080 = 8M

即应为该framebuffer在内核中分配大约8M的共享空间。

而实际能分配内存的上限来自于初始化函数ttm_bo_init_mm中对显存的设置,分配见下调用函数:

ttm_bo_init_mm(&qdev->mman.bdev, TTM_PL_VRAM, num_io_pages);

其中初始化最大值取决于num_io_pages,该值通过如下计算可得出vram_size:

vram_size = num_io_pages * PAGE_SIZE / (1024 * 1024)

值vram_size来源于qemu-system-x86_64执行中使用的的参数vram_size=8388608,该参数由ovirt固定在程序中。

在客户机中运行:

$ lspci -v -s 00:02.000:02.0 VGA compatible controller: Red Hat, Inc. QXL paravirtual graphic card (rev 04) (prog-if 00 [VGA controller])Subsystem: Red Hat, Inc QEMU Virtual MachineFlags: fast devsel, IRQ 10Memory at f8000000 (32-bit, non-prefetchable) [size=64M]Memory at fc000000 (32-bit, non-prefetchable) [size=8M]Memory at fc850000 (32-bit, non-prefetchable) [size=8K]I/O ports at c040 [size=32]Expansion ROM at fc840000 [disabled] [size=64K]Kernel driver in use: qxlKernel modules: qxl

可以看到该fc000000中的vram_size是8M,而根据前面计算的new_framebuffer + old_framebuffer的大小

8M + n > vram_size,所以导致了分辨率设置失败,因为分配framebuffer失败。

通过如下命令更新数据库中:

update vmDevice SET vmDevice="{“specParams”:{“vgamem”:“65536”,“heads”:“1”,“vram”:“65536”,“ram”:“65536”},“type”:“video”,“device”:“qxl”,“deviceId”:“026af321-efc4-4859-9c13-5fcffd3f9c06”}" where vmDevice="{“specParams”:{“vgamem”:“16384”,“heads”:“1”,“vram”:“8192”,“ram”:“65536”},“type”:“video”,“device”:“qxl”,“deviceId”:“026af321-efc4-4859-9c13-5fcffd3f9c06”}";

关闭、重新启动虚拟机,执行如下:

$ lspci -v -s 00:02.000:02.0 VGA compatible controller: Red Hat, Inc. QXL paravirtual graphic card (rev 04) (prog-if 00 [VGA controller])Subsystem: Red Hat, Inc QEMU Virtual MachineFlags: fast devsel, IRQ 10Memory at f0000000 (32-bit, non-prefetchable) [size=128M]Memory at f8000000 (32-bit, non-prefetchable) [size=64M]Memory at fc050000 (32-bit, non-prefetchable) [size=8K]I/O ports at c040 [size=32]Expansion ROM at fc040000 [disabled] [size=64K]Kernel driver in use: qxlKernel modules: qxl

测试结果:

vram_size大小增大到64M,实测在ubuntu16.04, ubuntu18.04, Centos7中设置分辨率均正常。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。