git: 49b9705d8fd8 - main - x11/nvidia-driver: Add Makefile.version and patch for nvidia-drm

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Wed, 16 Aug 2023 20:55:36 UTC
The branch main has been updated by kbowling:

URL: https://cgit.FreeBSD.org/ports/commit/?id=49b9705d8fd8bfea7d87a95658302f8899fb1e32

commit 49b9705d8fd8bfea7d87a95658302f8899fb1e32
Author:     Austin Shafer <ashafer@badland.io>
AuthorDate: 2023-08-16 19:21:01 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2023-08-16 20:55:10 +0000

    x11/nvidia-driver: Add Makefile.version and patch for nvidia-drm
    
    This moves the version string into a makefile that can be included from
    child ports.
    
    This also adds a patch to nvidia-modeset that handles a deadlock with
    queueing events observed with nvidia-drm. This fix is only needed in
    535, future versions will have a proper implementation included with
    them.
    
    Approved by:    maintainer timeout
    Differential Revision:  https://reviews.freebsd.org/D40168
---
 x11/linux-nvidia-libs/Makefile                     |   3 +-
 x11/nvidia-driver/Makefile                         |   8 +-
 x11/nvidia-driver/Makefile.version                 |   4 +
 ...-src_nvidia-modeset_nvidia-modeset-freebsd.c.in | 131 +++++++++++++++++++++
 4 files changed, 143 insertions(+), 3 deletions(-)

diff --git a/x11/linux-nvidia-libs/Makefile b/x11/linux-nvidia-libs/Makefile
index 84a31944ade1..811be656adf5 100644
--- a/x11/linux-nvidia-libs/Makefile
+++ b/x11/linux-nvidia-libs/Makefile
@@ -1,5 +1,5 @@
 PORTNAME=	nvidia-libs
-DISTVERSION?=	535.98
+DISTVERSION?=	${NVIDIA_DISTVERSION}
 # Always try to set PORTREVISION as it can be overridden by the slave ports
 PORTREVISION?=	0
 CATEGORIES=	x11 linux
@@ -13,6 +13,7 @@ COMMENT=	NVidia graphics libraries and programs (Linux version)
 WWW=		https://www.nvidia.com/object/unix.html
 
 LICENSE_FILE=	${WRKSRC}/LICENSE
+.include "${.CURDIR}/../nvidia-driver/Makefile.version"
 .include "${.CURDIR}/../nvidia-driver/Makefile.common"
 
 .if ${DISTVERSION:R} > 390
diff --git a/x11/nvidia-driver/Makefile b/x11/nvidia-driver/Makefile
index 24f855878f47..a722675748f7 100644
--- a/x11/nvidia-driver/Makefile
+++ b/x11/nvidia-driver/Makefile
@@ -12,9 +12,9 @@
 # ``make DISTVERSION=xxx.yy.zz -DNO_CHECKSUM'' should typically work.
 
 PORTNAME?=	nvidia-driver
-DISTVERSION?=	535.98
+DISTVERSION?=	${NVIDIA_DISTVERSION}
 # Always try to set PORTREVISION as it can be overridden by the slave ports
-PORTREVISION?=	0
+PORTREVISION?=	1
 CATEGORIES=	x11
 MASTER_SITES=	NVIDIA/XFree86/FreeBSD-${ARCH_SUFX}/${DISTVERSION}
 DISTNAME=	NVIDIA-FreeBSD-${ARCH_SUFX}-${DISTVERSION}
@@ -25,6 +25,7 @@ COMMENT?=	NVidia graphics card binary drivers for hardware OpenGL rendering
 WWW=		https://www.nvidia.com/object/unix.html
 
 LICENSE_FILE=	${WRKSRC}/doc/license.txt
+.include "${.CURDIR}/../nvidia-driver/Makefile.version"
 .include "${.CURDIR}/../nvidia-driver/Makefile.common"
 
 # Pull GNU sed(1) for "binary" patching of obj/libglvnd/libEGL.so.1 and
