From 2a4c57a9e731fa7bd20b028ca078a0ab0ec2485e Mon Sep 17 00:00:00 2001 From: Karsten Graul Date: Tue, 15 May 2018 17:04:59 +0200 Subject: net/smc: use a workqueue to defer llc send SMC handles deferred work in tasklets. As tasklets cannot sleep this can result in rare EBUSY conditions, so defer this work in a work queue. The high level api functions do not defer work because they can sleep until the llc send is actually completed. Signed-off-by: Karsten Graul Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- net/smc/smc_core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'net/smc/smc_core.c') diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index ba7dae819ac8..4523bbad8a15 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -194,10 +194,12 @@ static int smc_lgr_create(struct smc_sock *smc, smc_ib_setup_per_ibdev(smcibdev); get_random_bytes(rndvec, sizeof(rndvec)); lnk->psn_initial = rndvec[0] + (rndvec[1] << 8) + (rndvec[2] << 16); - smc_llc_link_init(lnk); - rc = smc_wr_alloc_link_mem(lnk); + rc = smc_llc_link_init(lnk); if (rc) goto free_lgr; + rc = smc_wr_alloc_link_mem(lnk); + if (rc) + goto clear_llc_lnk; rc = smc_ib_create_protection_domain(lnk); if (rc) goto free_link_mem; @@ -221,6 +223,8 @@ dealloc_pd: smc_ib_dealloc_protection_domain(lnk); free_link_mem: smc_wr_free_link_mem(lnk); +clear_llc_lnk: + smc_llc_link_clear(lnk); free_lgr: kfree(lgr); out: @@ -266,6 +270,7 @@ void smc_conn_free(struct smc_connection *conn) static void smc_link_clear(struct smc_link *lnk) { lnk->peer_qpn = 0; + smc_llc_link_clear(lnk); smc_ib_modify_qp_reset(lnk); smc_wr_free_link(lnk); smc_ib_destroy_queue_pair(lnk); @@ -323,7 +328,6 @@ static void smc_lgr_free_bufs(struct smc_link_group *lgr) /* remove a link group */ void smc_lgr_free(struct smc_link_group *lgr) { - smc_llc_link_flush(&lgr->lnk[SMC_SINGLE_LINK]); smc_lgr_free_bufs(lgr); smc_link_clear(&lgr->lnk[SMC_SINGLE_LINK]); kfree(lgr); -- cgit v1.2.3