crypto: hisilicon - fix to return sub-optimal device when best device has no qps
Currently find_zip_device() finds zip device which has the min NUMA distance with current CPU. This patch modifies find_zip_device to return sub-optimal device when best device has no qps. This patch sorts all devices by NUMA distance, then finds the best zip device which has free qp. Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com> Signed-off-by: Shukun Tan <tanshukun1@huawei.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Родитель
f0c8b6a1e1
Коммит
700f7d0d29
|
@ -1127,6 +1127,7 @@ struct hisi_qp *hisi_qm_create_qp(struct hisi_qm *qm, u8 alg_type)
|
||||||
}
|
}
|
||||||
set_bit(qp_id, qm->qp_bitmap);
|
set_bit(qp_id, qm->qp_bitmap);
|
||||||
qm->qp_array[qp_id] = qp;
|
qm->qp_array[qp_id] = qp;
|
||||||
|
qm->qp_in_used++;
|
||||||
|
|
||||||
write_unlock(&qm->qps_lock);
|
write_unlock(&qm->qps_lock);
|
||||||
|
|
||||||
|
@ -1191,6 +1192,7 @@ void hisi_qm_release_qp(struct hisi_qp *qp)
|
||||||
write_lock(&qm->qps_lock);
|
write_lock(&qm->qps_lock);
|
||||||
qm->qp_array[qp->qp_id] = NULL;
|
qm->qp_array[qp->qp_id] = NULL;
|
||||||
clear_bit(qp->qp_id, qm->qp_bitmap);
|
clear_bit(qp->qp_id, qm->qp_bitmap);
|
||||||
|
qm->qp_in_used--;
|
||||||
write_unlock(&qm->qps_lock);
|
write_unlock(&qm->qps_lock);
|
||||||
|
|
||||||
kfree(qp);
|
kfree(qp);
|
||||||
|
@ -1395,6 +1397,24 @@ static void hisi_qm_cache_wb(struct hisi_qm *qm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hisi_qm_get_free_qp_num() - Get free number of qp in qm.
|
||||||
|
* @qm: The qm which want to get free qp.
|
||||||
|
*
|
||||||
|
* This function return free number of qp in qm.
|
||||||
|
*/
|
||||||
|
int hisi_qm_get_free_qp_num(struct hisi_qm *qm)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
read_lock(&qm->qps_lock);
|
||||||
|
ret = qm->qp_num - qm->qp_in_used;
|
||||||
|
read_unlock(&qm->qps_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(hisi_qm_get_free_qp_num);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hisi_qm_init() - Initialize configures about qm.
|
* hisi_qm_init() - Initialize configures about qm.
|
||||||
* @qm: The qm needing init.
|
* @qm: The qm needing init.
|
||||||
|
@ -1458,6 +1478,7 @@ int hisi_qm_init(struct hisi_qm *qm)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_irq_vectors;
|
goto err_free_irq_vectors;
|
||||||
|
|
||||||
|
qm->qp_in_used = 0;
|
||||||
mutex_init(&qm->mailbox_lock);
|
mutex_init(&qm->mailbox_lock);
|
||||||
rwlock_init(&qm->qps_lock);
|
rwlock_init(&qm->qps_lock);
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,7 @@ struct hisi_qm {
|
||||||
u32 sqe_size;
|
u32 sqe_size;
|
||||||
u32 qp_base;
|
u32 qp_base;
|
||||||
u32 qp_num;
|
u32 qp_num;
|
||||||
|
u32 qp_in_used;
|
||||||
u32 ctrl_qp_num;
|
u32 ctrl_qp_num;
|
||||||
|
|
||||||
struct qm_dma qdma;
|
struct qm_dma qdma;
|
||||||
|
@ -206,6 +207,7 @@ int hisi_qm_start_qp(struct hisi_qp *qp, unsigned long arg);
|
||||||
int hisi_qm_stop_qp(struct hisi_qp *qp);
|
int hisi_qm_stop_qp(struct hisi_qp *qp);
|
||||||
void hisi_qm_release_qp(struct hisi_qp *qp);
|
void hisi_qm_release_qp(struct hisi_qp *qp);
|
||||||
int hisi_qp_send(struct hisi_qp *qp, const void *msg);
|
int hisi_qp_send(struct hisi_qp *qp, const void *msg);
|
||||||
|
int hisi_qm_get_free_qp_num(struct hisi_qm *qm);
|
||||||
int hisi_qm_get_vft(struct hisi_qm *qm, u32 *base, u32 *number);
|
int hisi_qm_get_vft(struct hisi_qm *qm, u32 *base, u32 *number);
|
||||||
int hisi_qm_set_vft(struct hisi_qm *qm, u32 fun_num, u32 base, u32 number);
|
int hisi_qm_set_vft(struct hisi_qm *qm, u32 fun_num, u32 base, u32 number);
|
||||||
int hisi_qm_debug_init(struct hisi_qm *qm);
|
int hisi_qm_debug_init(struct hisi_qm *qm);
|
||||||
|
|
|
@ -79,7 +79,6 @@
|
||||||
#define HZIP_SOFT_CTRL_CNT_CLR_CE 0x301000
|
#define HZIP_SOFT_CTRL_CNT_CLR_CE 0x301000
|
||||||
#define SOFT_CTRL_CNT_CLR_CE_BIT BIT(0)
|
#define SOFT_CTRL_CNT_CLR_CE_BIT BIT(0)
|
||||||
|
|
||||||
#define HZIP_NUMA_DISTANCE 100
|
|
||||||
#define HZIP_BUF_SIZE 22
|
#define HZIP_BUF_SIZE 22
|
||||||
|
|
||||||
static const char hisi_zip_name[] = "hisi_zip";
|
static const char hisi_zip_name[] = "hisi_zip";
|
||||||
|
@ -87,39 +86,74 @@ static struct dentry *hzip_debugfs_root;
|
||||||
static LIST_HEAD(hisi_zip_list);
|
static LIST_HEAD(hisi_zip_list);
|
||||||
static DEFINE_MUTEX(hisi_zip_list_lock);
|
static DEFINE_MUTEX(hisi_zip_list_lock);
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
struct hisi_zip_resource {
|
||||||
static struct hisi_zip *find_zip_device_numa(int node)
|
struct hisi_zip *hzip;
|
||||||
|
int distance;
|
||||||
|
struct list_head list;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void free_list(struct list_head *head)
|
||||||
{
|
{
|
||||||
struct hisi_zip *zip = NULL;
|
struct hisi_zip_resource *res, *tmp;
|
||||||
struct hisi_zip *hisi_zip;
|
|
||||||
int min_distance = HZIP_NUMA_DISTANCE;
|
|
||||||
struct device *dev;
|
|
||||||
|
|
||||||
list_for_each_entry(hisi_zip, &hisi_zip_list, list) {
|
list_for_each_entry_safe(res, tmp, head, list) {
|
||||||
dev = &hisi_zip->qm.pdev->dev;
|
list_del(&res->list);
|
||||||
if (node_distance(dev->numa_node, node) < min_distance) {
|
kfree(res);
|
||||||
zip = hisi_zip;
|
|
||||||
min_distance = node_distance(dev->numa_node, node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return zip;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
struct hisi_zip *find_zip_device(int node)
|
struct hisi_zip *find_zip_device(int node)
|
||||||
{
|
{
|
||||||
struct hisi_zip *zip = NULL;
|
struct hisi_zip *ret = NULL;
|
||||||
|
#ifdef CONFIG_NUMA
|
||||||
|
struct hisi_zip_resource *res, *tmp;
|
||||||
|
struct hisi_zip *hisi_zip;
|
||||||
|
struct list_head *n;
|
||||||
|
struct device *dev;
|
||||||
|
LIST_HEAD(head);
|
||||||
|
|
||||||
mutex_lock(&hisi_zip_list_lock);
|
mutex_lock(&hisi_zip_list_lock);
|
||||||
#ifdef CONFIG_NUMA
|
|
||||||
zip = find_zip_device_numa(node);
|
list_for_each_entry(hisi_zip, &hisi_zip_list, list) {
|
||||||
|
res = kzalloc(sizeof(*res), GFP_KERNEL);
|
||||||
|
if (!res)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
dev = &hisi_zip->qm.pdev->dev;
|
||||||
|
res->hzip = hisi_zip;
|
||||||
|
res->distance = node_distance(dev->numa_node, node);
|
||||||
|
|
||||||
|
n = &head;
|
||||||
|
list_for_each_entry(tmp, &head, list) {
|
||||||
|
if (res->distance < tmp->distance) {
|
||||||
|
n = &tmp->list;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list_add_tail(&res->list, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(tmp, &head, list) {
|
||||||
|
if (hisi_qm_get_free_qp_num(&tmp->hzip->qm)) {
|
||||||
|
ret = tmp->hzip;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free_list(&head);
|
||||||
#else
|
#else
|
||||||
zip = list_first_entry(&hisi_zip_list, struct hisi_zip, list);
|
mutex_lock(&hisi_zip_list_lock);
|
||||||
|
|
||||||
|
ret = list_first_entry(&hisi_zip_list, struct hisi_zip, list);
|
||||||
#endif
|
#endif
|
||||||
mutex_unlock(&hisi_zip_list_lock);
|
mutex_unlock(&hisi_zip_list_lock);
|
||||||
|
|
||||||
return zip;
|
return ret;
|
||||||
|
|
||||||
|
err:
|
||||||
|
free_list(&head);
|
||||||
|
mutex_unlock(&hisi_zip_list_lock);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hisi_zip_hw_error {
|
struct hisi_zip_hw_error {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче