From 8eeaf4203baae35badcf923f5237884b877fdf96 Mon Sep 17 00:00:00 2001 From: Pppp1116 Date: Wed, 25 Mar 2026 13:48:19 +0000 Subject: [PATCH 1/2] drm: reduce fence-path overhead and improve modeset diagnostics --- kernel-open/nvidia-drm/nvidia-drm-fence.c | 24 ++++++++++++----- .../nvidia-drm/nvidia-drm-gem-dma-buf.c | 2 +- kernel-open/nvidia-drm/nvidia-drm-modeset.c | 27 ++++++++++++------- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/kernel-open/nvidia-drm/nvidia-drm-fence.c b/kernel-open/nvidia-drm/nvidia-drm-fence.c index 7af1ed7f1..cdbfc499c 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-fence.c +++ b/kernel-open/nvidia-drm/nvidia-drm-fence.c @@ -1390,6 +1390,7 @@ __nv_drm_semsurf_ctx_add_pending(struct nv_drm_semsurf_fence_ctx *ctx, NvU64 timeoutMS) { struct list_head *pending; + NvU64 fence_seqno; unsigned long flags; if (timeoutMS > NV_DRM_SEMAPHORE_SURFACE_FENCE_MAX_TIMEOUT_MS) { @@ -1401,14 +1402,28 @@ __nv_drm_semsurf_ctx_add_pending(struct nv_drm_semsurf_fence_ctx *ctx, INIT_LIST_HEAD(&nv_fence->pending_node); nv_fence->timeout = nv_drm_timeout_from_ms(timeoutMS); + fence_seqno = __nv_drm_get_semsurf_fence_seqno(nv_fence); spin_lock_irqsave(&ctx->lock, flags); + /* + * Most callers append increasing wait values. Fast-path append in that + * case to avoid scanning the whole list on each fence creation. + */ + if (!list_empty(&ctx->pending_fences)) { + struct nv_drm_semsurf_fence *tail_fence = + list_last_entry(&ctx->pending_fences, + struct nv_drm_semsurf_fence, pending_node); + if (__nv_drm_get_semsurf_fence_seqno(tail_fence) <= fence_seqno) { + list_add_tail(&nv_fence->pending_node, &ctx->pending_fences); + goto added_pending; + } + } + list_for_each(pending, &ctx->pending_fences) { struct nv_drm_semsurf_fence *pending_fence = list_entry(pending, typeof(*pending_fence), pending_node); - if (__nv_drm_get_semsurf_fence_seqno(pending_fence) > - __nv_drm_get_semsurf_fence_seqno(nv_fence)) { + if (__nv_drm_get_semsurf_fence_seqno(pending_fence) > fence_seqno) { /* Inserts 'nv_fence->pending_node' before 'pending' */ list_add_tail(&nv_fence->pending_node, pending); break; @@ -1416,13 +1431,10 @@ __nv_drm_semsurf_ctx_add_pending(struct nv_drm_semsurf_fence_ctx *ctx, } if (list_empty(&nv_fence->pending_node)) { - /* - * Inserts 'fence->pending_node' at the end of 'ctx->pending_fences', - * or as the head if the list is empty - */ list_add_tail(&nv_fence->pending_node, &ctx->pending_fences); } +added_pending: /* Fence is live starting... now! */ spin_unlock_irqrestore(&ctx->lock, flags); diff --git a/kernel-open/nvidia-drm/nvidia-drm-gem-dma-buf.c b/kernel-open/nvidia-drm/nvidia-drm-gem-dma-buf.c index 163a8ecf6..55b49aadc 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-gem-dma-buf.c +++ b/kernel-open/nvidia-drm/nvidia-drm-gem-dma-buf.c @@ -151,7 +151,7 @@ nv_drm_gem_prime_import_sg_table(struct drm_device *dev, BUG_ON(dma_buf->size % PAGE_SIZE); pMemory = NULL; - if (drm_core_check_feature(dev, DRIVER_MODESET)) { + if (drm_core_check_feature(dev, DRIVER_MODESET) && nv_dev->pDevice != NULL) { pMemory = nvKms->getSystemMemoryHandleFromDmaBuf(nv_dev->pDevice, (NvP64)(NvUPtr)dma_buf, dma_buf->size - 1); diff --git a/kernel-open/nvidia-drm/nvidia-drm-modeset.c b/kernel-open/nvidia-drm/nvidia-drm-modeset.c index da167a075..6be98234b 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-modeset.c +++ b/kernel-open/nvidia-drm/nvidia-drm-modeset.c @@ -136,22 +136,24 @@ static bool __will_generate_flip_event(struct drm_crtc *crtc, static int __nv_drm_put_back_post_fence_fd( struct nv_drm_plane_state *plane_state, + struct nv_drm_device *nv_dev, const struct NvKmsKapiLayerReplyConfig *layer_reply_config) { int fd = layer_reply_config->postSyncptFd; - int ret = 0; if ((fd >= 0) && (plane_state->fd_user_ptr != NULL)) { - ret = copy_to_user(plane_state->fd_user_ptr, &fd, sizeof(fd)); - if (ret != 0) { - return ret; + if (copy_to_user(plane_state->fd_user_ptr, &fd, sizeof(fd)) != 0) { + NV_DRM_DEV_LOG_ERR( + nv_dev, + "Failed to copy post fence FD to userspace"); + return -EFAULT; } /*! set back to Null and let set_property specify it again */ plane_state->fd_user_ptr = NULL; } - return ret; + return 0; } struct nv_drm_plane_fence_cb_data { @@ -300,7 +302,7 @@ static int __nv_drm_convert_in_fences( default: NV_DRM_DEV_LOG_ERR( nv_dev, - "Failed plane fence callback registration"); + "Failed plane fence callback registration, ret=%d", ret); /* Fence callback registration failed */ nvKms->cancelDisplaySemaphore(nv_dev->pDevice, semaphore_index); nv_drm_free(fence_data); @@ -315,7 +317,6 @@ static int __nv_drm_get_syncpt_data( struct nv_drm_device *nv_dev, struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state, - struct NvKmsKapiRequestedModeSetConfig *requested_config, struct NvKmsKapiModeSetReplyConfig *reply_config) { struct nv_drm_crtc *nv_crtc = to_nv_crtc(crtc); @@ -355,6 +356,7 @@ static int __nv_drm_get_syncpt_data( ret = __nv_drm_put_back_post_fence_fd( plane_state, + nv_dev, &head_reply_config->layerReplyConfig[nv_plane->layer_idx]); if (ret != 0) { @@ -487,6 +489,11 @@ nv_drm_atomic_apply_modeset_config(struct drm_device *dev, requested_config, &reply_config, commit)) { + NV_DRM_DEV_LOG_ERR( + nv_dev, + "Failed to apply modeset config (commit=%u, flipResult=%u)", + commit, + reply_config.flipResult); if (commit || reply_config.flipResult != NV_KMS_FLIP_RESULT_IN_PROGRESS) { return -EINVAL; } @@ -497,7 +504,7 @@ nv_drm_atomic_apply_modeset_config(struct drm_device *dev, for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) { /*! loop over affected crtcs and get NvKmsKapiModeSetReplyConfig */ ret = __nv_drm_get_syncpt_data( - nv_dev, crtc, old_crtc_state, requested_config, &reply_config); + nv_dev, crtc, old_crtc_state, &reply_config); if (ret != 0) { return ret; } @@ -611,7 +618,9 @@ static void __nv_drm_handle_flip_event(struct nv_drm_crtc *nv_crtc) } spin_unlock(&dev->event_lock); - wake_up_all(&nv_dev->flip_event_wq); + if (nv_flip != NULL) { + wake_up_all(&nv_dev->flip_event_wq); + } nv_drm_free(nv_flip); } From ac5255915e18ca09792d49c5850fecd78b389a43 Mon Sep 17 00:00:00 2001 From: Pppp1116 Date: Wed, 25 Mar 2026 13:58:32 +0000 Subject: [PATCH 2/2] drm: only log applyModeSetConfig failures on true errors --- kernel-open/nvidia-drm/nvidia-drm-modeset.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel-open/nvidia-drm/nvidia-drm-modeset.c b/kernel-open/nvidia-drm/nvidia-drm-modeset.c index 6be98234b..a010ed12c 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-modeset.c +++ b/kernel-open/nvidia-drm/nvidia-drm-modeset.c @@ -489,12 +489,12 @@ nv_drm_atomic_apply_modeset_config(struct drm_device *dev, requested_config, &reply_config, commit)) { - NV_DRM_DEV_LOG_ERR( - nv_dev, - "Failed to apply modeset config (commit=%u, flipResult=%u)", - commit, - reply_config.flipResult); if (commit || reply_config.flipResult != NV_KMS_FLIP_RESULT_IN_PROGRESS) { + NV_DRM_DEV_LOG_ERR( + nv_dev, + "Failed to apply modeset config (commit=%u, flipResult=%u)", + commit, + reply_config.flipResult); return -EINVAL; } }