aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2012-09-17 22:23:26 -0700
committerYinghai Lu <yinghai@kernel.org>2012-09-17 22:23:26 -0700
commit3cceccbfa740ef139985df7202ea8744761d0db2 (patch)
tree65574906d2bc76964e7b890428b219481cb12026
parent9d963732429ccc690a210b1005710dfeb54c96b5 (diff)
downloadlinux-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.c18
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);
}