Commit 700f7d0d authored by Zhou Wang's avatar Zhou Wang Committed by Herbert Xu

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: default avatarZhou Wang <wangzhou1@hisilicon.com>
Signed-off-by: default avatarShukun Tan <tanshukun1@huawei.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent f0c8b6a1
...@@ -1127,6 +1127,7 @@ struct hisi_qp *hisi_qm_create_qp(struct hisi_qm *qm, u8 alg_type) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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); ...@@ -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 @@ ...@@ -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; ...@@ -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_resource *res, *tmp;
list_for_each_entry_safe(res, tmp, head, list) {
list_del(&res->list);
kfree(res);
}
}
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 hisi_zip *hisi_zip;
int min_distance = HZIP_NUMA_DISTANCE; struct list_head *n;
struct device *dev; struct device *dev;
LIST_HEAD(head);
mutex_lock(&hisi_zip_list_lock);
list_for_each_entry(hisi_zip, &hisi_zip_list, list) { 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; dev = &hisi_zip->qm.pdev->dev;
if (node_distance(dev->numa_node, node) < min_distance) { res->hzip = hisi_zip;
zip = hisi_zip; res->distance = node_distance(dev->numa_node, node);
min_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);
}
return zip; list_for_each_entry(tmp, &head, list) {
} if (hisi_qm_get_free_qp_num(&tmp->hzip->qm)) {
#endif ret = tmp->hzip;
break;
struct hisi_zip *find_zip_device(int node) }
{ }
struct hisi_zip *zip = NULL;
mutex_lock(&hisi_zip_list_lock); free_list(&head);
#ifdef CONFIG_NUMA
zip = find_zip_device_numa(node);
#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 {
......
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