From: Wenkai Lin <linwenkai6@hisilicon.com> wd_hw_alloc_ctx picked the first device whose wd_request_ctx() succeeded. When PF and VFs share the same NUMA node, the NUMA-distance sort is a no-op, so the device order comes from readdir() over /sys/class/uacce. Each concurrent business independently starts from the list head and binds all ctxs to the same leading device, starving the others. Select the device with the most available contexts (wd_get_avail_ctx) instead, with a fallback to the remaining devices if the chosen one fails to open. NUMA distance priority is unchanged. Signed-off-by: Wenkai Lin <linwenkai6@hisilicon.com> --- drv/wd_drv.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/drv/wd_drv.c b/drv/wd_drv.c index c839ed4..08014dd 100644 --- a/drv/wd_drv.c +++ b/drv/wd_drv.c @@ -181,12 +181,12 @@ int wd_hw_alloc_ctx(char *alg_name, void *params, handle_t *ctx) { struct wd_drv_ctx_params *ctx_params = (struct wd_drv_ctx_params *)params; struct uacce_dev_list *dev_list, *used_list = NULL; + struct uacce_dev_list *curr, *best = NULL; char alg_type[CRYPTO_MAX_ALG_NAME]; - struct uacce_dev_list *curr; + int target_numa, best_avail = 0; struct wd_ctx_h *ctx_h; - int target_numa; + int ret, avail; handle_t hctx; - int ret; if (!params || !ctx) { WD_ERR("invalid: parameters are NULL!\n"); @@ -246,14 +246,35 @@ int wd_hw_alloc_ctx(char *alg_name, void *params, handle_t *ctx) goto success; } - curr = used_list; - while (curr) { - if (curr->dev) { - hctx = wd_request_ctx(curr->dev); - if (hctx) - goto success; + /* Pick the device with the most available contexts to balance load. */ + for (curr = used_list; curr; curr = curr->next) { + if (!curr->dev) + continue; + avail = wd_get_avail_ctx(curr->dev); + if (avail > best_avail) { + best_avail = avail; + best = curr; } - curr = curr->next; + } + + if (!best) { + WD_ERR("failed to request ctx on NUMA node %d for %s\n", + target_numa, alg_name); + ret = -WD_EBUSY; + goto out; + } + + hctx = wd_request_ctx(best->dev); + if (hctx) + goto success; + + /* Fall back to remaining devices if the best one fails to open */ + for (curr = used_list; curr; curr = curr->next) { + if (curr == best || !curr->dev) + continue; + hctx = wd_request_ctx(curr->dev); + if (hctx) + goto success; } WD_ERR("failed to request ctx on NUMA node %d for %s\n", -- 2.50.1.windows.1