Module Name: src Committed By: riastradh Date: Tue Oct 25 23:36:21 UTC 2022
Modified Files: src/sys/external/bsd/drm2/dist/drm/vmwgfx: vmwgfx_drv.h vmwgfx_irq.c Log Message: vmwgfx(4): Hand-cruft threaded irq with a workqueue(9). To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h cvs rdiff -u -r1.5 -r1.6 \ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h:1.8 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h:1.9 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h:1.8 Tue Oct 25 23:35:43 2022 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_drv.h Tue Oct 25 23:36:21 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_drv.h,v 1.8 2022/10/25 23:35:43 riastradh Exp $ */ +/* $NetBSD: vmwgfx_drv.h,v 1.9 2022/10/25 23:36:21 riastradh Exp $ */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /************************************************************************** @@ -30,6 +30,10 @@ #ifndef _VMWGFX_DRV_H_ #define _VMWGFX_DRV_H_ +#ifdef __NetBSD__ +#include <sys/workqueue.h> +#endif + #include <linux/notifier.h> #include <linux/suspend.h> #include <linux/sync_file.h> @@ -629,6 +633,11 @@ struct vmw_private { struct vmw_cmdbuf_man *cman; DECLARE_BITMAP(irqthread_pending, VMW_IRQTHREAD_MAX); +#ifdef __NetBSD__ + struct workqueue *irqthread_wq; + struct work irqthread_work; + volatile unsigned irqthread_scheduled; +#endif /* Validation memory reservation */ struct vmw_validation_mem vvm; Index: src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c diff -u src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c:1.5 src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c:1.6 --- src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c:1.5 Tue Oct 25 23:35:43 2022 +++ src/sys/external/bsd/drm2/dist/drm/vmwgfx/vmwgfx_irq.c Tue Oct 25 23:36:21 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: vmwgfx_irq.c,v 1.5 2022/10/25 23:35:43 riastradh Exp $ */ +/* $NetBSD: vmwgfx_irq.c,v 1.6 2022/10/25 23:36:21 riastradh Exp $ */ // SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** @@ -28,7 +28,7 @@ **************************************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vmwgfx_irq.c,v 1.5 2022/10/25 23:35:43 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vmwgfx_irq.c,v 1.6 2022/10/25 23:36:21 riastradh Exp $"); #include <linux/sched/signal.h> @@ -49,12 +49,21 @@ __KERNEL_RCSID(0, "$NetBSD: vmwgfx_irq.c * vmw_irq_handler has returned with IRQ_WAKE_THREAD. * */ +#ifdef __NetBSD__ +static void +vmw_thread_fn(struct work *work, void *arg) +#else static irqreturn_t vmw_thread_fn(int irq, void *arg) +#endif { struct drm_device *dev = (struct drm_device *)arg; struct vmw_private *dev_priv = vmw_priv(dev); irqreturn_t ret = IRQ_NONE; +#ifdef __NetBSD__ + atomic_store_relaxed(&dev_priv->irqthread_scheduled, false); +#endif + if (test_and_clear_bit(VMW_IRQTHREAD_FENCE, dev_priv->irqthread_pending)) { spin_lock(&dev_priv->fence_lock); @@ -71,7 +80,9 @@ static irqreturn_t vmw_thread_fn(int irq ret = IRQ_HANDLED; } +#ifndef __NetBSD__ return ret; +#endif } /** @@ -129,6 +140,16 @@ static irqreturn_t vmw_irq_handler(int i dev_priv->irqthread_pending)) ret = IRQ_WAKE_THREAD; +#ifdef __NetBSD__ + if (ret == IRQ_WAKE_THREAD) { + if (atomic_swap_uint(&dev_priv->irqthread_scheduled, 1) == 0) { + workqueue_enqueue(dev_priv->irqthread_wq, + &dev_priv->irqthread_work, NULL); + } + ret = IRQ_HANDLED; + } +#endif + return ret; } @@ -450,7 +471,13 @@ void vmw_irq_uninstall(struct drm_device #endif dev->irq_enabled = false; +#ifdef __NetBSD__ + int ret = drm_irq_uninstall(dev); + KASSERT(ret == 0); + workqueue_destroy(dev_priv->irqthread_wq); +#else free_irq(dev->irq, dev); +#endif } /** @@ -469,8 +496,21 @@ int vmw_irq_install(struct drm_device *d vmw_irq_preinstall(dev); +#ifdef __NetBSD__ + /* XXX errno NetBSD->Linux */ + ret = -workqueue_create(&vmw_priv(dev)->irqthread_wq, "vmwgfirq", + vmw_thread_fn, dev, PRI_NONE, IPL_DRM, WQ_MPSAFE); + if (ret < 0) + return ret; + ret = drm_irq_install(dev); + if (ret < 0) { + workqueue_destroy(vmw_priv(dev)->irqthread_wq); + vmw_priv(dev)->irqthread_wq = NULL; + } +#else ret = request_threaded_irq(irq, vmw_irq_handler, vmw_thread_fn, IRQF_SHARED, VMWGFX_DRIVER_NAME, dev); +#endif if (ret < 0) return ret;