net/smc: introduce link group termination worker
Use a worker for link group termination to guarantee process context. Signed-off-by: Ursula Braun <ubraun@linux.ibm.com> Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
This commit is contained in:
parent
2a0674fffb
commit
f528ba24a8
|
@ -219,6 +219,14 @@ static void smc_lgr_free_work(struct work_struct *work)
|
||||||
smc_lgr_free(lgr);
|
smc_lgr_free(lgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void smc_lgr_terminate_work(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct smc_link_group *lgr = container_of(work, struct smc_link_group,
|
||||||
|
terminate_work);
|
||||||
|
|
||||||
|
smc_lgr_terminate(lgr);
|
||||||
|
}
|
||||||
|
|
||||||
/* create a new SMC link group */
|
/* create a new SMC link group */
|
||||||
static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
|
static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
|
||||||
{
|
{
|
||||||
|
@ -258,6 +266,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
|
||||||
smc_lgr_list.num += SMC_LGR_NUM_INCR;
|
smc_lgr_list.num += SMC_LGR_NUM_INCR;
|
||||||
memcpy(&lgr->id, (u8 *)&smc_lgr_list.num, SMC_LGR_ID_SIZE);
|
memcpy(&lgr->id, (u8 *)&smc_lgr_list.num, SMC_LGR_ID_SIZE);
|
||||||
INIT_DELAYED_WORK(&lgr->free_work, smc_lgr_free_work);
|
INIT_DELAYED_WORK(&lgr->free_work, smc_lgr_free_work);
|
||||||
|
INIT_WORK(&lgr->terminate_work, smc_lgr_terminate_work);
|
||||||
lgr->conns_all = RB_ROOT;
|
lgr->conns_all = RB_ROOT;
|
||||||
if (ini->is_smcd) {
|
if (ini->is_smcd) {
|
||||||
/* SMC-D specific settings */
|
/* SMC-D specific settings */
|
||||||
|
|
|
@ -202,6 +202,7 @@ struct smc_link_group {
|
||||||
|
|
||||||
u8 id[SMC_LGR_ID_SIZE]; /* unique lgr id */
|
u8 id[SMC_LGR_ID_SIZE]; /* unique lgr id */
|
||||||
struct delayed_work free_work; /* delayed freeing of an lgr */
|
struct delayed_work free_work; /* delayed freeing of an lgr */
|
||||||
|
struct work_struct terminate_work; /* abnormal lgr termination */
|
||||||
u8 sync_err : 1; /* lgr no longer fits to peer */
|
u8 sync_err : 1; /* lgr no longer fits to peer */
|
||||||
u8 terminating : 1;/* lgr is terminating */
|
u8 terminating : 1;/* lgr is terminating */
|
||||||
u8 freefast : 1; /* free worker scheduled fast */
|
u8 freefast : 1; /* free worker scheduled fast */
|
||||||
|
@ -282,6 +283,12 @@ static inline struct smc_connection *smc_lgr_find_conn(
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void smc_lgr_terminate_sched(struct smc_link_group *lgr)
|
||||||
|
{
|
||||||
|
if (!lgr->terminating)
|
||||||
|
schedule_work(&lgr->terminate_work);
|
||||||
|
}
|
||||||
|
|
||||||
struct smc_sock;
|
struct smc_sock;
|
||||||
struct smc_clc_msg_accept_confirm;
|
struct smc_clc_msg_accept_confirm;
|
||||||
struct smc_clc_msg_local;
|
struct smc_clc_msg_local;
|
||||||
|
|
|
@ -475,7 +475,7 @@ static void smc_llc_rx_delete_link(struct smc_link *link,
|
||||||
smc_llc_prep_delete_link(llc, link, SMC_LLC_RESP, true);
|
smc_llc_prep_delete_link(llc, link, SMC_LLC_RESP, true);
|
||||||
}
|
}
|
||||||
smc_llc_send_message(link, llc, sizeof(*llc));
|
smc_llc_send_message(link, llc, sizeof(*llc));
|
||||||
smc_lgr_schedule_free_work_fast(lgr);
|
smc_lgr_terminate_sched(lgr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ static inline void smc_wr_tx_process_cqe(struct ib_wc *wc)
|
||||||
clear_bit(i, link->wr_tx_mask);
|
clear_bit(i, link->wr_tx_mask);
|
||||||
}
|
}
|
||||||
/* terminate connections of this link group abnormally */
|
/* terminate connections of this link group abnormally */
|
||||||
smc_lgr_terminate(smc_get_lgr(link));
|
smc_lgr_terminate_sched(smc_get_lgr(link));
|
||||||
}
|
}
|
||||||
if (pnd_snd.handler)
|
if (pnd_snd.handler)
|
||||||
pnd_snd.handler(&pnd_snd.priv, link, wc->status);
|
pnd_snd.handler(&pnd_snd.priv, link, wc->status);
|
||||||
|
@ -191,7 +191,7 @@ int smc_wr_tx_get_free_slot(struct smc_link *link,
|
||||||
SMC_WR_TX_WAIT_FREE_SLOT_TIME);
|
SMC_WR_TX_WAIT_FREE_SLOT_TIME);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
/* timeout - terminate connections */
|
/* timeout - terminate connections */
|
||||||
smc_lgr_terminate(smc_get_lgr(link));
|
smc_lgr_terminate_sched(smc_get_lgr(link));
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
}
|
}
|
||||||
if (idx == link->wr_tx_cnt)
|
if (idx == link->wr_tx_cnt)
|
||||||
|
@ -247,7 +247,7 @@ int smc_wr_tx_send(struct smc_link *link, struct smc_wr_tx_pend_priv *priv)
|
||||||
rc = ib_post_send(link->roce_qp, &link->wr_tx_ibs[pend->idx], NULL);
|
rc = ib_post_send(link->roce_qp, &link->wr_tx_ibs[pend->idx], NULL);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
smc_wr_tx_put_slot(link, priv);
|
smc_wr_tx_put_slot(link, priv);
|
||||||
smc_lgr_terminate(smc_get_lgr(link));
|
smc_lgr_terminate_sched(smc_get_lgr(link));
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,7 @@ int smc_wr_reg_send(struct smc_link *link, struct ib_mr *mr)
|
||||||
SMC_WR_REG_MR_WAIT_TIME);
|
SMC_WR_REG_MR_WAIT_TIME);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
/* timeout - terminate connections */
|
/* timeout - terminate connections */
|
||||||
smc_lgr_terminate(smc_get_lgr(link));
|
smc_lgr_terminate_sched(smc_get_lgr(link));
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
}
|
}
|
||||||
if (rc == -ERESTARTSYS)
|
if (rc == -ERESTARTSYS)
|
||||||
|
@ -373,7 +373,7 @@ static inline void smc_wr_rx_process_cqes(struct ib_wc wc[], int num)
|
||||||
/* terminate connections of this link group
|
/* terminate connections of this link group
|
||||||
* abnormally
|
* abnormally
|
||||||
*/
|
*/
|
||||||
smc_lgr_terminate(smc_get_lgr(link));
|
smc_lgr_terminate_sched(smc_get_lgr(link));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
smc_wr_rx_post(link); /* refill WR RX */
|
smc_wr_rx_post(link); /* refill WR RX */
|
||||||
|
|
Loading…
Reference in New Issue