From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6C535C4450E for ; Fri, 10 Jul 2026 21:55:06 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2199E10F974; Fri, 10 Jul 2026 21:54:56 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="D2iLEaov"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.18]) by gabe.freedesktop.org (Postfix) with ESMTPS id 565C510E50F; Fri, 10 Jul 2026 21:54:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1783720491; x=1815256491; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Dww0yEVCQagosf6H5V5oeLo+lU6pkgwQ2dn/EPyhfeg=; b=D2iLEaovPYF9kjMqId/Alk2xoEJi1Fv6J+JJMo7wK4sjFmVS8xmGhFrg douUju20PwtYmL0Y2HwCWaV2Svjbw/a9hy51CegufN9aCToFkFXf2Avwq w9p8yvSE5oWLjYlkU/WGmsQ4g1g0rmNpepcwym7Mhoxv0cQB0Idw6TmzV mY4gyw1BelwONm9/keAzIADKpAWKIICHZnqkcNvy1fRvTLmB5uTJRq+26 s0IPaVpo+hSWXwDRZWy4E8hRYlWorUU6N5V3gtmZSBv+ctgmd8poOjJ3X +Elkn7NZl34uLEnzi5BtRo01YGv3Rl8EoKCYPxlRwM0AO5NWVtnNuZr9C w==; X-CSE-ConnectionGUID: g8PvU0uJQ8aoCthBJWte8g== X-CSE-MsgGUID: I55TIKJhQXC1NtmkwUZqBw== X-IronPort-AV: E=McAfee;i="6800,10657,11841"; a="83543124" X-IronPort-AV: E=Sophos;i="6.25,154,1779174000"; d="scan'208";a="83543124" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by fmvoesa112.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2026 14:54:51 -0700 X-CSE-ConnectionGUID: OoyyWMKcSE63nCsYVvPW+Q== X-CSE-MsgGUID: B/gyQGCKSqaaKEaTj4QDhg== X-ExtLoop1: 1 Received: from gsse-cloud1.jf.intel.com ([10.54.39.91]) by fmviesa003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2026 14:54:51 -0700 From: Matthew Brost To: intel-xe@lists.freedesktop.org, dri-devel@lists.freedesktop.org Cc: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= Subject: [PATCH v2 11/33] drm/gpusvm: Add a DMA-mapping accounting callback Date: Fri, 10 Jul 2026 14:54:20 -0700 Message-Id: <20260710215442.2444235-12-matthew.brost@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260710215442.2444235-1-matthew.brost@intel.com> References: <20260710215442.2444235-1-matthew.brost@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: intel-xe@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel Xe graphics driver List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-xe-bounces@lists.freedesktop.org Sender: "Intel-xe" From: Thomas Hellström Drivers that use the GPU SVM core to DMA-map system memory for GPU access may want to keep track of how many pages they have mapped, for example to expose statistics or to detect leaks. Doing this accounting in the driver around drm_gpusvm_get_pages() / drm_gpusvm_unmap_pages() is error prone: the number, order and kind of the dma_addr[] entries can change between map and unmap (migration, partial unmaps, the iova vs non-iova paths), which makes symmetric accounting hard to get right. Add an optional @dma_map_account callback to struct drm_gpusvm_ops and invoke it once per &drm_pagemap_addr entry at the exact points where the entry is DMA-mapped (sign == +1) in drm_gpusvm_get_pages() and unmapped (sign == -1) in __drm_gpusvm_unmap_pages(). Since the map error path and every unmap/free path funnel through __drm_gpusvm_unmap_pages() for the entries that were actually mapped, the accounting is symmetric by construction. The callback receives the full &drm_pagemap_addr so the driver can use the order and the proto field to distinguish system memory mappings from device interconnect mappings. The callback must also be usable by the core drm_gpusvm_pages-only API (mm == NULL), as used e.g. for userptr-style mappings. Relax drm_gpusvm_init() to allow such users to pass a restricted @ops that only implements the page-level hooks; the full-SVM hooks (@invalidate) and the chunk configuration must still be unset in that mode. Assisted-by: GitHub_Copilot:claude-opus-4.8 Signed-off-by: Thomas Hellström --- drivers/gpu/drm/drm_gpusvm.c | 17 +++++++++++++++-- include/drm/drm_gpusvm.h | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c index fcfe635bc195..512f52471419 100644 --- a/drivers/gpu/drm/drm_gpusvm.c +++ b/drivers/gpu/drm/drm_gpusvm.c @@ -474,8 +474,15 @@ int drm_gpusvm_init(struct drm_gpusvm *gpusvm, return -EINVAL; mmgrab(mm); } else { - /* No full SVM mode, only core drm_gpusvm_pages API. */ - if (ops || num_chunks || mm_range || notifier_size) + /* + * No full SVM mode, only core drm_gpusvm_pages API. A + * restricted @ops that only implements the page-level hooks + * (e.g. @dma_map_account) is allowed; the full-SVM hooks must + * not be set. + */ + if (num_chunks || mm_range || notifier_size) + return -EINVAL; + if (ops && ops->invalidate) return -EINVAL; } @@ -1246,6 +1253,8 @@ static void __drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm, else if (dpagemap && dpagemap->ops->device_unmap) dpagemap->ops->device_unmap(dpagemap, dev, addr); + if (gpusvm->ops && gpusvm->ops->dma_map_account) + gpusvm->ops->dma_map_account(gpusvm, addr, -1); i += 1 << addr->order; } @@ -1654,6 +1663,10 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, (addr, DRM_INTERCONNECT_SYSTEM, order, dma_dir); } + if (gpusvm->ops && gpusvm->ops->dma_map_account) + gpusvm->ops->dma_map_account(gpusvm, + &svm_pages->dma_addr[j], + 1); i += 1 << order; num_dma_mapped = i; flags.has_dma_mapping = true; diff --git a/include/drm/drm_gpusvm.h b/include/drm/drm_gpusvm.h index b7d987bf76aa..36f35816a569 100644 --- a/include/drm/drm_gpusvm.h +++ b/include/drm/drm_gpusvm.h @@ -75,6 +75,25 @@ struct drm_gpusvm_ops { void (*invalidate)(struct drm_gpusvm *gpusvm, struct drm_gpusvm_notifier *notifier, const struct mmu_notifier_range *mmu_range); + + /** + * @dma_map_account: Account a DMA-mapping change (optional) + * @gpusvm: Pointer to the GPU SVM + * @addr: The address descriptor of the chunk being (un)mapped + * @sign: +1 when @addr has just been DMA-mapped, -1 when it is being + * unmapped + * + * Called once per &drm_pagemap_addr entry, when the entry is + * DMA-mapped by drm_gpusvm_get_pages() (@sign == +1) and when it is + * unmapped (@sign == -1), so the driver can keep symmetric accounting + * of the pages it has mapped for GPU access. The @addr->proto field + * can be used to distinguish system-memory mappings from device + * interconnect mappings. May be provided in both full SVM mode and the + * core drm_gpusvm_pages-only mode. + */ + void (*dma_map_account)(struct drm_gpusvm *gpusvm, + const struct drm_pagemap_addr *addr, + int sign); }; /** -- 2.34.1