diff --git a/x11/linux-nvidia-libs/Makefile b/x11/linux-nvidia-libs/Makefile --- 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 @@ 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 --- 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 @@ 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-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 --- /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 --- /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; + } +