Lyude Paul
2018-Jul-31 00:58 UTC
[Nouveau] [PATCH 1/2] drm/nouveau: Print debug message on ACPI probe event
Signed-off-by: Lyude Paul <lyude at redhat.com> --- drivers/gpu/drm/nouveau/nouveau_display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index ec7861457b84..b2a93e3fa67b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -387,6 +387,7 @@ nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val, * connector hotplug on a runtime suspended GPU, * schedule hpd_work to check. */ + NV_DEBUG(drm, "ACPI requested connector probe\n"); schedule_work(&drm->hpd_work); /* acpi-video should not generate keypresses for this */ -- 2.17.1
Lyude Paul
2018-Jul-31 00:58 UTC
[Nouveau] [PATCH 2/2] drm/nouveau: Prevent redundant connector probes from ACPI
On the Lenovo P50 I've been working on, ACPI notifications for hotplugs always seem happen even while the GPU has it's hotplugs enabled. This means that we're uselessly scheduling two connector probes every time we get a hotplug. Since we can't unregister the acpi handler without causing userspace to start getting mysterious keypresses from the ACPI_VIDEO_REPROBE events that are meant for us, simply add a member to nouveau_drm that can be used to enable/disable our ACPI event handler from being able to schedule connector probes on it's own. Signed-off-by: Lyude Paul <lyude at redhat.com> --- drivers/gpu/drm/nouveau/nouveau_display.c | 40 +++++++++++++++-------- drivers/gpu/drm/nouveau/nouveau_display.h | 4 +-- drivers/gpu/drm/nouveau/nouveau_drm.c | 4 +-- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index b2a93e3fa67b..b80226c87487 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -382,13 +382,16 @@ nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val, if (!strcmp(info->device_class, ACPI_VIDEO_CLASS)) { if (info->type == ACPI_VIDEO_NOTIFY_PROBE) { - /* - * This may be the only indication we receive of a - * connector hotplug on a runtime suspended GPU, - * schedule hpd_work to check. - */ - NV_DEBUG(drm, "ACPI requested connector probe\n"); - schedule_work(&drm->hpd_work); + if (READ_ONCE(drm->acpi_hpd_enabled)) { + /* + * This may be the only indication we receive + * of a connector hotplug on a runtime + * suspended GPU, schedule hpd_work to check. + */ + NV_DEBUG(drm, + "ACPI requested connector probe\n"); + schedule_work(&drm->hpd_work); + } /* acpi-video should not generate keypresses for this */ return NOTIFY_BAD; @@ -400,7 +403,7 @@ nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val, #endif int -nouveau_display_init(struct drm_device *dev) +nouveau_display_init(struct drm_device *dev, bool runtime) { struct nouveau_display *disp = nouveau_display(dev); struct nouveau_drm *drm = nouveau_drm(dev); @@ -420,13 +423,20 @@ nouveau_display_init(struct drm_device *dev) } drm_connector_list_iter_end(&conn_iter); + /* disable ACPI hotplug handling to prevent duplicate connector + * probes + * FIXME: make sure that WRITE_ONCE() implies a store barrier + * beforehand + */ + WRITE_ONCE(drm->acpi_hpd_enabled, false); + /* enable flip completion events */ nvif_notify_get(&drm->flip); return ret; } void -nouveau_display_fini(struct drm_device *dev, bool suspend) +nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime) { struct nouveau_display *disp = nouveau_display(dev); struct nouveau_drm *drm = nouveau_drm(dev); @@ -443,6 +453,10 @@ nouveau_display_fini(struct drm_device *dev, bool suspend) /* disable flip completion events */ nvif_notify_put(&drm->flip); + /* let ACPI handle hotplugs since we won't have them enabled */ + if (runtime) + WRITE_ONCE(drm->acpi_hpd_enabled, true); + /* disable hotplug interrupts */ drm_connector_list_iter_begin(dev, &conn_iter); nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) { @@ -619,11 +633,11 @@ nouveau_display_suspend(struct drm_device *dev, bool runtime) } } - nouveau_display_fini(dev, true); + nouveau_display_fini(dev, true, runtime); return 0; } - nouveau_display_fini(dev, true); + nouveau_display_fini(dev, true, runtime); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_framebuffer *nouveau_fb; @@ -656,7 +670,7 @@ nouveau_display_resume(struct drm_device *dev, bool runtime) int ret; if (drm_drv_uses_atomic_modeset(dev)) { - nouveau_display_init(dev); + nouveau_display_init(dev, runtime); if (disp->suspend) { drm_atomic_helper_resume(dev, disp->suspend); disp->suspend = NULL; @@ -689,7 +703,7 @@ nouveau_display_resume(struct drm_device *dev, bool runtime) NV_ERROR(drm, "Could not pin/map cursor.\n"); } - nouveau_display_init(dev); + nouveau_display_init(dev, runtime); /* Force CLUT to get re-loaded during modeset */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 54aa7c3fa42d..473411120225 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -61,8 +61,8 @@ nouveau_display(struct drm_device *dev) int nouveau_display_create(struct drm_device *dev); void nouveau_display_destroy(struct drm_device *dev); -int nouveau_display_init(struct drm_device *dev); -void nouveau_display_fini(struct drm_device *dev, bool suspend); +int nouveau_display_init(struct drm_device *dev, bool runtime); +void nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime); int nouveau_display_suspend(struct drm_device *dev, bool runtime); void nouveau_display_resume(struct drm_device *dev, bool runtime); int nouveau_display_vblank_enable(struct drm_device *, unsigned int); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index c7ec86d6c3c9..65dc5b5cf6ce 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -574,7 +574,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) goto fail_dispctor; if (dev->mode_config.num_crtc) { - ret = nouveau_display_init(dev); + ret = nouveau_display_init(dev, false); if (ret) goto fail_dispinit; } @@ -629,7 +629,7 @@ nouveau_drm_unload(struct drm_device *dev) nouveau_debugfs_fini(drm); if (dev->mode_config.num_crtc) - nouveau_display_fini(dev, false); + nouveau_display_fini(dev, false, false); nouveau_display_destroy(dev); nouveau_bios_takedown(dev); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 6e1acaec3400..22e70e72ec8b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -201,6 +201,7 @@ struct nouveau_drm { int fbcon_new_state; #ifdef CONFIG_ACPI struct notifier_block acpi_nb; + bool acpi_hpd_enabled; #endif /* power management */ -- 2.17.1
kbuild test robot
2018-Jul-31 10:33 UTC
[Nouveau] [PATCH 2/2] drm/nouveau: Prevent redundant connector probes from ACPI
Hi Lyude, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.18-rc7 next-20180727] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Lyude-Paul/drm-nouveau-Print-debug-message-on-ACPI-probe-event/20180731-150343 config: arm-multi_v7_defconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=arm All errors (new ones prefixed by >>): In file included from include/linux/kernel.h:10:0, from include/linux/list.h:9, from include/linux/agp_backend.h:33, from include/drm/drmP.h:35, from drivers/gpu/drm/nouveau/nouveau_display.c:28: drivers/gpu/drm/nouveau/nouveau_display.c: In function 'nouveau_display_init':>> drivers/gpu/drm/nouveau/nouveau_display.c:431:16: error: 'struct nouveau_drm' has no member named 'acpi_hpd_enabled'WRITE_ONCE(drm->acpi_hpd_enabled, false); ^ include/linux/compiler.h:275:17: note: in definition of macro 'WRITE_ONCE' union { typeof(x) __val; char __c[1]; } __u = \ ^>> drivers/gpu/drm/nouveau/nouveau_display.c:431:16: error: 'struct nouveau_drm' has no member named 'acpi_hpd_enabled'WRITE_ONCE(drm->acpi_hpd_enabled, false); ^ include/linux/compiler.h:276:30: note: in definition of macro 'WRITE_ONCE' { .__val = (__force typeof(x)) (val) }; \ ^>> drivers/gpu/drm/nouveau/nouveau_display.c:431:16: error: 'struct nouveau_drm' has no member named 'acpi_hpd_enabled'WRITE_ONCE(drm->acpi_hpd_enabled, false); ^ include/linux/compiler.h:277:22: note: in definition of macro 'WRITE_ONCE' __write_once_size(&(x), __u.__c, sizeof(x)); \ ^>> drivers/gpu/drm/nouveau/nouveau_display.c:431:16: error: 'struct nouveau_drm' has no member named 'acpi_hpd_enabled'WRITE_ONCE(drm->acpi_hpd_enabled, false); ^ include/linux/compiler.h:277:42: note: in definition of macro 'WRITE_ONCE' __write_once_size(&(x), __u.__c, sizeof(x)); \ ^ drivers/gpu/drm/nouveau/nouveau_display.c: In function 'nouveau_display_fini': drivers/gpu/drm/nouveau/nouveau_display.c:458:17: error: 'struct nouveau_drm' has no member named 'acpi_hpd_enabled' WRITE_ONCE(drm->acpi_hpd_enabled, true); ^ include/linux/compiler.h:275:17: note: in definition of macro 'WRITE_ONCE' union { typeof(x) __val; char __c[1]; } __u = \ ^ drivers/gpu/drm/nouveau/nouveau_display.c:458:17: error: 'struct nouveau_drm' has no member named 'acpi_hpd_enabled' WRITE_ONCE(drm->acpi_hpd_enabled, true); ^ include/linux/compiler.h:276:30: note: in definition of macro 'WRITE_ONCE' { .__val = (__force typeof(x)) (val) }; \ ^ drivers/gpu/drm/nouveau/nouveau_display.c:458:17: error: 'struct nouveau_drm' has no member named 'acpi_hpd_enabled' WRITE_ONCE(drm->acpi_hpd_enabled, true); ^ include/linux/compiler.h:277:22: note: in definition of macro 'WRITE_ONCE' __write_once_size(&(x), __u.__c, sizeof(x)); \ ^ drivers/gpu/drm/nouveau/nouveau_display.c:458:17: error: 'struct nouveau_drm' has no member named 'acpi_hpd_enabled' WRITE_ONCE(drm->acpi_hpd_enabled, true); ^ include/linux/compiler.h:277:42: note: in definition of macro 'WRITE_ONCE' __write_once_size(&(x), __u.__c, sizeof(x)); \ ^ vim +431 drivers/gpu/drm/nouveau/nouveau_display.c 404 405 int 406 nouveau_display_init(struct drm_device *dev, bool runtime) 407 { 408 struct nouveau_display *disp = nouveau_display(dev); 409 struct nouveau_drm *drm = nouveau_drm(dev); 410 struct drm_connector *connector; 411 struct drm_connector_list_iter conn_iter; 412 int ret; 413 414 ret = disp->init(dev); 415 if (ret) 416 return ret; 417 418 /* enable hotplug interrupts */ 419 drm_connector_list_iter_begin(dev, &conn_iter); 420 nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) { 421 struct nouveau_connector *conn = nouveau_connector(connector); 422 nvif_notify_get(&conn->hpd); 423 } 424 drm_connector_list_iter_end(&conn_iter); 425 426 /* disable ACPI hotplug handling to prevent duplicate connector 427 * probes 428 * FIXME: make sure that WRITE_ONCE() implies a store barrier 429 * beforehand 430 */ > 431 WRITE_ONCE(drm->acpi_hpd_enabled, false); 432 433 /* enable flip completion events */ 434 nvif_notify_get(&drm->flip); 435 return ret; 436 } 437 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation -------------- next part -------------- A non-text attachment was scrubbed... Name: .config.gz Type: application/gzip Size: 43915 bytes Desc: not available URL: <https://lists.freedesktop.org/archives/nouveau/attachments/20180731/9da62d3b/attachment-0001.gz>
Reasonably Related Threads
- [PATCH] drm/nouveau: Don't forget to cancel hpd_work on suspend/unload
- [PATCH 1/2] drm/nouveau: Print debug message on ACPI probe event
- [PATCH 2/2] drm/nouveau: Avoid looping through fake MST connectors
- [PATCH v4 1/8] drm/nouveau: Fix bogus drm_kms_helper_poll_enable() placement
- [PATCH v2] drm/nouveau: don't attempt to schedule hpd_work on headless cards