解决qemu虚拟机图形界面卡死问题

2023-11-18

1)基础环境

Virtio-gpu双heads+4.9.0内核+xserver1.9.3+modesettings0.5.0驱动

2)问题描述

终端中打开大量文字内容,不停上下滑动,或cat大量内容的文件,操作过程中用户界面卡死,如下:
在这里插入图片描述

3)基础排查

稳定复现方法:
$ cat /var/log/syslog
$ 上下滑动滚轮
卡死后:
kill pid of X能解决这个问题

kill掉kde程序仍然死机,只有kill掉xserver程序才能弹回登录界面恢复响应,并且屏幕响应鼠标移动事件,不响应点击事件和键盘输入事件。
只在日志中发现kdm的报错:
localhost kdm_greet[2336]: Can’t open default user face

4)排查分析

重新执行后发现内核中出现drm ioctl报错,并且重复测试后每次均会出现该问题:
[drm:drm_ioctl [drm]] pid=2285, dev=0xe200, auth=1, DRM_IOCTL_MODE_DIRTYFB
[drm:drm_mode_object_unreference [drm]] OBJ ID: 105 (6)
[drm:drm_ioctl [drm]] pid=2285, dev=0xe200, auth=1, DRM_IOCTL_MODE_DIRTYFB
[drm:drm_mode_object_unreference [drm]] OBJ ID: 105 (6)
[drm:drm_ioctl [drm]] pid=2285, dev=0xe200, auth=1, DRM_IOCTL_MODE_DIRTYFB
[drm:drm_mode_object_unreference [drm]] OBJ ID: 105 (6)
2019-10-16T01:34:21.108908+08:00 localhost kernel: [ 90.915464] [drm:drm_ioctl [drm]] ret = -22

-22出错代表EINVAL,通过strace跟踪xorg也发现了这个问题:
ioctl(10, 0xc01864b1, 0x7ffeaaed3e80) = -1 EINVAL (Invalid argument)
其中:
0xc01864b1代表的DRM_IOCTL_MODE_DIRTYFB
0x7ffeaaed3e80是参数地址

DRM_IOCTL_MODE_DIRTYFB调用执行如下:

int drm_mode_dirtyfb_ioctl(struct drm_device *dev, 
             void *data, struct drm_file *file_priv) 
{ 
    struct drm_clip_rect __user *clips_ptr; 
    struct drm_clip_rect *clips = NULL; 
    struct drm_mode_fb_dirty_cmd *r = data; 
    struct drm_framebuffer *fb; 
    unsigned flags; 
    int num_clips; 
    int ret; 
    
    if (!drm_core_check_feature(dev, DRIVER_MODESET)) 
        return -EINVAL; 

    fb = drm_framebuffer_lookup(dev, r->fb_id); 
    if (!fb) 
        return -ENOENT; 
        
    num_clips = r->num_clips; 
    clips_ptr = (struct drm_clip_rect __user *)(unsigned long)r->clips_ptr; 
    if (!num_clips != !clips_ptr) { 
        ret = -EINVAL; 
        goto out_err1; 
    } 
    
    flags = DRM_MODE_FB_DIRTY_FLAGS & r->flags; 
   
    /* If userspace annotates copy, clips must come in pairs */ 
    if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY && (num_clips % 2)) { 
        ret = -EINVAL; 
        goto out_err1; 
    } 
    
    if (num_clips && clips_ptr) { 
        if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) { 
            ret = -EINVAL; 
            goto out_err1; 
        } 
        
        clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); 
        if (!clips) { 
            ret = -ENOMEM; 
            goto out_err1; 
        } 

        ret = copy_from_user(clips, clips_ptr, 
                 num_clips * sizeof(*clips)); 
        if (ret) { 
            ret = -EFAULT; 
            goto out_err2; 
        } 
    } 

    if (fb->funcs->dirty) { 
        ret = fb->funcs->dirty(fb, file_priv, flags, r->color, 
                 clips, num_clips); 
    } else { 
        ret = -ENOSYS; 
    } 
    
