Skip to content
/ linux Public
forked from torvalds/linux

Commit

Permalink
iommu/arm-smmu-v3: Use the new rb tree helpers
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Mostafa Saleh <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Will Deacon <[email protected]>
  • Loading branch information
jgunthorpe authored and willdeacon committed Sep 6, 2024
1 parent 483e0bd commit a2bb820
Showing 1 changed file with 31 additions and 37 deletions.
68 changes: 31 additions & 37 deletions drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1735,26 +1735,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 */
Expand Down Expand Up @@ -3210,8 +3221,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),
Expand All @@ -3222,9 +3231,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;

Expand All @@ -3233,28 +3242,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) {
Expand Down

0 comments on commit a2bb820

Please sign in to comment.