761 lines
24 KiB
Diff
761 lines
24 KiB
Diff
From eb7e13baaf58cdede50c060633bdb14bf9603a54 Mon Sep 17 00:00:00 2001
|
|
From: Peter Jung <admin@ptr1337.dev>
|
|
Date: Mon, 3 Jun 2024 15:33:26 +0200
|
|
Subject: [PATCH] Fix 6.10 NVIDIA
|
|
|
|
Co Authord by Laio Oriel Seman <laioseman@gmail.com>
|
|
|
|
Signed-off-by: Peter Jung <admin@ptr1337.dev>
|
|
---
|
|
include/linux/mm.h | 4 ++++
|
|
mm/memory.c | 37 ++++++++++++++++++++++++++++++++++++-
|
|
mm/nommu.c | 21 +++++++++++++++++++++
|
|
3 files changed, 61 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/include/linux/mm.h b/include/linux/mm.h
|
|
index 9849dfda44d43..adc5a252da02e 100644
|
|
--- a/include/linux/mm.h
|
|
+++ b/include/linux/mm.h
|
|
@@ -2438,6 +2438,10 @@ int
|
|
copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma);
|
|
int follow_pte(struct vm_area_struct *vma, unsigned long address,
|
|
pte_t **ptepp, spinlock_t **ptlp);
|
|
+int follow_pfn(struct vm_area_struct *vma, unsigned long address,
|
|
+ unsigned long *pfn);
|
|
+//int follow_phys(struct vm_area_struct *vma, unsigned long address,
|
|
+// unsigned int flags, unsigned long *prot, resource_size_t *phys);
|
|
int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
|
|
void *buf, int len, int write);
|
|
|
|
diff --git a/mm/memory.c b/mm/memory.c
|
|
index 0f47a533014e4..0401d10b3d824 100644
|
|
--- a/mm/memory.c
|
|
+++ b/mm/memory.c
|
|
@@ -5962,7 +5962,8 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
|
|
* Only IO mappings and raw PFN mappings are allowed. The mmap semaphore
|
|
* should be taken for read.
|
|
*
|
|
- * This function must not be used to modify PTE content.
|
|
+ * KVM uses this function. While it is arguably less bad than ``follow_pfn``,
|
|
+ * it is not a good general-purpose API.
|
|
*
|
|
* Return: zero on success, -ve otherwise.
|
|
*/
|
|
@@ -6012,6 +6013,40 @@ int follow_pte(struct vm_area_struct *vma, unsigned long address,
|
|
}
|
|
EXPORT_SYMBOL_GPL(follow_pte);
|
|
|
|
+/**
|
|
+ * follow_pfn - look up PFN at a user virtual address
|
|
+ * @vma: memory mapping
|
|
+ * @address: user virtual address
|
|
+ * @pfn: location to store found PFN
|
|
+ *
|
|
+ * Only IO mappings and raw PFN mappings are allowed.
|
|
+ *
|
|
+ * This function does not allow the caller to read the permissions
|
|
+ * of the PTE. Do not use it.
|
|
+ *
|
|
+ * Return: zero and the pfn at @pfn on success, -ve otherwise.
|
|
+ */
|
|
+int follow_pfn(struct vm_area_struct *vma, unsigned long address,
|
|
+ unsigned long *pfn)
|
|
+{
|
|
+ int ret = -EINVAL;
|
|
+ spinlock_t *ptl;
|
|
+ pte_t *ptep;
|
|
+
|
|
+ if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
|
|
+ return ret;
|
|
+
|
|
+ //ret = follow_pte(vma->vm_mm, address, &ptep, &ptl);
|
|
+ ret = follow_pte(vma, address, &ptep, &ptl);
|
|
+
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ *pfn = pte_pfn(ptep_get(ptep));
|
|
+ pte_unmap_unlock(ptep, ptl);
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL(follow_pfn);
|
|
+
|
|
#ifdef CONFIG_HAVE_IOREMAP_PROT
|
|
/**
|
|
* generic_access_phys - generic implementation for iomem mmap access
|
|
diff --git a/mm/nommu.c b/mm/nommu.c
|
|
index 7296e775e04e2..8e0deb733bfef 100644
|
|
--- a/mm/nommu.c
|
|
+++ b/mm/nommu.c
|
|
@@ -110,6 +110,27 @@ unsigned int kobjsize(const void *objp)
|
|
return page_size(page);
|
|
}
|
|
|
|
+/**
|
|
+ * follow_pfn - look up PFN at a user virtual address
|
|
+ * @vma: memory mapping
|
|
+ * @address: user virtual address
|
|
+ * @pfn: location to store found PFN
|
|
+ *
|
|
+ * Only IO mappings and raw PFN mappings are allowed.
|
|
+ *
|
|
+ * Returns zero and the pfn at @pfn on success, -ve otherwise.
|
|
+ */
|
|
+int follow_pfn(struct vm_area_struct *vma, unsigned long address,
|
|
+ unsigned long *pfn)
|
|
+{
|
|
+ if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
|
|
+ return -EINVAL;
|
|
+
|
|
+ *pfn = address >> PAGE_SHIFT;
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL(follow_pfn);
|
|
+
|
|
void vfree(const void *addr)
|
|
{
|
|
kfree(addr);
|
|
--
|
|
2.45.1
|
|
|
|
--- a/kernel/nvidia-drm/nvidia-drm-drv.c
|
|
+++ b/kernel/nvidia-drm/nvidia-drm-drv.c
|
|
@@ -480,6 +480,22 @@ static int nv_drm_load(struct drm_device *dev, unsigned long flags)
|
|
return -ENODEV;
|
|
}
|
|
|
|
+#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
|
+ /*
|
|
+ * If fbdev is enabled, take modeset ownership now before other DRM clients
|
|
+ * can take master (and thus NVKMS ownership).
|
|
+ */
|
|
+ if (nv_drm_fbdev_module_param) {
|
|
+ if (!nvKms->grabOwnership(pDevice)) {
|
|
+ nvKms->freeDevice(pDevice);
|
|
+ NV_DRM_DEV_LOG_ERR(nv_dev, "Failed to grab NVKMS modeset ownership");
|
|
+ return -EBUSY;
|
|
+ }
|
|
+
|
|
+ nv_dev->hasFramebufferConsole = NV_TRUE;
|
|
+ }
|
|
+#endif
|
|
+
|
|
mutex_lock(&nv_dev->lock);
|
|
|
|
/* Set NvKmsKapiDevice */
|
|
@@ -590,6 +606,15 @@ static void __nv_drm_unload(struct drm_device *dev)
|
|
return;
|
|
}
|
|
|
|
+ /* Release modeset ownership if fbdev is enabled */
|
|
+
|
|
+#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
|
+ if (nv_dev->hasFramebufferConsole) {
|
|
+ drm_atomic_helper_shutdown(dev);
|
|
+ nvKms->releaseOwnership(nv_dev->pDevice);
|
|
+ }
|
|
+#endif
|
|
+
|
|
cancel_delayed_work_sync(&nv_dev->hotplug_event_work);
|
|
mutex_lock(&nv_dev->lock);
|
|
|
|
@@ -1768,14 +1793,7 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
|
|
}
|
|
|
|
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
|
- if (nv_drm_fbdev_module_param &&
|
|
- drm_core_check_feature(dev, DRIVER_MODESET)) {
|
|
-
|
|
- if (!nvKms->grabOwnership(nv_dev->pDevice)) {
|
|
- NV_DRM_DEV_LOG_ERR(nv_dev, "Failed to grab NVKMS modeset ownership");
|
|
- goto failed_grab_ownership;
|
|
- }
|
|
-
|
|
+ if (nv_dev->hasFramebufferConsole) {
|
|
if (bus_is_pci) {
|
|
struct pci_dev *pdev = to_pci_dev(device);
|
|
|
|
@@ -1786,8 +1804,6 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
|
|
#endif
|
|
}
|
|
drm_fbdev_generic_setup(dev, 32);
|
|
-
|
|
- nv_dev->hasFramebufferConsole = NV_TRUE;
|
|
}
|
|
#endif /* defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) */
|
|
|
|
@@ -1798,12 +1814,6 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
|
|
|
|
return; /* Success */
|
|
|
|
-#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
|
-failed_grab_ownership:
|
|
-
|
|
- drm_dev_unregister(dev);
|
|
-#endif
|
|
-
|
|
failed_drm_register:
|
|
|
|
nv_drm_dev_free(dev);
|
|
@@ -1870,12 +1880,6 @@ void nv_drm_remove_devices(void)
|
|
struct nv_drm_device *next = dev_list->next;
|
|
struct drm_device *dev = dev_list->dev;
|
|
|
|
-#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
|
- if (dev_list->hasFramebufferConsole) {
|
|
- drm_atomic_helper_shutdown(dev);
|
|
- nvKms->releaseOwnership(dev_list->pDevice);
|
|
- }
|
|
-#endif
|
|
drm_dev_unregister(dev);
|
|
nv_drm_dev_free(dev);
|
|
|
|
From 612740b11c9645e0f0240b3ca5908ef225763bc8 Mon Sep 17 00:00:00 2001
|
|
From: Peter Jung <admin@ptr1337.dev>
|
|
Date: Thu, 27 Jun 2024 19:46:51 +0200
|
|
Subject: [PATCH] gsp-stutter-fix
|
|
|
|
We've been having reports of stutter issues in 555 releases related to GSP enablement. On the proprietary driver, NVreg_EnableGpuFirmware=0 makes them go away; on the open driver that's not an option.
|
|
|
|
So far, we've identified two possible causes here. One is fixed by commit 674c009 below. The other we can't fix/workaround in the kernel modules and requires usermode changes, but commit 8c1c49b should tell us if that path is actually being hit or not.
|
|
|
|
I've also augmented the logs captured by nvidia-bug-report.sh with some of the info that we found severely lacking in the bug reports so far.
|
|
|
|
My hope is that folks that have experienced these stutter issues can take these patches, try to reproduce the issue and report back with their findings (and their nvidia-bug-report logs). Many thanks in advance to anyone willing to go the extra mile(s) for us here!
|
|
|
|
We've unfortunately missed beta2 / 555.52 with this stuff (security fixes can't wait), but here it is early so we don't have to wait on the next release.
|
|
---
|
|
kernel-open/nvidia/nv.c | 10 +
|
|
src/nvidia/arch/nvalloc/unix/include/osapi.h | 6 -
|
|
src/nvidia/arch/nvalloc/unix/src/escape.c | 46 ----
|
|
src/nvidia/arch/nvalloc/unix/src/osapi.c | 230 ++++++++-----------
|
|
src/nvidia/exports_link_command.txt | 1 -
|
|
src/nvidia/src/kernel/disp/disp_sw.c | 23 ++
|
|
6 files changed, 132 insertions(+), 184 deletions(-)
|
|
|
|
diff --git a/kernel-open/nvidia/nv.c b/kernel-open/nvidia/nv.c
|
|
index 99792de9..ccef3f29 100644
|
|
--- a/kernel-open/nvidia/nv.c
|
|
+++ b/kernel-open/nvidia/nv.c
|
|
@@ -4042,6 +4042,16 @@ int NV_API_CALL nv_get_event(
|
|
nvidia_event_t *nvet;
|
|
unsigned long eflags;
|
|
|
|
+ //
|
|
+ // Note that the head read/write is not atomic when done outside of the
|
|
+ // spinlock, so this might not be a valid pointer at all. But if we read
|
|
+ // NULL here that means that the value indeed was NULL and we can bail
|
|
+ // early since there's no events. Otherwise, we have to do a proper read
|
|
+ // under a spinlock.
|
|
+ //
|
|
+ if (nvlfp->event_data_head == NULL)
|
|
+ return NV_ERR_GENERIC;
|
|
+
|
|
NV_SPIN_LOCK_IRQSAVE(&nvlfp->fp_lock, eflags);
|
|
|
|
nvet = nvlfp->event_data_head;
|
|
diff --git a/src/nvidia/arch/nvalloc/unix/include/osapi.h b/src/nvidia/arch/nvalloc/unix/include/osapi.h
|
|
index f91e3aa5..640155e9 100644
|
|
--- a/src/nvidia/arch/nvalloc/unix/include/osapi.h
|
|
+++ b/src/nvidia/arch/nvalloc/unix/include/osapi.h
|
|
@@ -121,9 +121,6 @@ NvBool RmGpuHasIOSpaceEnabled (nv_state_t *);
|
|
void RmFreeUnusedClients (nv_state_t *, nv_file_private_t *);
|
|
NV_STATUS RmIoctl (nv_state_t *, nv_file_private_t *, NvU32, void *, NvU32);
|
|
|
|
-NV_STATUS RmAllocOsEvent (NvHandle, nv_file_private_t *, NvU32);
|
|
-NV_STATUS RmFreeOsEvent (NvHandle, NvU32);
|
|
-
|
|
void RmI2cAddGpuPorts(nv_state_t *);
|
|
|
|
NV_STATUS RmInitX86EmuState(OBJGPU *);
|
|
@@ -141,9 +138,6 @@ int amd_msr_c0011022_incompatible(OBJOS *);
|
|
|
|
NV_STATUS rm_get_adapter_status (nv_state_t *, NvU32 *);
|
|
|
|
-NV_STATUS rm_alloc_os_event (NvHandle, nv_file_private_t *, NvU32);
|
|
-NV_STATUS rm_free_os_event (NvHandle, NvU32);
|
|
-NV_STATUS rm_get_event_data (nv_file_private_t *, NvP64, NvU32 *);
|
|
void rm_client_free_os_events (NvHandle);
|
|
|
|
NV_STATUS rm_create_mmap_context (NvHandle, NvHandle, NvHandle, NvP64, NvU64, NvU64, NvU32, NvU32);
|
|
diff --git a/src/nvidia/arch/nvalloc/unix/src/escape.c b/src/nvidia/arch/nvalloc/unix/src/escape.c
|
|
index de099513..1046b19f 100644
|
|
--- a/src/nvidia/arch/nvalloc/unix/src/escape.c
|
|
+++ b/src/nvidia/arch/nvalloc/unix/src/escape.c
|
|
@@ -677,52 +677,6 @@ NV_STATUS RmIoctl(
|
|
break;
|
|
}
|
|
|
|
- case NV_ESC_ALLOC_OS_EVENT:
|
|
- {
|
|
- nv_ioctl_alloc_os_event_t *pApi = data;
|
|
-
|
|
- if (dataSize != sizeof(nv_ioctl_alloc_os_event_t))
|
|
- {
|
|
- rmStatus = NV_ERR_INVALID_ARGUMENT;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- pApi->Status = rm_alloc_os_event(pApi->hClient,
|
|
- nvfp,
|
|
- pApi->fd);
|
|
- break;
|
|
- }
|
|
-
|
|
- case NV_ESC_FREE_OS_EVENT:
|
|
- {
|
|
- nv_ioctl_free_os_event_t *pApi = data;
|
|
-
|
|
- if (dataSize != sizeof(nv_ioctl_free_os_event_t))
|
|
- {
|
|
- rmStatus = NV_ERR_INVALID_ARGUMENT;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- pApi->Status = rm_free_os_event(pApi->hClient, pApi->fd);
|
|
- break;
|
|
- }
|
|
-
|
|
- case NV_ESC_RM_GET_EVENT_DATA:
|
|
- {
|
|
- NVOS41_PARAMETERS *pApi = data;
|
|
-
|
|
- if (dataSize != sizeof(NVOS41_PARAMETERS))
|
|
- {
|
|
- rmStatus = NV_ERR_INVALID_ARGUMENT;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- pApi->status = rm_get_event_data(nvfp,
|
|
- pApi->pEvent,
|
|
- &pApi->MoreEvents);
|
|
- break;
|
|
- }
|
|
-
|
|
case NV_ESC_STATUS_CODE:
|
|
{
|
|
nv_state_t *pNv;
|
|
diff --git a/src/nvidia/arch/nvalloc/unix/src/osapi.c b/src/nvidia/arch/nvalloc/unix/src/osapi.c
|
|
index fd312466..51249750 100644
|
|
--- a/src/nvidia/arch/nvalloc/unix/src/osapi.c
|
|
+++ b/src/nvidia/arch/nvalloc/unix/src/osapi.c
|
|
@@ -25,6 +25,7 @@
|
|
|
|
#include <nv_ref.h>
|
|
#include <nv.h>
|
|
+#include <nv_escape.h>
|
|
#include <nv-priv.h>
|
|
#include <os/os.h>
|
|
#include <osapi.h>
|
|
@@ -406,6 +407,39 @@ static void free_os_events(
|
|
portSyncSpinlockRelease(nv->event_spinlock);
|
|
}
|
|
|
|
+static NV_STATUS get_os_event_data(
|
|
+ nv_file_private_t *nvfp,
|
|
+ NvP64 pEvent,
|
|
+ NvU32 *MoreEvents
|
|
+)
|
|
+{
|
|
+ nv_event_t nv_event;
|
|
+ NvUnixEvent *nv_unix_event;
|
|
+ NV_STATUS status;
|
|
+
|
|
+ status = os_alloc_mem((void**)&nv_unix_event, sizeof(NvUnixEvent));
|
|
+ if (status != NV_OK)
|
|
+ return status;
|
|
+
|
|
+ status = nv_get_event(nvfp, &nv_event, MoreEvents);
|
|
+ if (status != NV_OK)
|
|
+ {
|
|
+ status = NV_ERR_OPERATING_SYSTEM;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ os_mem_set(nv_unix_event, 0, sizeof(NvUnixEvent));
|
|
+ nv_unix_event->hObject = nv_event.hObject;
|
|
+ nv_unix_event->NotifyIndex = nv_event.index;
|
|
+ nv_unix_event->info32 = nv_event.info32;
|
|
+ nv_unix_event->info16 = nv_event.info16;
|
|
+
|
|
+ status = os_memcpy_to_user(NvP64_VALUE(pEvent), nv_unix_event, sizeof(NvUnixEvent));
|
|
+done:
|
|
+ os_free_mem(nv_unix_event);
|
|
+ return status;
|
|
+}
|
|
+
|
|
void rm_client_free_os_events(
|
|
NvHandle client
|
|
)
|
|
@@ -482,6 +516,12 @@ static NV_STATUS allocate_os_event(
|
|
goto done;
|
|
}
|
|
|
|
+ new_event->hParent = hParent;
|
|
+ new_event->nvfp = nvfp;
|
|
+ new_event->fd = fd;
|
|
+ new_event->active = NV_TRUE;
|
|
+ new_event->refcount = 0;
|
|
+
|
|
portSyncSpinlockAcquire(nv->event_spinlock);
|
|
for (event = nv->event_list; event; event = event->next)
|
|
{
|
|
@@ -496,45 +536,26 @@ static NV_STATUS allocate_os_event(
|
|
|
|
new_event->next = nv->event_list;
|
|
nv->event_list = new_event;
|
|
+ nvfp->bCleanupRmapi = NV_TRUE;
|
|
portSyncSpinlockRelease(nv->event_spinlock);
|
|
|
|
done:
|
|
if (status == NV_OK)
|
|
{
|
|
- new_event->hParent = hParent;
|
|
- new_event->nvfp = nvfp;
|
|
- new_event->fd = fd;
|
|
- new_event->active = NV_TRUE;
|
|
- new_event->refcount = 0;
|
|
-
|
|
- nvfp->bCleanupRmapi = NV_TRUE;
|
|
-
|
|
NV_PRINTF(LEVEL_INFO, "allocated OS event:\n");
|
|
NV_PRINTF(LEVEL_INFO, " hParent: 0x%x\n", hParent);
|
|
NV_PRINTF(LEVEL_INFO, " fd: %d\n", fd);
|
|
}
|
|
else
|
|
{
|
|
+ NV_PRINTF(LEVEL_ERROR, "failed to allocate OS event: 0x%08x\n", status);
|
|
+ status = NV_ERR_INSUFFICIENT_RESOURCES;
|
|
portMemFree(new_event);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
-NV_STATUS RmAllocOsEvent(
|
|
- NvHandle hParent,
|
|
- nv_file_private_t *nvfp,
|
|
- NvU32 fd
|
|
-)
|
|
-{
|
|
- if (NV_OK != allocate_os_event(hParent, nvfp, fd))
|
|
- {
|
|
- NV_PRINTF(LEVEL_ERROR, "failed to allocate OS event\n");
|
|
- return NV_ERR_INSUFFICIENT_RESOURCES;
|
|
- }
|
|
- return NV_OK;
|
|
-}
|
|
-
|
|
static NV_STATUS free_os_event(
|
|
NvHandle hParent,
|
|
NvU32 fd
|
|
@@ -585,18 +606,6 @@ static NV_STATUS free_os_event(
|
|
return result;
|
|
}
|
|
|
|
-NV_STATUS RmFreeOsEvent(
|
|
- NvHandle hParent,
|
|
- NvU32 fd
|
|
-)
|
|
-{
|
|
- if (NV_OK != free_os_event(hParent, fd))
|
|
- {
|
|
- return NV_ERR_INVALID_EVENT;
|
|
- }
|
|
- return NV_OK;
|
|
-}
|
|
-
|
|
static void RmExecuteWorkItem(
|
|
void *pWorkItem
|
|
)
|
|
@@ -656,40 +665,6 @@ done:
|
|
portMemFree((void *)pWi);
|
|
}
|
|
|
|
-static NV_STATUS RmGetEventData(
|
|
- nv_file_private_t *nvfp,
|
|
- NvP64 pEvent,
|
|
- NvU32 *MoreEvents,
|
|
- NvBool bUserModeArgs
|
|
-)
|
|
-{
|
|
- NV_STATUS RmStatus;
|
|
- NvUnixEvent *pKernelEvent = NULL;
|
|
- nv_event_t nv_event;
|
|
- RMAPI_PARAM_COPY paramCopy;
|
|
-
|
|
- RmStatus = nv_get_event(nvfp, &nv_event, MoreEvents);
|
|
- if (RmStatus != NV_OK)
|
|
- return NV_ERR_OPERATING_SYSTEM;
|
|
-
|
|
- // setup for access to client's parameters
|
|
- RMAPI_PARAM_COPY_INIT(paramCopy, pKernelEvent, pEvent, 1, sizeof(NvUnixEvent));
|
|
- RmStatus = rmapiParamsAcquire(¶mCopy, bUserModeArgs);
|
|
- if (RmStatus != NV_OK)
|
|
- return NV_ERR_OPERATING_SYSTEM;
|
|
-
|
|
- pKernelEvent->hObject = nv_event.hObject;
|
|
- pKernelEvent->NotifyIndex = nv_event.index;
|
|
- pKernelEvent->info32 = nv_event.info32;
|
|
- pKernelEvent->info16 = nv_event.info16;
|
|
-
|
|
- // release client buffer access, with copyout as needed
|
|
- if (rmapiParamsRelease(¶mCopy) != NV_OK)
|
|
- return NV_ERR_OPERATING_SYSTEM;
|
|
-
|
|
- return NV_OK;
|
|
-}
|
|
-
|
|
static NV_STATUS RmAccessRegistry(
|
|
NvHandle hClient,
|
|
NvHandle hObject,
|
|
@@ -2738,16 +2713,68 @@ NV_STATUS NV_API_CALL rm_ioctl(
|
|
NvU32 dataSize
|
|
)
|
|
{
|
|
- NV_STATUS rmStatus;
|
|
+ NV_STATUS rmStatus = NV_OK;
|
|
THREAD_STATE_NODE threadState;
|
|
void *fp;
|
|
|
|
NV_ENTER_RM_RUNTIME(sp,fp);
|
|
- threadStateInit(&threadState, THREAD_STATE_FLAGS_NONE);
|
|
|
|
- rmStatus = RmIoctl(pNv, nvfp, Command, pData, dataSize);
|
|
+ //
|
|
+ // Some ioctls are handled entirely inside the OS layer and don't need to
|
|
+ // suffer the overhead of calling into RM core.
|
|
+ //
|
|
+ switch (Command)
|
|
+ {
|
|
+ case NV_ESC_ALLOC_OS_EVENT:
|
|
+ {
|
|
+ nv_ioctl_alloc_os_event_t *pApi = pData;
|
|
+
|
|
+ if (dataSize != sizeof(nv_ioctl_alloc_os_event_t))
|
|
+ {
|
|
+ rmStatus = NV_ERR_INVALID_ARGUMENT;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ pApi->Status = allocate_os_event(pApi->hClient, nvfp, pApi->fd);
|
|
+ break;
|
|
+ }
|
|
+ case NV_ESC_FREE_OS_EVENT:
|
|
+ {
|
|
+ nv_ioctl_free_os_event_t *pApi = pData;
|
|
+
|
|
+ if (dataSize != sizeof(nv_ioctl_free_os_event_t))
|
|
+ {
|
|
+ rmStatus = NV_ERR_INVALID_ARGUMENT;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ pApi->Status = free_os_event(pApi->hClient, pApi->fd);
|
|
+ break;
|
|
+ }
|
|
+ case NV_ESC_RM_GET_EVENT_DATA:
|
|
+ {
|
|
+ NVOS41_PARAMETERS *pApi = pData;
|
|
+
|
|
+ if (dataSize != sizeof(NVOS41_PARAMETERS))
|
|
+ {
|
|
+ rmStatus = NV_ERR_INVALID_ARGUMENT;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ pApi->status = get_os_event_data(nvfp,
|
|
+ pApi->pEvent,
|
|
+ &pApi->MoreEvents);
|
|
+ break;
|
|
+ }
|
|
+ default:
|
|
+ {
|
|
+ threadStateInit(&threadState, THREAD_STATE_FLAGS_NONE);
|
|
+ rmStatus = RmIoctl(pNv, nvfp, Command, pData, dataSize);
|
|
+ threadStateFree(&threadState, THREAD_STATE_FLAGS_NONE);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
|
|
- threadStateFree(&threadState, THREAD_STATE_FLAGS_NONE);
|
|
NV_EXIT_RM_RUNTIME(sp,fp);
|
|
|
|
return rmStatus;
|
|
@@ -2882,65 +2909,6 @@ void NV_API_CALL rm_unbind_lock(
|
|
NV_EXIT_RM_RUNTIME(sp,fp);
|
|
}
|
|
|
|
-NV_STATUS rm_alloc_os_event(
|
|
- NvHandle hClient,
|
|
- nv_file_private_t *nvfp,
|
|
- NvU32 fd
|
|
-)
|
|
-{
|
|
- NV_STATUS RmStatus;
|
|
-
|
|
- // LOCK: acquire API lock
|
|
- if ((RmStatus = rmapiLockAcquire(RMAPI_LOCK_FLAGS_READ, RM_LOCK_MODULES_EVENT)) == NV_OK)
|
|
- {
|
|
- RmStatus = RmAllocOsEvent(hClient, nvfp, fd);
|
|
-
|
|
- // UNLOCK: release API lock
|
|
- rmapiLockRelease();
|
|
- }
|
|
-
|
|
- return RmStatus;
|
|
-}
|
|
-
|
|
-NV_STATUS rm_free_os_event(
|
|
- NvHandle hClient,
|
|
- NvU32 fd
|
|
-)
|
|
-{
|
|
- NV_STATUS RmStatus;
|
|
-
|
|
- // LOCK: acquire API lock
|
|
- if ((RmStatus = rmapiLockAcquire(RMAPI_LOCK_FLAGS_READ, RM_LOCK_MODULES_EVENT)) == NV_OK)
|
|
- {
|
|
- RmStatus = RmFreeOsEvent(hClient, fd);
|
|
-
|
|
- // UNLOCK: release API lock
|
|
- rmapiLockRelease();
|
|
- }
|
|
-
|
|
- return RmStatus;
|
|
-}
|
|
-
|
|
-NV_STATUS rm_get_event_data(
|
|
- nv_file_private_t *nvfp,
|
|
- NvP64 pEvent,
|
|
- NvU32 *MoreEvents
|
|
-)
|
|
-{
|
|
- NV_STATUS RmStatus;
|
|
-
|
|
- // LOCK: acquire API lock
|
|
- if ((RmStatus = rmapiLockAcquire(RMAPI_LOCK_FLAGS_READ, RM_LOCK_MODULES_EVENT)) == NV_OK)
|
|
- {
|
|
- RmStatus = RmGetEventData(nvfp, pEvent, MoreEvents, NV_TRUE);
|
|
-
|
|
- // UNLOCK: release API lock
|
|
- rmapiLockRelease();
|
|
- }
|
|
-
|
|
- return RmStatus;
|
|
-}
|
|
-
|
|
NV_STATUS NV_API_CALL rm_read_registry_dword(
|
|
nvidia_stack_t *sp,
|
|
nv_state_t *nv,
|
|
diff --git a/src/nvidia/exports_link_command.txt b/src/nvidia/exports_link_command.txt
|
|
index de3cf86d..b92185de 100644
|
|
--- a/src/nvidia/exports_link_command.txt
|
|
+++ b/src/nvidia/exports_link_command.txt
|
|
@@ -1,6 +1,5 @@
|
|
--undefined=rm_disable_adapter
|
|
--undefined=rm_execute_work_item
|
|
---undefined=rm_free_os_event
|
|
--undefined=rm_free_private_state
|
|
--undefined=rm_cleanup_file_private
|
|
--undefined=rm_unbind_lock
|
|
diff --git a/src/nvidia/src/kernel/disp/disp_sw.c b/src/nvidia/src/kernel/disp/disp_sw.c
|
|
index 03ce58f7..bb7396b6 100644
|
|
--- a/src/nvidia/src/kernel/disp/disp_sw.c
|
|
+++ b/src/nvidia/src/kernel/disp/disp_sw.c
|
|
@@ -141,8 +141,15 @@ NV_STATUS dispswReleaseSemaphoreAndNotifierFill
|
|
NvBool bFound = NV_FALSE;
|
|
NV_STATUS status;
|
|
|
|
+#define PRINT_INTERVAL 3600 // At 60Hz, this will emit about once per minute.
|
|
+
|
|
if (flags & F_SEMAPHORE_ADDR_VALID)
|
|
{
|
|
+ static NvU64 counter;
|
|
+ if ((++counter % PRINT_INTERVAL) == 0) {
|
|
+ NV_PRINTF(LEVEL_ERROR, "XXXMT: NVRM debugging - F_SEMAPHORE_ADDR_VALID = %llu\n", counter);
|
|
+ }
|
|
+
|
|
bFound = CliGetDmaMappingInfo(RES_GET_CLIENT(pDevice),
|
|
RES_GET_HANDLE(pDevice),
|
|
vaSpace,
|
|
@@ -154,6 +161,11 @@ NV_STATUS dispswReleaseSemaphoreAndNotifierFill
|
|
}
|
|
else if (flags & F_SEMAPHORE_RELEASE)
|
|
{
|
|
+ static NvU64 counter;
|
|
+ if ((++counter % PRINT_INTERVAL) == 0) {
|
|
+ NV_PRINTF(LEVEL_ERROR, "XXXMT: NVRM debugging - F_SEMAPHORE_RELEASE = %llu\n", counter);
|
|
+ }
|
|
+
|
|
status = semaphoreFillGPUVA(pGpu,
|
|
pDevice,
|
|
vaSpace,
|
|
@@ -165,6 +177,11 @@ NV_STATUS dispswReleaseSemaphoreAndNotifierFill
|
|
}
|
|
else if (flags & F_NOTIFIER_FILL)
|
|
{
|
|
+ static NvU64 counter;
|
|
+ if ((++counter % PRINT_INTERVAL) == 0) {
|
|
+ NV_PRINTF(LEVEL_ERROR, "XXXMT: NVRM debugging - F_NOTIFIER_FILL = %llu\n", counter);
|
|
+ }
|
|
+
|
|
status = notifyFillNotifierGPUVA(pGpu,
|
|
pDevice,
|
|
vaSpace,
|
|
@@ -175,5 +192,11 @@ NV_STATUS dispswReleaseSemaphoreAndNotifierFill
|
|
NV9072_NOTIFIERS_NOTIFY_ON_VBLANK /* Index */);
|
|
return status;
|
|
}
|
|
+ else {
|
|
+ static NvU64 counter;
|
|
+ if ((++counter % PRINT_INTERVAL) == 0) {
|
|
+ NV_PRINTF(LEVEL_ERROR, "XXXMT: NVRM debugging - ??? 0x%08x = %llu\n", flags, counter);
|
|
+ }
|
|
+ }
|
|
return NV9072_NOTIFICATION_STATUS_DONE_SUCCESS;
|
|
}
|
|
--
|
|
2.45.2
|
|
|
|
--- a/nvidia-drm/nvidia-drm-linux.c
|
|
+++ b/nvidia-drm/nvidia-drm-linux.c
|
|
@@ -31,13 +31,13 @@
|
|
|
|
MODULE_PARM_DESC(
|
|
modeset,
|
|
- "Enable atomic kernel modesetting (1 = enable, 0 = disable (default))");
|
|
+ "Enable atomic kernel modesetting (1 = enable (default), 0 = disable)");
|
|
module_param_named(modeset, nv_drm_modeset_module_param, bool, 0400);
|
|
|
|
#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
|
|
MODULE_PARM_DESC(
|
|
fbdev,
|
|
- "Create a framebuffer device (1 = enable, 0 = disable (default)) (EXPERIMENTAL)");
|
|
+ "Create a framebuffer device (1 = enable (default), 0 = disable) (EXPERIMENTAL)");
|
|
module_param_named(fbdev, nv_drm_fbdev_module_param, bool, 0400);
|
|
#endif
|
|
|
|
--- a/nvidia-drm/nvidia-drm-os-interface.c
|
|
+++ b/nvidia-drm/nvidia-drm-os-interface.c
|
|
@@ -41,8 +41,8 @@
|
|
#include <drm/drmP.h>
|
|
#endif
|
|
|
|
-bool nv_drm_modeset_module_param = false;
|
|
-bool nv_drm_fbdev_module_param = false;
|
|
+bool nv_drm_modeset_module_param = true;
|
|
+bool nv_drm_fbdev_module_param = true;
|
|
|
|
void *nv_drm_calloc(size_t nmemb, size_t size)
|
|
{
|
|
|
|
--- a/src/nvidia-modeset/Makefile
|
|
+++ b/src/nvidia-modeset/Makefile
|
|
@@ -142,6 +142,7 @@ ifeq ($(TARGET_ARCH),x86_64)
|
|
CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -fno-jump-tables)
|
|
CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -mindirect-branch=thunk-extern)
|
|
CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -mindirect-branch-register)
|
|
+ CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -mharden-sls=all)
|
|
endif
|
|
|
|
CFLAGS += $(CONDITIONAL_CFLAGS)
|