out_err2: 
    kfree(clips); 
out_err1:
    drm_framebuffer_unreference(fb); 
    
    return ret; 
} 

这里偏怀疑是num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS导致的,在xorg driver中添加打印,卡死时打印出:
[ 141.634] (II) modeset(0): fd_id:105 clip num:554

而驱动中的定义如下:
#define DRM_MODE_FB_DIRTY_MAX_CLIPS 256

这也就导致了如下的执行:

if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) { 
        ret = -EINVAL; 
        goto out_err1; 
} 

在xorg驱动中对ioctl传入的clips num进行分片执行解决了这个问题,改动如下:

-       ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects); 
-       DamageEmpty(damage); 
-       if (ret) { 
-           if (ret == -EINVAL) 
-               return ret; 
-       } 
+    drmModeClip *sig_clip = clip; 
+    int sig_cliprects; 
+    while(num_cliprects > 0) { 
+        if(num_cliprects > DRM_MODE_FB_DIRTY_MAX_CLIPS) { 
+            sig_cliprects = DRM_MODE_FB_DIRTY_MAX_CLIPS; 
+        } else { 
+            sig_cliprects = num_cliprects; 
+        } 
+           ret = drmModeDirtyFB(ms->fd, fb_id, sig_clip, sig_cliprects); 
+        sig_clip += sig_cliprects; 
+        num_cliprects -= sig_cliprects; 
+           DamageEmpty(damage); 
+           if (ret) { 
+               if (ret == -EINVAL) 
+                   return ret; 
+           } 
+    } 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

解决qemu虚拟机图形界面卡死问题 的相关文章

  • 一次内核hung task分析

    http blog chinaunix net uid 14528823 id 4406510 html 1 内核hung task检测机制由来 我们知道进程等待IO时 经常处于D状态 即TASK UNINTERRUPTIBLE状态 处于这

