Commit 82eb481d authored by Weihang Li's avatar Weihang Li Committed by Jason Gunthorpe

RDMA/hns: Use refcount_t APIs for HEM

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.comSigned-off-by: default avatarWeihang Li <liweihang@huawei.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 5e6370d7
...@@ -271,7 +271,6 @@ static struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev *hr_dev, ...@@ -271,7 +271,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);
...@@ -618,7 +617,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev, ...@@ -618,7 +617,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;
} }
...@@ -637,7 +636,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev, ...@@ -637,7 +636,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:
...@@ -663,7 +662,7 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev, ...@@ -663,7 +662,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;
} }
...@@ -686,7 +685,7 @@ int hns_roce_table_get(struct hns_roce_dev *hr_dev, ...@@ -686,7 +685,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;
...@@ -753,11 +752,11 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev, ...@@ -753,11 +752,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);
...@@ -779,16 +778,15 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev, ...@@ -779,16 +778,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);
} }
......
...@@ -88,8 +88,8 @@ struct hns_roce_hem_chunk { ...@@ -88,8 +88,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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment