}
        set_bit(qp_id, qm->qp_bitmap);
        qm->qp_array[qp_id] = qp;
+       qm->qp_in_used++;
 
        write_unlock(&qm->qps_lock);
 
        write_lock(&qm->qps_lock);
        qm->qp_array[qp->qp_id] = NULL;
        clear_bit(qp->qp_id, qm->qp_bitmap);
+       qm->qp_in_used--;
        write_unlock(&qm->qps_lock);
 
        kfree(qp);
        }
 }
 
+/**
+ * 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.
  * @qm: The qm needing init.
        if (ret)
                goto err_free_irq_vectors;
 
+       qm->qp_in_used = 0;
        mutex_init(&qm->mailbox_lock);
        rwlock_init(&qm->qps_lock);
 
 
        u32 sqe_size;
        u32 qp_base;
        u32 qp_num;
+       u32 qp_in_used;
        u32 ctrl_qp_num;
 
        struct qm_dma qdma;
 int hisi_qm_stop_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_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_set_vft(struct hisi_qm *qm, u32 fun_num, u32 base, u32 number);
 int hisi_qm_debug_init(struct hisi_qm *qm);
 
 #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";
 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 {