drm/i915/gvt: fix cleanup sequence in intel_gvt_clean_device
authorHang Yuan <hang.yuan@linux.intel.com>
Mon, 23 Jul 2018 12:15:46 +0000 (20:15 +0800)
committerZhenyu Wang <zhenyuw@linux.intel.com>
Tue, 14 Aug 2018 07:25:32 +0000 (15:25 +0800)
Create one vGPU and then unbind IGD device from i915 driver. The following
oops will happen. This patch will free vgpu resource first and then gvt
resource to remove these oops.

BUG: unable to handle kernel NULL pointer dereference at       00000000000000a8
  PGD 80000003c9d2c067 P4D 80000003c9d2c067 PUD 3c817c067 P      MD 0
  Oops: 0002 [#1] SMP PTI
  RIP: 0010:down_write+0x1b/0x40
Call Trace:
  debugfs_remove_recursive+0x46/0x1a0
  intel_gvt_debugfs_remove_vgpu+0x15/0x30 [i915]
  intel_gvt_destroy_vgpu+0x2d/0xf0 [i915]
  intel_vgpu_remove+0x2c/0x30 [kvmgt]
  mdev_device_remove_ops+0x23/0x50 [mdev]
  mdev_device_remove+0xdb/0x190 [mdev]
  mdev_device_remove+0x190/0x190 [mdev]
  device_for_each_child+0x47/0x90
  mdev_unregister_device+0xd5/0x120 [mdev]
  intel_gvt_clean_device+0x91/0x120 [i915]
  i915_driver_unload+0x9d/0x120 [i915]
  i915_pci_remove+0x15/0x20 [i915]
  pci_device_remove+0x3b/0xc0
  device_release_driver_internal+0x157/0x230
  unbind_store+0xfc/0x150
  kernfs_fop_write+0x10f/0x180
  __vfs_write+0x36/0x180
  ? common_file_perm+0x41/0x130
  ? _cond_resched+0x16/0x40
  vfs_write+0xb3/0x1a0
  ksys_write+0x52/0xc0
  do_syscall_64+0x55/0x100
  entry_SYSCALL_64_after_hwframe+0x44/0xa9

BUG: unable to handle kernel NULL pointer dereference at 0      000000000000038
  PGD 8000000405bce067 P4D 8000000405bce067 PUD 405bcd067 PM      D 0
  Oops: 0000 [#1] SMP PTI
  RIP: 0010:hrtimer_active+0x5/0x40
Call Trace:
  hrtimer_try_to_cancel+0x25/0x120
  ? tbs_sched_clean_vgpu+0x1f/0x50 [i915]
  hrtimer_cancel+0x15/0x20
  intel_gvt_destroy_vgpu+0x4c/0xf0 [i915]
  intel_vgpu_remove+0x2c/0x30 [kvmgt]
  mdev_device_remove_ops+0x23/0x50 [mdev]
  mdev_device_remove+0xdb/0x190 [mdev]
  ? mdev_device_remove+0x190/0x190 [mdev]
  device_for_each_child+0x47/0x90
  mdev_unregister_device+0xd5/0x120 [mdev]
  intel_gvt_clean_device+0x89/0x120 [i915]
  i915_driver_unload+0x9d/0x120 [i915]
  i915_pci_remove+0x15/0x20 [i915]
  pci_device_remove+0x3b/0xc0
  device_release_driver_internal+0x157/0x230
  unbind_store+0xfc/0x150
  kernfs_fop_write+0x10f/0x180
  __vfs_write+0x36/0x180
  ? common_file_perm+0x41/0x130
  ? _cond_resched+0x16/0x40
  vfs_write+0xb3/0x1a0
  ksys_write+0x52/0xc0
  do_syscall_64+0x55/0x100
  entry_SYSCALL_64_after_hwframe+0x44/0xa9

Fixes: bc7b0be316ae("drm/i915/gvt: Add basic debugfs infrastructure")
Fixes: afe04fbe6c52("drm/i915/gvt: create an idle vGPU")
Signed-off-by: Hang Yuan <hang.yuan@linux.intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
drivers/gpu/drm/i915/gvt/gvt.c

index 195a3b24e6241fa7e7dbe7c9f73df228a657162f..46c8b720e336317f5fdf1ce51553031112513295 100644 (file)
@@ -316,6 +316,11 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
        if (WARN_ON(!gvt))
                return;
 
+       intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
+       intel_gvt_hypervisor_host_exit(&dev_priv->drm.pdev->dev, gvt);
+       intel_gvt_cleanup_vgpu_type_groups(gvt);
+       intel_gvt_clean_vgpu_types(gvt);
+
        intel_gvt_debugfs_clean(gvt);
        clean_service_thread(gvt);
        intel_gvt_clean_cmd_parser(gvt);
@@ -323,17 +328,10 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
        intel_gvt_clean_workload_scheduler(gvt);
        intel_gvt_clean_gtt(gvt);
        intel_gvt_clean_irq(gvt);
-       intel_gvt_clean_mmio_info(gvt);
        intel_gvt_free_firmware(gvt);
-
-       intel_gvt_hypervisor_host_exit(&dev_priv->drm.pdev->dev, gvt);
-       intel_gvt_cleanup_vgpu_type_groups(gvt);
-       intel_gvt_clean_vgpu_types(gvt);
-
+       intel_gvt_clean_mmio_info(gvt);
        idr_destroy(&gvt->vgpu_idr);
 
-       intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
-
        kfree(dev_priv->gvt);
        dev_priv->gvt = NULL;
 }