On Fri, Jan 06, 2023 at 05:09:34PM +0800, Jiasheng Jiang wrote: > 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> Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@xxxxxxxxxxxxxxx> > 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 >