Skip to content

Commit

Permalink
x11/nvidia-driver: Add Makefile.version and patch for nvidia-drm
Browse files Browse the repository at this point in the history
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
  • Loading branch information
amshafer authored and kev009 committed Aug 16, 2023
1 parent 21f435c commit 49b9705
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 3 deletions.
3 changes: 2 additions & 1 deletion 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
Expand All @@ -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
Expand Down
8 changes: 6 additions & 2 deletions x11/nvidia-driver/Makefile
Expand Up @@ -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}
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions 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
@@ -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;
}

0 comments on commit 49b9705

Please sign in to comment.