Add checks for the return value of alloc_workqueue and alloc_ordered_workqueue as they may return NULL pointer and cause NULL pointer dereference. Moreover, destroy them when fails later in order to avoid memory leak. Because in `drivers/gpu/drm/i915/i915_driver.c`, if intel_modeset_init_noirq fails, its workqueues will not be destroyed. Fixes: c26a058680dc ("drm/i915: Use a high priority wq for nonblocking plane updates") Fixes: 757fffcfdffb ("drm/i915: Put all non-blocking modesets onto an ordered wq") Signed-off-by: Jiasheng Jiang <jiasheng@xxxxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_display.c | 21 ++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 6c2686ecb62a..58f6840d6bd8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8655,26 +8655,35 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915) intel_dmc_ucode_init(i915); i915->display.wq.modeset = alloc_ordered_workqueue("i915_modeset", 0); + if (!i915->display.wq.modeset) { + ret = -ENOMEM; + goto cleanup_vga_client_pw_domain_dmc; + } + i915->display.wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI | WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE); + if (!i915->display.wq.flip) { + ret = -ENOMEM; + goto cleanup_modeset; + } intel_mode_config_init(i915); ret = intel_cdclk_init(i915); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_flip; ret = intel_color_init(i915); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_flip; ret = intel_dbuf_init(i915); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_flip; ret = intel_bw_init(i915); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_flip; init_llist_head(&i915->display.atomic_helper.free_list); INIT_WORK(&i915->display.atomic_helper.free_work, @@ -8686,6 +8695,10 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915) return 0; +cleanup_flip: + destroy_workqueue(i915->display.wq.flip); +cleanup_modeset: + destroy_workqueue(i915->display.wq.modeset); cleanup_vga_client_pw_domain_dmc: intel_dmc_ucode_fini(i915); intel_power_domains_driver_remove(i915); -- 2.25.1