RDMA/hns: Use refcount_t APIs for HEM
[ Upstream commit 82eb481da64586ccd287b2b2c5a086202c65e7eb ] refcount_t is better than integer for reference counting, it will WARN on overflow/underflow and avoid use-after-free risks. Link: https://lore.kernel.org/r/1621589395-2435-5-git-send-email-liweihang@huawei.com Signed-off-by: Weihang Li <liweihang@huawei.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Stable-dep-of: cf5b608fb0e3 ("RDMA/hns: Fix hns_roce_table_get return value") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
de1049dd18
commit
aa495b927f
@ -260,7 +260,6 @@ static struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev *hr_dev,
|
|||||||
if (!hem)
|
if (!hem)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
hem->refcount = 0;
|
|
||||||
INIT_LIST_HEAD(&hem->chunk_list);
|
INIT_LIST_HEAD(&hem->chunk_list);
|
||||||
|
|
||||||
order = get_order(hem_alloc_size);
|
order = get_order(hem_alloc_size);
|
||||||
@ -607,7 +606,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
|
|||||||
|
|
||||||
mutex_lock(&table->mutex);
|
mutex_lock(&table->mutex);
|
||||||
if (table->hem[index.buf]) {
|
if (table->hem[index.buf]) {
|
||||||
++table->hem[index.buf]->refcount;
|
refcount_inc(&table->hem[index.buf]->refcount);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,7 +625,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++table->hem[index.buf]->refcount;
|
refcount_set(&table->hem[index.buf]->refcount, 1);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
err_alloc:
|
err_alloc:
|
||||||
@ -652,7 +651,7 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev,
|
|||||||
mutex_lock(&table->mutex);
|
mutex_lock(&table->mutex);
|
||||||
|
|
||||||
if (table->hem[i]) {
|
if (table->hem[i]) {
|
||||||
++table->hem[i]->refcount;
|
refcount_inc(&table->hem[i]->refcount);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,7 +674,7 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
++table->hem[i]->refcount;
|
refcount_set(&table->hem[i]->refcount, 1);
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&table->mutex);
|
mutex_unlock(&table->mutex);
|
||||||
return ret;
|
return ret;
|
||||||
@ -742,11 +741,11 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&table->mutex);
|
if (!check_refcount)
|
||||||
if (check_refcount && (--table->hem[index.buf]->refcount > 0)) {
|
mutex_lock(&table->mutex);
|
||||||
mutex_unlock(&table->mutex);
|
else if (!refcount_dec_and_mutex_lock(&table->hem[index.buf]->refcount,
|
||||||
|
&table->mutex))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
clear_mhop_hem(hr_dev, table, obj, &mhop, &index);
|
clear_mhop_hem(hr_dev, table, obj, &mhop, &index);
|
||||||
free_mhop_hem(hr_dev, table, &mhop, &index);
|
free_mhop_hem(hr_dev, table, &mhop, &index);
|
||||||
@ -768,16 +767,15 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev,
|
|||||||
i = (obj & (table->num_obj - 1)) /
|
i = (obj & (table->num_obj - 1)) /
|
||||||
(table->table_chunk_size / table->obj_size);
|
(table->table_chunk_size / table->obj_size);
|
||||||
|
|
||||||
mutex_lock(&table->mutex);
|
if (!refcount_dec_and_mutex_lock(&table->hem[i]->refcount,
|
||||||
|
&table->mutex))
|
||||||
|
return;
|
||||||
|
|
||||||
if (--table->hem[i]->refcount == 0) {
|
if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
|
||||||
/* Clear HEM base address */
|
dev_warn(dev, "failed to clear HEM base address.\n");
|
||||||
if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
|
|
||||||
dev_warn(dev, "Clear HEM base address failed.\n");
|
|
||||||
|
|
||||||
hns_roce_free_hem(hr_dev, table->hem[i]);
|
hns_roce_free_hem(hr_dev, table->hem[i]);
|
||||||
table->hem[i] = NULL;
|
table->hem[i] = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&table->mutex);
|
mutex_unlock(&table->mutex);
|
||||||
}
|
}
|
||||||
|
@ -87,8 +87,8 @@ struct hns_roce_hem_chunk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct hns_roce_hem {
|
struct hns_roce_hem {
|
||||||
struct list_head chunk_list;
|
struct list_head chunk_list;
|
||||||
int refcount;
|
refcount_t refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hns_roce_hem_iter {
|
struct hns_roce_hem_iter {
|
||||||
|
Loading…
Reference in New Issue
Block a user