@@ -97,6 +98,9 @@ SUB_LIST+=	KLDNAME=nvidia
 SUB_LIST+=	KLDNAME=nvidia-modeset
 .endif
 
+.if ${NVVERSION} >= 530.03002 && ${NVVERSION} < 545.00
+SUB_PATCHES += surplus-patch-src_nvidia-modeset_nvidia-modeset-freebsd.c
+.endif
 .if ${NVVERSION} < 460.039
 .  if ${NVVERSION} >= 358.009
 EXTRA_PATCHES+=	${FILESDIR}/extra-patch-src_nvidia-modeset_nvidia-modeset-freebsd.c
diff --git a/x11/nvidia-driver/Makefile.version b/x11/nvidia-driver/Makefile.version
new file mode 100644
index 000000000000..751e2bcb6e9c
--- /dev/null
+++ b/x11/nvidia-driver/Makefile.version
@@ -0,0 +1,4 @@
+# NVIDIA Distversion
+#
+# This will be included from x11/nvidia-driver and the nvidia-drm port
+NVIDIA_DISTVERSION = 535.98
diff --git a/x11/nvidia-driver/files/surplus-patch-src_nvidia-modeset_nvidia-modeset-freebsd.c.in b/x11/nvidia-driver/files/surplus-patch-src_nvidia-modeset_nvidia-modeset-freebsd.c.in
new file mode 100644
index 000000000000..0df09d8811c6
--- /dev/null
+++ b/x11/nvidia-driver/files/surplus-patch-src_nvidia-modeset_nvidia-modeset-freebsd.c.in
@@ -0,0 +1,131 @@
+--- src/nvidia-modeset/nvidia-modeset-freebsd.c.orig	2023-03-28 22:14:28 UTC
++++ src/nvidia-modeset/nvidia-modeset-freebsd.c
+@@ -368,6 +368,7 @@ struct nvkms_timer_t {
+     NvBool cancel;
+     NvBool complete;
+     NvBool isRefPtr;
++    NvBool needsNvkmsLock;
+     NvBool callout_created;
+     nvkms_timer_proc_t *proc;
+     void *dataPtr;
+@@ -406,7 +407,14 @@ static void nvkms_taskqueue_callback(void *arg, int pe
+         callout_drain(&timer->callout);
+     }
+ 
+-    sx_xlock(&nvkms_lock);
++    /*
++     * Only lock if this timer requests it. DRM's callback nv_drm_event_callback
++     * will not need this, since it may reenter nvkms through the kapi and lock
++     * nvkms_lock then.
++     */
++    if (timer->needsNvkmsLock) {
++        sx_xlock(&nvkms_lock);
++    }
+ 
+     if (timer->isRefPtr) {
+         // If the object this timer refers to was destroyed, treat the timer as
+@@ -424,11 +432,13 @@ static void nvkms_taskqueue_callback(void *arg, int pe
+         timer->complete = NV_TRUE;
+     }
+ 
++    if (timer->needsNvkmsLock) {
++        sx_xunlock(&nvkms_lock);
++    }
++
+     if (timer->cancel || timer->isRefPtr) {
+         nvkms_free(timer, sizeof(*timer));
+     }
+-
+-    sx_xunlock(&nvkms_lock);
+ }
+ 
+ static void nvkms_callout_callback(void *arg)
+@@ -441,11 +451,13 @@ nvkms_init_timer(struct nvkms_timer_t *timer, nvkms_ti
+ 
+ static void
+ nvkms_init_timer(struct nvkms_timer_t *timer, nvkms_timer_proc_t *proc,
+-                 void *dataPtr, NvU32 dataU32, NvBool isRefPtr, NvU64 usec)
++                 void *dataPtr, NvU32 dataU32, NvBool isRefPtr, NvU64 usec,
++                 NvBool needsNvkmsLock)
+ {
+     timer->cancel = NV_FALSE;
+     timer->complete = NV_FALSE;
+     timer->isRefPtr = isRefPtr;
++    timer->needsNvkmsLock = needsNvkmsLock;
+ 
+     timer->proc = proc;
+     timer->dataPtr = dataPtr;
+@@ -479,19 +491,27 @@ nvkms_init_timer(struct nvkms_timer_t *timer, nvkms_ti
+     mtx_unlock_spin(&nvkms_timers.lock);
+ }
+ 
+-nvkms_timer_handle_t*
+-nvkms_alloc_timer(nvkms_timer_proc_t *proc,
+-                  void *dataPtr, NvU32 dataU32,
+-                  NvU64 usec)
++static nvkms_timer_handle_t*
++nvkms_alloc_timer_locked(nvkms_timer_proc_t *proc,
++                         void *dataPtr, NvU32 dataU32,
++                         NvU64 usec, NvBool needsNvkmsLock)
+ {
+     // nvkms_alloc_timer cannot be called from an interrupt context.
+     struct nvkms_timer_t *timer = nvkms_alloc(sizeof(*timer), NV_TRUE);
+     if (timer) {
+-        nvkms_init_timer(timer, proc, dataPtr, dataU32, NV_FALSE, usec);
++        nvkms_init_timer(timer, proc, dataPtr, dataU32, NV_FALSE, usec, needsNvkmsLock);
+     }
+     return timer;
+ }
+ 
++nvkms_timer_handle_t*
++nvkms_alloc_timer(nvkms_timer_proc_t *proc,
++                  void *dataPtr, NvU32 dataU32,
++                  NvU64 usec)
++{
++    return nvkms_alloc_timer_locked(proc, dataPtr, dataU32, usec, NV_TRUE);
++}
++
+ NvBool
+ nvkms_alloc_timer_with_ref_ptr(nvkms_timer_proc_t *proc,
+                                struct nvkms_ref_ptr *ref_ptr,
+@@ -506,7 +526,7 @@ nvkms_alloc_timer_with_ref_ptr(nvkms_timer_proc_t *pro
+         // Reference the ref_ptr to make sure that it doesn't get freed before
+         // the timer fires.
+         nvkms_inc_ref(ref_ptr);
+-        nvkms_init_timer(timer, proc, ref_ptr, dataU32, NV_TRUE, usec);
++        nvkms_init_timer(timer, proc, ref_ptr, dataU32, NV_TRUE, usec, NV_TRUE);
+     }
+ 
+     return timer != NULL;
+@@ -570,10 +590,11 @@ nvkms_event_queue_changed(nvkms_per_open_handle_t *pOp
+             break;
+         case NVKMS_CLIENT_KERNEL_SPACE:
+             if (!popen->kernel.task) {
+-                popen->kernel.task = nvkms_alloc_timer(nvkms_kapi_task_callback,
+-                                                       popen,
+-                                                       0, /* dataU32 */
+-                                                       0 /* callout delay */);
++                popen->kernel.task = nvkms_alloc_timer_locked(nvkms_kapi_task_callback,
++                                                              popen,
++                                                              0, /* dataU32 */
++                                                              0, /* callout delay */
++                                                              NV_FALSE);
+             }
+             break;
+     }
+@@ -828,10 +849,11 @@ static struct nvkms_per_open *nvkms_open_common(enum N
+         case NVKMS_CLIENT_KERNEL_SPACE:
+             /* enqueue our new task */
+             popen->kernel.device = device;
+-            popen->kernel.task = nvkms_alloc_timer(nvkms_kapi_task_callback,
+-                                                   popen,
+-                                                   0, /* dataU32 */
+-                                                   0 /* callout delay */);
++            popen->kernel.task = nvkms_alloc_timer_locked(nvkms_kapi_task_callback,
++                                                          popen,
++                                                          0, /* dataU32 */
++                                                          0, /* callout delay */
++                                                          NV_FALSE);
+             break;
+     }
+