随机推荐

  • python读取csv中所遇到的中文编码问题

    由于本人准备学习使用一些机器学习算法 第一个是DecisionTree 然后使用到了西瓜案例 因为涉及到讨厌的编码问题 所以找了好多办法去尝试读取csv文件 1 pandas pandas可谓是神奇 用python学习机器学习不可缺少的一个
  • 如何解决WIN10中,进入本地组策略时出现“命名空间已经被定义为存储中另一文件的目标命名空间”

    1 首先 怎么打开组策略 win R gpedit msc 回车 2 当打开组策略时出现如下的提示 当然关闭后还是可以正常使用的 只是如何去掉该提示呢 3 解决办法 引起该问题的原因就是提示的C WINDOWS PolicyDefiniti
  • Linux脚本启动jar包

    这里主要为shell脚本启动部署在服务器中jar包 bin bash 这里可替换为你自己的执行程序 其他代码无需更改 APP NAME demo jar 使用说明 用来提示输入参数 usage echo Usage sh demo sh s
  • Android上层与驱动交互完整篇(二)Hal层篇

    Android上层与驱动交互完整篇 二 Hal层篇 上篇写了I2C驱动如何来编写 但是驱动里并没有交代如何具体的跟设备通信 现在我们在hal层实现这部分逻辑代码 HAL全称Hardware Abstract Layer 硬件抽象层 它向下屏
  • 基于改进二进制粒子群算法的电力系统机组组合——复现

    目录 文章摘要 研究背景 二进制粒子群算法 代码运行效果 本文代码分享 文章摘要 提出了1种改进的BS0 二进制粒子群 方法求解机组组合问题 首先 利用优先顺序法确定初始的机组组合 根据这个结果 确定优化窗口的范围 在此范围内利用BPSO进
  • WebLogic-执行队列

    一 Tuning the Application Server 二 执行队列 Using Work Managers to Optimize Scheduled WorkThis chapter describes how WebLogic
  • K-近邻算法

    一 K 近邻算法 1 介绍 K 近邻算法 K Nearest Neighbor 又叫KNN算法 指如果一个样本在特征空间中的k个最相似的样本中的大多数属于某一个类别 则该样本也属于这个类别 也就是对于新输入的实例 从数据集中找到于该实例最邻
  • Ubuntu:停掉某个网络

    ifconfig 网口名 down 例子如下 ifconfig docker0 down
  • 163_omnicore升级后无法连接

    qq群里转载的 最近由于omnicore要升级 每个要升级的人都在问rpc怎么连不了了 这里统一回复下 1 为什么连不了 这是bitcoin0 18 0更改了rpcallowip自动侦听的功能 必须使用rpcbind指定要侦听的ip 2 怎
  • 约瑟夫问题详解

    约瑟夫问题 有n个人 编号为1 n 从第一个人开始报数 从1开始报 报到m的人会死掉 然后从第m 1个人开始 重复以上过程 在死了n 1个人后 问最后一个人的编号是 暴力 题目传送门 暴力都想不到就真是让人折服了 暴力的话大模拟即可 不是重
  • 列表转链表+链表合并

    列表转链表 思路 生成一个头节点 current指向该节点 再生成新节点 给该节点赋值val 更新current位置 依次类推 class ListNode object def int self val 0 next None self
  • 腾讯28-整数反转

    腾讯28 整数反转leetcode7 给出一个 32 位的有符号整数 你需要将这个整数中每位上的数字进行反转 示例 1 输入 123 输出 321 示例 2 输入 123 输出 321 示例 3 输入 120 输出 21 注意 假设我们的环
  • mac xmind

    1 首先要安装包 XMind For Mac 本人下载的这个版本xmind8update9 2 下载破解包 XMindCrack jar 链接 https pan baidu com s 1jqpodMvKQTNQyenAIy0Y3w 密码
  • vue反向代理解决跨域及部署nginx端口转发解决跨域

    1 前言 本文是为了解决vue反向代理解决跨域及部署服务器nginx端口转发解决跨域 因为踩了不少的坑 百度了很多 也试了太多的方法 最终得以解决 所以记录一下 希望遇到同样问题的友友们可以高效的解决自己项目中遇到的问题 2 为什么会出现跨
  • 自写控件:滑动呈现控件(实现了两个以上控件间的切换)师傅的

    public class NavigatePanel Panel public enum Direction LeftToRight RightToLeft private NavigateArgs mArgs Navigate参数 pri
  • JS基础,从JS的组成到JS函数写法

    一 计算机的组成 计算机 软件 硬件 输入设备 输出设备 CPU 硬盘 内存 二 JS的组成 1 ECMAScript 是由ECMA国际 原欧洲计算机制造商协会 进行标准化的一门编程语言 这种语言在万维网上应用广泛 它往往被称为JavaSc
  • Selenium定位页面元素的方法

    一 Selenium定位页面元素的方法 selenium提供如下强大的定位元素的方法 id id name name dom javascriptExpression xpath xpathExpression link textPatte
  • java 基础重学(五)-底层-JVM

    1 JVM JVM内存结构 class 文件格式 运行时数据区 堆和栈的区别 java中对象一定在堆上分配吗 java 内存模型 计算机内存模型 缓存一致性 MESI协议 原子性 可见性 顺序性 happens before 内存屏蔽 sy
  • 刷题day65:分割等和子集

    题意描述 给你一个 只包含正整数 的 非空 数组 nums 请你判断是否可以将这个数组分割成两个子集 使得两个子集的元素和相等 思路 使用01背包 背包的体积为sum 2 背包要放入的商品 集合里的元素 重量为 元素的数值 价值也为元素的数
  • 解决qemu虚拟机图形界面卡死问题

    1 基础环境 Virtio gpu双heads 4 9 0内核 xserver1 9 3 modesettings0 5 0驱动 2 问题描述 终端中打开大量文字内容 不停上下滑动 或cat大量内容的文件 操作过程中用户界面卡死 如下 3