Skip to content

Commit 1672730

Browse files
Dawei Liwilldeacon
authored andcommitted
iommu/arm-smmu-v3: Change vmid alloc strategy from bitmap to ida
For current implementation of vmid allocation of arm smmu-v3, a per-smmu devide bitmap of 64K bits(8K bytes) is allocated on behalf of possible VMID range, which is two pages for some architectures. Besides that, its memory consumption is 'static', despite of how many VMIDs are allocated actually. That's memory inefficient and lack of scalability. So an IDA based implementation is introduced to address this issue, which is capable of self-expanding on the actual need of VMID allocation. Signed-off-by: Dawei Li <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/TYCP286MB2323E0C525FF9F94E3B07C7ACA35A@TYCP286MB2323.JPNP286.PROD.OUTLOOK.COM Signed-off-by: Will Deacon <[email protected]>
1 parent 6eaae19 commit 1672730

File tree

2 files changed

+8
-23
lines changed

2 files changed

+8
-23
lines changed

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,24 +2055,6 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
20552055
return &smmu_domain->domain;
20562056
}
20572057

2058-
static int arm_smmu_bitmap_alloc(unsigned long *map, int span)
2059-
{
2060-
int idx, size = 1 << span;
2061-
2062-
do {
2063-
idx = find_first_zero_bit(map, size);
2064-
if (idx == size)
2065-
return -ENOSPC;
2066-
} while (test_and_set_bit(idx, map));
2067-
2068-
return idx;
2069-
}
2070-
2071-
static void arm_smmu_bitmap_free(unsigned long *map, int idx)
2072-
{
2073-
clear_bit(idx, map);
2074-
}
2075-
20762058
static void arm_smmu_domain_free(struct iommu_domain *domain)
20772059
{
20782060
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
@@ -2093,7 +2075,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
20932075
} else {
20942076
struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
20952077
if (cfg->vmid)
2096-
arm_smmu_bitmap_free(smmu->vmid_map, cfg->vmid);
2078+
ida_free(&smmu->vmid_map, cfg->vmid);
20972079
}
20982080

20992081
kfree(smmu_domain);
@@ -2167,7 +2149,9 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
21672149
struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
21682150
typeof(&pgtbl_cfg->arm_lpae_s2_cfg.vtcr) vtcr;
21692151

2170-
vmid = arm_smmu_bitmap_alloc(smmu->vmid_map, smmu->vmid_bits);
2152+
/* Reserve VMID 0 for stage-2 bypass STEs */
2153+
vmid = ida_alloc_range(&smmu->vmid_map, 1, (1 << smmu->vmid_bits) - 1,
2154+
GFP_KERNEL);
21712155
if (vmid < 0)
21722156
return vmid;
21732157

@@ -3098,8 +3082,8 @@ static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
30983082
reg |= STRTAB_BASE_RA;
30993083
smmu->strtab_cfg.strtab_base = reg;
31003084

3101-
/* Allocate the first VMID for stage-2 bypass STEs */
3102-
set_bit(0, smmu->vmid_map);
3085+
ida_init(&smmu->vmid_map);
3086+
31033087
return 0;
31043088
}
31053089

@@ -3923,6 +3907,7 @@ static void arm_smmu_device_remove(struct platform_device *pdev)
39233907
iommu_device_sysfs_remove(&smmu->iommu);
39243908
arm_smmu_device_disable(smmu);
39253909
iopf_queue_free(smmu->evtq.iopf);
3910+
ida_destroy(&smmu->vmid_map);
39263911
}
39273912

39283913
static void arm_smmu_device_shutdown(struct platform_device *pdev)

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ struct arm_smmu_device {
670670

671671
#define ARM_SMMU_MAX_VMIDS (1 << 16)
672672
unsigned int vmid_bits;
673-
DECLARE_BITMAP(vmid_map, ARM_SMMU_MAX_VMIDS);
673+
struct ida vmid_map;
674674

675675
unsigned int ssid_bits;
676676
unsigned int sid_bits;

0 commit comments

Comments
 (0)