iommu/arm-smmu-v3: Use the new rb tree helpers
[ Upstream commit a2bb820e862d61f9ca1499e500915f9f505a2655 ] Since v5.12 the rbtree has gained some simplifying helpers aimed at making rb tree users write less convoluted boiler plate code. Instead the caller provides a single comparison function and the helpers generate the prior open-coded stuff. Update smmu->streams to use rb_find_add() and rb_find(). Tested-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Mostafa Saleh <smostafa@google.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/1-v3-9fef8cdc2ff6+150d1-smmuv3_tidy_jgg@nvidia.com Signed-off-by: Will Deacon <will@kernel.org> Stable-dep-of: b00d24997a11 ("iommu/arm-smmu-v3: Fix iommu_device_probe bug due to duplicated stream ids") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
8f2451ebaf
commit
3dc33f145a
@@ -1443,26 +1443,37 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arm_smmu_streams_cmp_key(const void *lhs, const struct rb_node *rhs)
|
||||
{
|
||||
struct arm_smmu_stream *stream_rhs =
|
||||
rb_entry(rhs, struct arm_smmu_stream, node);
|
||||
const u32 *sid_lhs = lhs;
|
||||
|
||||
if (*sid_lhs < stream_rhs->id)
|
||||
return -1;
|
||||
if (*sid_lhs > stream_rhs->id)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arm_smmu_streams_cmp_node(struct rb_node *lhs,
|
||||
const struct rb_node *rhs)
|
||||
{
|
||||
return arm_smmu_streams_cmp_key(
|
||||
&rb_entry(lhs, struct arm_smmu_stream, node)->id, rhs);
|
||||
}
|
||||
|
||||
static struct arm_smmu_master *
|
||||
arm_smmu_find_master(struct arm_smmu_device *smmu, u32 sid)
|
||||
{
|
||||
struct rb_node *node;
|
||||
struct arm_smmu_stream *stream;
|
||||
|
||||
lockdep_assert_held(&smmu->streams_mutex);
|
||||
|
||||
node = smmu->streams.rb_node;
|
||||
while (node) {
|
||||
stream = rb_entry(node, struct arm_smmu_stream, node);
|
||||
if (stream->id < sid)
|
||||
node = node->rb_right;
|
||||
else if (stream->id > sid)
|
||||
node = node->rb_left;
|
||||
else
|
||||
return stream->master;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
node = rb_find(&sid, &smmu->streams, arm_smmu_streams_cmp_key);
|
||||
if (!node)
|
||||
return NULL;
|
||||
return rb_entry(node, struct arm_smmu_stream, node)->master;
|
||||
}
|
||||
|
||||
/* IRQ and event handlers */
|
||||
@@ -2575,8 +2586,6 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
struct arm_smmu_stream *new_stream, *cur_stream;
|
||||
struct rb_node **new_node, *parent_node = NULL;
|
||||
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
|
||||
|
||||
master->streams = kcalloc(fwspec->num_ids, sizeof(*master->streams),
|
||||
@@ -2587,9 +2596,9 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
|
||||
|
||||
mutex_lock(&smmu->streams_mutex);
|
||||
for (i = 0; i < fwspec->num_ids; i++) {
|
||||
struct arm_smmu_stream *new_stream = &master->streams[i];
|
||||
u32 sid = fwspec->ids[i];
|
||||
|
||||
new_stream = &master->streams[i];
|
||||
new_stream->id = sid;
|
||||
new_stream->master = master;
|
||||
|
||||
@@ -2598,28 +2607,13 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
|
||||
break;
|
||||
|
||||
/* Insert into SID tree */
|
||||
new_node = &(smmu->streams.rb_node);
|
||||
while (*new_node) {
|
||||
cur_stream = rb_entry(*new_node, struct arm_smmu_stream,
|
||||
node);
|
||||
parent_node = *new_node;
|
||||
if (cur_stream->id > new_stream->id) {
|
||||
new_node = &((*new_node)->rb_left);
|
||||
} else if (cur_stream->id < new_stream->id) {
|
||||
new_node = &((*new_node)->rb_right);
|
||||
} else {
|
||||
dev_warn(master->dev,
|
||||
"stream %u already in tree\n",
|
||||
cur_stream->id);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
if (rb_find_add(&new_stream->node, &smmu->streams,
|
||||
arm_smmu_streams_cmp_node)) {
|
||||
dev_warn(master->dev, "stream %u already in tree\n",
|
||||
sid);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
|
||||
rb_link_node(&new_stream->node, parent_node, new_node);
|
||||
rb_insert_color(&new_stream->node, &smmu->streams);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
|
Reference in New Issue
Block a user