aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/hisilicon/zip/zip_main.c
diff options
context:
space:
mode:
authorZhou Wang <wangzhou1@hisilicon.com>2019-10-26 11:00:16 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2019-11-01 13:42:47 +0800
commit700f7d0d29c795c36517dcd3541e4432a76c2efc (patch)
treefd10d926f7904cf8446f7d2b0a5209ff49ae58dd /drivers/crypto/hisilicon/zip/zip_main.c
parentcrypto: hisilicon - use sgl API to get sgl dma addr and len (diff)
downloadlinux-dev-700f7d0d29c795c36517dcd3541e4432a76c2efc.tar.xz
linux-dev-700f7d0d29c795c36517dcd3541e4432a76c2efc.zip
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>
Diffstat (limited to '')
-rw-r--r--drivers/crypto/hisilicon/zip/zip_main.c74
1 files changed, 54 insertions, 20 deletions
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index 9f45bb5fc285..255b63cfbe1d 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -79,7 +79,6 @@
#define HZIP_SOFT_CTRL_CNT_CLR_CE 0x301000
#define SOFT_CTRL_CNT_CLR_CE_BIT BIT(0)
-#define HZIP_NUMA_DISTANCE 100
#define HZIP_BUF_SIZE 22
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 DEFINE_MUTEX(hisi_zip_list_lock);
-#ifdef CONFIG_NUMA
-static struct hisi_zip *find_zip_device_numa(int node)
+struct hisi_zip_resource {
+ 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;
+
+ 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 *ret = NULL;
+#ifdef CONFIG_NUMA
+ struct hisi_zip_resource *res, *tmp;
struct hisi_zip *hisi_zip;
- int min_distance = HZIP_NUMA_DISTANCE;
+ struct list_head *n;
struct device *dev;
+ LIST_HEAD(head);
+
+ mutex_lock(&hisi_zip_list_lock);
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;
- if (node_distance(dev->numa_node, node) < min_distance) {
- zip = hisi_zip;
- min_distance = node_distance(dev->numa_node, node);
+ 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);
}
- return zip;
-}
-#endif
-
-struct hisi_zip *find_zip_device(int node)
-{
- struct hisi_zip *zip = NULL;
+ list_for_each_entry(tmp, &head, list) {
+ if (hisi_qm_get_free_qp_num(&tmp->hzip->qm)) {
+ ret = tmp->hzip;
+ break;
+ }
+ }
- mutex_lock(&hisi_zip_list_lock);
-#ifdef CONFIG_NUMA
- zip = find_zip_device_numa(node);
+ free_list(&head);
#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
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 {