From nobody Sun Feb 8 10:50:20 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 190EA263F5E for ; Wed, 23 Apr 2025 03:09:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745377795; cv=none; b=T9IguwmpiE5wKJDnvczeeQfPqdKvXtOBjSNGan4WaTkaXEbZ/TVDQC/+ds4dmfWEGfQpM4eRMLCCQuMHaPLC0NitqYl/qUUYdbhDfQxT9EIxVOQxHvY3dGKtQorigQODXD0F0PgdYPsTzsU3IJQWrIvznimrCokZzTQ/L/P63VE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745377795; c=relaxed/simple; bh=oTpsehoZbXy0jXsOZr3vLVODxh7wFFjRuhGAMhkosps=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mkufbvhGnRT4Oj3rNr4nFpGbm83+iHDoHzKNRLOD3hx9jGFnkfl1R7Uo+LmermUpSWpd+WHVOLPVSJ5ZuwhvlYduCLZPH1T7tkQn0nMvUKjPilAH8yHcstXkRqYYxyRockpTYm1d49ld0NFbbYnaLUCoNARAmuiczwR3cQdxuAg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=kh2gj0B8; arc=none smtp.client-ip=198.175.65.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="kh2gj0B8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1745377794; x=1776913794; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oTpsehoZbXy0jXsOZr3vLVODxh7wFFjRuhGAMhkosps=; b=kh2gj0B8o8QIJI8MxVvsx9ecE6KU+w2VNHLtr7XsQUjVcxZt2R7vRDjY oweixX+xcVYmoFh9XeJy9qOjmVTNsE+qEwYhnkL0RtNUsuYgPCPJSoyBf EzWiUiGiar5MdXeQPvZfTdIc+q+oZ55A+iXa03z7XVcZDYue1/IezUF2B ODDkZsgqH0bIXSfpSfEDphxdqI2h2MbMluGuIiCCd6vQX6utsV41JZ3id iviCWo27s9YkA/xEdeNHdHW8XNAHlaoB0dk/RWlOs1DrKgkbEvWoDaJcr XjrD+QrRJ7lWJSUFV5EYZzRAYL12l1YmRcAWr8cbEIykrNQYuJBtoL1Oe g==; X-CSE-ConnectionGUID: kg/sRbGUQYyLvxqJT0Yu/Q== X-CSE-MsgGUID: wIu0Bdk8SqGvQjSpuMoLwg== X-IronPort-AV: E=McAfee;i="6700,10204,11411"; a="57145937" X-IronPort-AV: E=Sophos;i="6.15,232,1739865600"; d="scan'208";a="57145937" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Apr 2025 20:09:53 -0700 X-CSE-ConnectionGUID: rGduN7WgRFO7X7xDBQNulw== X-CSE-MsgGUID: b7I9iVkKQPKG4fAmwcBMLg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.15,232,1739865600"; d="scan'208";a="155398698" Received: from allen-box.sh.intel.com ([10.239.159.52]) by fmviesa002.fm.intel.com with ESMTP; 22 Apr 2025 20:09:51 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian Cc: iommu@lists.linux.dev, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 1/3] iommu/vt-d: Use ida to manage domain id Date: Wed, 23 Apr 2025 11:10:18 +0800 Message-ID: <20250423031020.2189546-2-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250423031020.2189546-1-baolu.lu@linux.intel.com> References: <20250423031020.2189546-1-baolu.lu@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Switch the intel iommu driver to use the ida mechanism for managing domain IDs, replacing the previous fixed-size bitmap. The previous approach allocated a bitmap large enough to cover the maximum number of domain IDs supported by the hardware, regardless of the actual number of domains in use. This led to unnecessary memory consumption, especially on systems supporting a large number of iommu units but only utilizing a small number of domain IDs. The ida allocator dynamically manages the allocation and freeing of integer IDs, only consuming memory for the IDs that are currently in use. This significantly optimizes memory usage compared to the fixed-size bitmap. Signed-off-by: Lu Baolu Reviewed-by: Kevin Tian --- drivers/iommu/intel/dmar.c | 2 + drivers/iommu/intel/iommu.c | 80 ++++++++----------------------------- drivers/iommu/intel/iommu.h | 18 +++++++-- 3 files changed, 33 insertions(+), 67 deletions(-) diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c index e540092d664d..0afba7434a5c 100644 --- a/drivers/iommu/intel/dmar.c +++ b/drivers/iommu/intel/dmar.c @@ -1099,6 +1099,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) spin_lock_init(&iommu->device_rbtree_lock); mutex_init(&iommu->iopf_lock); iommu->node =3D NUMA_NO_NODE; + spin_lock_init(&iommu->lock); + ida_init(&iommu->domain_ida); =20 ver =3D readl(iommu->reg + DMAR_VER_REG); pr_info("%s: reg_base_addr %llx ver %d:%d cap %llx ecap %llx\n", diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index b29da2d96d0b..76e170922149 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -1289,52 +1289,13 @@ static void iommu_disable_translation(struct intel_= iommu *iommu) raw_spin_unlock_irqrestore(&iommu->register_lock, flag); } =20 -static int iommu_init_domains(struct intel_iommu *iommu) -{ - u32 ndomains; - - ndomains =3D cap_ndoms(iommu->cap); - pr_debug("%s: Number of Domains supported <%d>\n", - iommu->name, ndomains); - - spin_lock_init(&iommu->lock); - - iommu->domain_ids =3D bitmap_zalloc(ndomains, GFP_KERNEL); - if (!iommu->domain_ids) - return -ENOMEM; - - /* - * If Caching mode is set, then invalid translations are tagged - * with domain-id 0, hence we need to pre-allocate it. We also - * use domain-id 0 as a marker for non-allocated domain-id, so - * make sure it is not used for a real domain. - */ - set_bit(0, iommu->domain_ids); - - /* - * Vt-d spec rev3.0 (section 6.2.3.1) requires that each pasid - * entry for first-level or pass-through translation modes should - * be programmed with a domain id different from those used for - * second-level or nested translation. We reserve a domain id for - * this purpose. This domain id is also used for identity domain - * in legacy mode. - */ - set_bit(FLPT_DEFAULT_DID, iommu->domain_ids); - - return 0; -} - static void disable_dmar_iommu(struct intel_iommu *iommu) { - if (!iommu->domain_ids) - return; - /* * All iommu domains must have been detached from the devices, * hence there should be no domain IDs in use. */ - if (WARN_ON(bitmap_weight(iommu->domain_ids, cap_ndoms(iommu->cap)) - > NUM_RESERVED_DID)) + if (WARN_ON(!ida_is_empty(&iommu->domain_ida))) return; =20 if (iommu->gcmd & DMA_GCMD_TE) @@ -1343,10 +1304,7 @@ static void disable_dmar_iommu(struct intel_iommu *i= ommu) =20 static void free_dmar_iommu(struct intel_iommu *iommu) { - if (iommu->domain_ids) { - bitmap_free(iommu->domain_ids); - iommu->domain_ids =3D NULL; - } + ida_destroy(&iommu->domain_ida); =20 if (iommu->copied_tables) { bitmap_free(iommu->copied_tables); @@ -1380,7 +1338,6 @@ static bool first_level_by_default(struct intel_iommu= *iommu) int domain_attach_iommu(struct dmar_domain *domain, struct intel_iommu *io= mmu) { struct iommu_domain_info *info, *curr; - unsigned long ndomains; int num, ret =3D -ENOSPC; =20 if (domain->domain.type =3D=3D IOMMU_DOMAIN_SVA) @@ -1399,14 +1356,13 @@ int domain_attach_iommu(struct dmar_domain *domain,= struct intel_iommu *iommu) return 0; } =20 - ndomains =3D cap_ndoms(iommu->cap); - num =3D find_first_zero_bit(iommu->domain_ids, ndomains); - if (num >=3D ndomains) { + num =3D ida_alloc_range(&iommu->domain_ida, FLPT_DEFAULT_DID + 1, + cap_ndoms(iommu->cap) - 1, GFP_ATOMIC); + if (num < 0) { pr_err("%s: No free domain ids\n", iommu->name); goto err_unlock; } =20 - set_bit(num, iommu->domain_ids); info->refcnt =3D 1; info->did =3D num; info->iommu =3D iommu; @@ -1421,7 +1377,7 @@ int domain_attach_iommu(struct dmar_domain *domain, s= truct intel_iommu *iommu) return 0; =20 err_clear: - clear_bit(info->did, iommu->domain_ids); + ida_free(&iommu->domain_ida, info->did); err_unlock: spin_unlock(&iommu->lock); kfree(info); @@ -1438,7 +1394,7 @@ void domain_detach_iommu(struct dmar_domain *domain, = struct intel_iommu *iommu) spin_lock(&iommu->lock); info =3D xa_load(&domain->iommu_array, iommu->seq_id); if (--info->refcnt =3D=3D 0) { - clear_bit(info->did, iommu->domain_ids); + ida_free(&iommu->domain_ida, info->did); xa_erase(&domain->iommu_array, iommu->seq_id); domain->nid =3D NUMA_NO_NODE; kfree(info); @@ -2042,7 +1998,7 @@ static int copy_context_table(struct intel_iommu *iom= mu, =20 did =3D context_domain_id(&ce); if (did >=3D 0 && did < cap_ndoms(iommu->cap)) - set_bit(did, iommu->domain_ids); + ida_alloc_range(&iommu->domain_ida, did, did + 1, GFP_KERNEL); =20 set_context_copied(iommu, bus, devfn); new_ce[idx] =3D ce; @@ -2169,11 +2125,6 @@ static int __init init_dmars(void) } =20 intel_iommu_init_qi(iommu); - - ret =3D iommu_init_domains(iommu); - if (ret) - goto free_iommu; - init_translation_status(iommu); =20 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) { @@ -2651,9 +2602,7 @@ static int intel_iommu_add(struct dmar_drhd_unit *dma= ru) if (iommu->gcmd & DMA_GCMD_TE) iommu_disable_translation(iommu); =20 - ret =3D iommu_init_domains(iommu); - if (ret =3D=3D 0) - ret =3D iommu_alloc_root_entry(iommu); + ret =3D iommu_alloc_root_entry(iommu); if (ret) goto out; =20 @@ -2972,9 +2921,14 @@ static ssize_t domains_used_show(struct device *dev, struct device_attribute *attr, char *buf) { struct intel_iommu *iommu =3D dev_to_intel_iommu(dev); - return sysfs_emit(buf, "%d\n", - bitmap_weight(iommu->domain_ids, - cap_ndoms(iommu->cap))); + unsigned int count =3D 0; + int id; + + for (id =3D 0; id < cap_ndoms(iommu->cap); id++) + if (ida_exists(&iommu->domain_ida, id)) + count++; + + return sysfs_emit(buf, "%d\n", count); } static DEVICE_ATTR_RO(domains_used); =20 diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index c4916886da5a..993232292400 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -722,7 +722,7 @@ struct intel_iommu { unsigned char name[16]; /* Device Name */ =20 #ifdef CONFIG_INTEL_IOMMU - unsigned long *domain_ids; /* bitmap of domains */ + struct ida domain_ida; /* domain id allocator */ unsigned long *copied_tables; /* bitmap of copied tables */ spinlock_t lock; /* protect context, domain ids */ struct root_entry *root_entry; /* virtual address */ @@ -809,11 +809,21 @@ static inline struct dmar_domain *to_dmar_domain(stru= ct iommu_domain *dom) } =20 /* - * Domain ID reserved for pasid entries programmed for first-level - * only and pass-through transfer modes. + * Domain ID 0 and 1 are reserved: + * + * If Caching mode is set, then invalid translations are tagged + * with domain-id 0, hence we need to pre-allocate it. We also + * use domain-id 0 as a marker for non-allocated domain-id, so + * make sure it is not used for a real domain. + * + * Vt-d spec rev3.0 (section 6.2.3.1) requires that each pasid + * entry for first-level or pass-through translation modes should + * be programmed with a domain id different from those used for + * second-level or nested translation. We reserve a domain id for + * this purpose. This domain id is also used for identity domain + * in legacy mode. */ #define FLPT_DEFAULT_DID 1 -#define NUM_RESERVED_DID 2 =20 /* Retrieve the domain ID which has allocated to the domain */ static inline u16 --=20 2.43.0 From nobody Sun Feb 8 10:50:20 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16E69265602 for ; Wed, 23 Apr 2025 03:09:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745377797; cv=none; b=Zemf4mgx3bJZWVhlDfJHWvQRb8akAO20Kh23E8zcMkWJYnKqMYvEKP7Kdj2ldiWU64MKqEAjvXG2FH1V2OqHvGUlfKfrFImFJdF65k9mj6EL1DisHA2Abfaw1EYha9Xp2buzCPja8ltNsyQS6WVgcP0GucxnqDGYMR81Wc5qTD8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745377797; c=relaxed/simple; bh=+hW7JcAr+6EOSDzqv7OIfCrpIM+Dso5F0RZpEoC2c/Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=If6oC+bKttwWuy6OWskuNN2ZoQq6r7qqYLv/CK4AvILoTV7hMB81XZlcpwseUValJvZcoWr9eFU4kieK6GKqIAfzgScFb9gtBejVFA5v8VsPX3xRhBUfXLE5Hd84C4ea37EfOl69XEjKRW0Z+yRQDoRazZPVPsWe9q0t20x/RWc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=TRaMZFqp; arc=none smtp.client-ip=198.175.65.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="TRaMZFqp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1745377796; x=1776913796; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+hW7JcAr+6EOSDzqv7OIfCrpIM+Dso5F0RZpEoC2c/Q=; b=TRaMZFqpllG59xwjbhJjZP5TRAn51DuwrtRMN6QAZ6EMPARH9crdkB8K XB/Utxx3eS+LaKN22JrRCmfBGnrfR7e1b+jQ6U3QEJHjLVxK1Otw47vMI JDGdZX3uXGGYxdDOHqR2ie9cd9DjBv1wCnTCD4TaEAgQkVQI9lkf2/83X 9v/qbC8ddqZL6nEwwpCAZLJSuWP33GhrmXpvn691nmSEz6XRRKLgcI576 UUsxMjOra75ovpsUU2xVKxFz9aAbUEX18Ila1ohrUrLzGzmcsKu53db81 u/0U252ruE/WOvFfViaunAoEphJ8Wf94MxrrE2tLT2EbsUDgSZ/XWoltW Q==; X-CSE-ConnectionGUID: dhEv3wRVQJGz1CpdxAaatw== X-CSE-MsgGUID: K8E4k3YkSomTzcp72GdTDA== X-IronPort-AV: E=McAfee;i="6700,10204,11411"; a="57145943" X-IronPort-AV: E=Sophos;i="6.15,232,1739865600"; d="scan'208";a="57145943" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Apr 2025 20:09:55 -0700 X-CSE-ConnectionGUID: fB2ijo1rS32UJK9a9CbBVA== X-CSE-MsgGUID: x/IwPMz2TDe1OlpeMDQ6qQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.15,232,1739865600"; d="scan'208";a="155398704" Received: from allen-box.sh.intel.com ([10.239.159.52]) by fmviesa002.fm.intel.com with ESMTP; 22 Apr 2025 20:09:53 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian Cc: iommu@lists.linux.dev, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 2/3] iommu/vt-d: Replace spin_lock with mutex to protect domain ida Date: Wed, 23 Apr 2025 11:10:19 +0800 Message-ID: <20250423031020.2189546-3-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250423031020.2189546-1-baolu.lu@linux.intel.com> References: <20250423031020.2189546-1-baolu.lu@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The domain ID allocator is currently protected by a spin_lock. However, ida_alloc_range can potentially block if it needs to allocate memory to grow its internal structures. Replace the spin_lock with a mutex which allows sleep on block. Thus, the memory allocation flags can be updated from GFP_ATOMIC to GFP_KERNEL to allow blocking memory allocations if necessary. Introduce a new mutex, did_lock, specifically for protecting the domain ida. The existing spinlock will remain for protecting other intel_iommu fields. Signed-off-by: Lu Baolu Reviewed-by: Kevin Tian --- drivers/iommu/intel/dmar.c | 1 + drivers/iommu/intel/iommu.c | 12 ++++-------- drivers/iommu/intel/iommu.h | 2 ++ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c index 0afba7434a5c..e25e8d3dedcb 100644 --- a/drivers/iommu/intel/dmar.c +++ b/drivers/iommu/intel/dmar.c @@ -1101,6 +1101,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->node =3D NUMA_NO_NODE; spin_lock_init(&iommu->lock); ida_init(&iommu->domain_ida); + mutex_init(&iommu->did_lock); =20 ver =3D readl(iommu->reg + DMAR_VER_REG); pr_info("%s: reg_base_addr %llx ver %d:%d cap %llx ecap %llx\n", diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 76e170922149..3a9ea0ad2cd3 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -1347,17 +1347,16 @@ int domain_attach_iommu(struct dmar_domain *domain,= struct intel_iommu *iommu) if (!info) return -ENOMEM; =20 - spin_lock(&iommu->lock); + guard(mutex)(&iommu->did_lock); curr =3D xa_load(&domain->iommu_array, iommu->seq_id); if (curr) { curr->refcnt++; - spin_unlock(&iommu->lock); kfree(info); return 0; } =20 num =3D ida_alloc_range(&iommu->domain_ida, FLPT_DEFAULT_DID + 1, - cap_ndoms(iommu->cap) - 1, GFP_ATOMIC); + cap_ndoms(iommu->cap) - 1, GFP_KERNEL); if (num < 0) { pr_err("%s: No free domain ids\n", iommu->name); goto err_unlock; @@ -1367,19 +1366,17 @@ int domain_attach_iommu(struct dmar_domain *domain,= struct intel_iommu *iommu) info->did =3D num; info->iommu =3D iommu; curr =3D xa_cmpxchg(&domain->iommu_array, iommu->seq_id, - NULL, info, GFP_ATOMIC); + NULL, info, GFP_KERNEL); if (curr) { ret =3D xa_err(curr) ? : -EBUSY; goto err_clear; } =20 - spin_unlock(&iommu->lock); return 0; =20 err_clear: ida_free(&iommu->domain_ida, info->did); err_unlock: - spin_unlock(&iommu->lock); kfree(info); return ret; } @@ -1391,7 +1388,7 @@ void domain_detach_iommu(struct dmar_domain *domain, = struct intel_iommu *iommu) if (domain->domain.type =3D=3D IOMMU_DOMAIN_SVA) return; =20 - spin_lock(&iommu->lock); + guard(mutex)(&iommu->did_lock); info =3D xa_load(&domain->iommu_array, iommu->seq_id); if (--info->refcnt =3D=3D 0) { ida_free(&iommu->domain_ida, info->did); @@ -1399,7 +1396,6 @@ void domain_detach_iommu(struct dmar_domain *domain, = struct intel_iommu *iommu) domain->nid =3D NUMA_NO_NODE; kfree(info); } - spin_unlock(&iommu->lock); } =20 static void domain_exit(struct dmar_domain *domain) diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 993232292400..1e98c10ca553 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -722,6 +722,8 @@ struct intel_iommu { unsigned char name[16]; /* Device Name */ =20 #ifdef CONFIG_INTEL_IOMMU + /* mutex to protect domain_ida */ + struct mutex did_lock; struct ida domain_ida; /* domain id allocator */ unsigned long *copied_tables; /* bitmap of copied tables */ spinlock_t lock; /* protect context, domain ids */ --=20 2.43.0 From nobody Sun Feb 8 10:50:20 2026 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 00CC5265CDC for ; Wed, 23 Apr 2025 03:09:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745377799; cv=none; b=JU94MCmOoymGLGFLamFaZj+TwYiAvMjkrgyjVbPDLnXtIzSajtuv+pbgspHRAWdUHdZ/4akV6LieS/oZkMkS6hahFnOPYrH8wxr7XrGe2JIHI9+SBkEelVdnchb5W547Bb533+rn/kGay4l/yGE0aPeKbQ4vDcYsbinb0aRDqAc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745377799; c=relaxed/simple; bh=GycVYA/NvO+xmkaA5ol9tDUppgYdB32anXTkGIawxtk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rll0WmHQVZKhmwqsOsGdsnVOrmsZvSHKYY2V2/POjCIWzFr6b3t1P5YpqkJHwk/aw0GUpA2djfdtXsmPzQ+LcJE5eOqkpg+cYqDJjDngHeFLaQOn1xkTp+ghfYl/NpHsaYoe1+R4njhfuNJK3pSyQEOA/s23VpGOKM9RKZn8Gt8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=P4FEI6OA; arc=none smtp.client-ip=198.175.65.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="P4FEI6OA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1745377798; x=1776913798; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GycVYA/NvO+xmkaA5ol9tDUppgYdB32anXTkGIawxtk=; b=P4FEI6OAabCD/LxJ1fTL1PN67tTGLCz57mir913JoF3d4oou7UZ33Sjv a9PCiIIgDRDB/ujZbze+0H1oMcdxqSOJ0IMyGrz0CU9TM09np318fNpSJ 6V/Ylzh2chuA6a9rYDEivXMIw8ssw3A5/V7WX6viMhu3v4UJwLQtMRAX8 8lxFLjJc/m9vf79CgNEvSJK1rY33fL5YkximqZmyYR9CRrzaRUhoFAnOa X5Driu8bFQMTI0nt04Iwbf/F/67Ce9MLOkETgPVJGFT7ngmFxfLMrXQt3 YKAyhCN26VLr8xKtzdt2eI0P8wJc1oAcBhWNe7HAa1n2PFR4hw2xhw8E0 w==; X-CSE-ConnectionGUID: ZMU91c/oSkimcWblUuFkiA== X-CSE-MsgGUID: RcXk4T7IRoWgtgZ4QSv8NQ== X-IronPort-AV: E=McAfee;i="6700,10204,11411"; a="57145950" X-IronPort-AV: E=Sophos;i="6.15,232,1739865600"; d="scan'208";a="57145950" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Apr 2025 20:09:57 -0700 X-CSE-ConnectionGUID: 2UArvlSUTc2bYAbSg/Fneg== X-CSE-MsgGUID: s3M7YOd5T++tWRjrts7LYA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.15,232,1739865600"; d="scan'208";a="155398708" Received: from allen-box.sh.intel.com ([10.239.159.52]) by fmviesa002.fm.intel.com with ESMTP; 22 Apr 2025 20:09:56 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian Cc: iommu@lists.linux.dev, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 3/3] iommu/vt-d: Simplify domain_attach_iommu() Date: Wed, 23 Apr 2025 11:10:20 +0800 Message-ID: <20250423031020.2189546-4-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250423031020.2189546-1-baolu.lu@linux.intel.com> References: <20250423031020.2189546-1-baolu.lu@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use the __free(kfree) attribute with kzalloc() to automatically handle the freeing of the allocated struct iommu_domain_info on error or early exit paths, eliminating the need for explicit kfree() calls in error handling branches. Signed-off-by: Lu Baolu --- drivers/iommu/intel/iommu.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 3a9ea0ad2cd3..12382c85495f 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -1337,13 +1337,14 @@ static bool first_level_by_default(struct intel_iom= mu *iommu) =20 int domain_attach_iommu(struct dmar_domain *domain, struct intel_iommu *io= mmu) { - struct iommu_domain_info *info, *curr; - int num, ret =3D -ENOSPC; + struct iommu_domain_info *curr; + int num; =20 if (domain->domain.type =3D=3D IOMMU_DOMAIN_SVA) return 0; =20 - info =3D kzalloc(sizeof(*info), GFP_KERNEL); + struct iommu_domain_info *info __free(kfree) =3D + kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; =20 @@ -1351,34 +1352,20 @@ int domain_attach_iommu(struct dmar_domain *domain,= struct intel_iommu *iommu) curr =3D xa_load(&domain->iommu_array, iommu->seq_id); if (curr) { curr->refcnt++; - kfree(info); return 0; } =20 num =3D ida_alloc_range(&iommu->domain_ida, FLPT_DEFAULT_DID + 1, cap_ndoms(iommu->cap) - 1, GFP_KERNEL); - if (num < 0) { - pr_err("%s: No free domain ids\n", iommu->name); - goto err_unlock; - } + if (num < 0) + return num; =20 info->refcnt =3D 1; info->did =3D num; info->iommu =3D iommu; - curr =3D xa_cmpxchg(&domain->iommu_array, iommu->seq_id, - NULL, info, GFP_KERNEL); - if (curr) { - ret =3D xa_err(curr) ? : -EBUSY; - goto err_clear; - } =20 - return 0; - -err_clear: - ida_free(&iommu->domain_ida, info->did); -err_unlock: - kfree(info); - return ret; + return xa_err(xa_store(&domain->iommu_array, iommu->seq_id, + no_free_ptr(info), GFP_KERNEL)); } =20 void domain_detach_iommu(struct dmar_domain *domain, struct intel_iommu *i= ommu) --=20 2.43.0