diff options
author | Yinghai Lu <yinghai@kernel.org> | 2012-09-17 22:23:26 -0700 |
---|---|---|
committer | Yinghai Lu <yinghai@kernel.org> | 2012-09-17 22:23:26 -0700 |
commit | 3cceccbfa740ef139985df7202ea8744761d0db2 (patch) | |
tree | 65574906d2bc76964e7b890428b219481cb12026 | |
parent | 9d963732429ccc690a210b1005710dfeb54c96b5 (diff) | |
download | linux-yinghai-3cceccbfa740ef139985df7202ea8744761d0db2.tar.gz |
IOMMU: iommu_unique_seq_id()
So for hot-remove/hot-add will reuse seq_id.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
-rw-r--r-- | drivers/iommu/dmar.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index cb50b36be6c4f7..1053b547a23ffe 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -769,11 +769,22 @@ out: return err; } +static DECLARE_BITMAP(iommu_allocated, 1024); + +static int iommu_unique_seq_id(void) +{ + int id; + + id = find_first_zero_bit(iommu_allocated, 1024); + __set_bit(id, iommu_allocated); + + return id; +} + int alloc_iommu(struct dmar_drhd_unit *drhd) { struct intel_iommu *iommu; u32 ver; - static int iommu_allocated = 0; int agaw = 0; int msagaw = 0; int err; @@ -787,7 +798,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) if (!iommu) return -ENOMEM; - iommu->seq_id = iommu_allocated++; + iommu->seq_id = iommu_unique_seq_id(); sprintf (iommu->name, "dmar%d", iommu->seq_id); err = map_iommu(iommu, drhd->reg_base_addr); @@ -830,6 +841,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) err_unmap: unmap_iommu(iommu); error: + __clear_bit(iommu->seq_id, iommu_allocated); kfree(iommu); return err; } @@ -844,6 +856,8 @@ void free_iommu(struct intel_iommu *iommu) if (iommu->reg) unmap_iommu(iommu); + __clear_bit(iommu->seq_id, iommu_allocated); + kfree(iommu); } |