Skip to content

Commit a52bcc9

Browse files
karstengrdavem330
authored andcommitted
net/smc: improve termination processing
Add helper smcr_lgr_link_deactivate_all() and eliminate duplicate code. In smc_lgr_free(), clear the smc-r links before smc_lgr_free_bufs() is called so buffers are already prepared for free. The usage of the soft parameter in __smc_lgr_terminate() is no longer needed, smc_lgr_free() can be called directly. smc_lgr_terminate_sched() and smc_smcd_terminate() set lgr->freeing to indicate that the link group will be freed soon to avoid unnecessary schedules of the free worker. Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Reviewed-by: Ursula Braun <ubraun@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 3e0c40a commit a52bcc9

File tree

1 file changed

+31
-30
lines changed

1 file changed

+31
-30
lines changed

net/smc/smc_core.c

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,19 @@ void smc_lgr_cleanup_early(struct smc_connection *conn)
237237
smc_lgr_schedule_free_work_fast(lgr);
238238
}
239239

240+
static void smcr_lgr_link_deactivate_all(struct smc_link_group *lgr)
241+
{
242+
int i;
243+
244+
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
245+
struct smc_link *lnk = &lgr->lnk[i];
246+
247+
if (smc_link_usable(lnk))
248+
lnk->state = SMC_LNK_INACTIVE;
249+
}
250+
wake_up_interruptible_all(&lgr->llc_waiter);
251+
}
252+
240253
static void smc_lgr_free(struct smc_link_group *lgr);
241254

242255
static void smc_lgr_free_work(struct work_struct *work)
@@ -246,7 +259,6 @@ static void smc_lgr_free_work(struct work_struct *work)
246259
free_work);
247260
spinlock_t *lgr_lock;
248261
bool conns;
249-
int i;
250262

251263
smc_lgr_list_head(lgr, &lgr_lock);
252264
spin_lock_bh(lgr_lock);
@@ -271,15 +283,8 @@ static void smc_lgr_free_work(struct work_struct *work)
271283
SMC_LLC_DEL_PROG_INIT_TERM);
272284
if (lgr->is_smcd && !lgr->terminating)
273285
smc_ism_signal_shutdown(lgr);
274-
if (!lgr->is_smcd) {
275-
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
276-
struct smc_link *lnk = &lgr->lnk[i];
277-
278-
if (smc_link_usable(lnk))
279-
lnk->state = SMC_LNK_INACTIVE;
280-
}
281-
wake_up_interruptible_all(&lgr->llc_waiter);
282-
}
286+
if (!lgr->is_smcd)
287+
smcr_lgr_link_deactivate_all(lgr);
283288
smc_lgr_free(lgr);
284289
}
285290

@@ -802,6 +807,16 @@ static void smc_lgr_free(struct smc_link_group *lgr)
802807
{
803808
int i;
804809

810+
if (!lgr->is_smcd) {
811+
mutex_lock(&lgr->llc_conf_mutex);
812+
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
813+
if (lgr->lnk[i].state != SMC_LNK_UNUSED)
814+
smcr_link_clear(&lgr->lnk[i]);
815+
}
816+
mutex_unlock(&lgr->llc_conf_mutex);
817+
smc_llc_lgr_clear(lgr);
818+
}
819+
805820
smc_lgr_free_bufs(lgr);
806821
if (lgr->is_smcd) {
807822
if (!lgr->terminating) {
@@ -811,11 +826,6 @@ static void smc_lgr_free(struct smc_link_group *lgr)
811826
if (!atomic_dec_return(&lgr->smcd->lgr_cnt))
812827
wake_up(&lgr->smcd->lgrs_deleted);
813828
} else {
814-
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
815-
if (lgr->lnk[i].state != SMC_LNK_UNUSED)
816-
smcr_link_clear(&lgr->lnk[i]);
817-
}
818-
smc_llc_lgr_clear(lgr);
819829
if (!atomic_dec_return(&lgr_cnt))
820830
wake_up(&lgrs_deleted);
821831
}
@@ -870,8 +880,6 @@ static void smc_conn_kill(struct smc_connection *conn, bool soft)
870880

871881
static void smc_lgr_cleanup(struct smc_link_group *lgr)
872882
{
873-
int i;
874-
875883
if (lgr->is_smcd) {
876884
smc_ism_signal_shutdown(lgr);
877885
smcd_unregister_all_dmbs(lgr);
@@ -883,13 +891,7 @@ static void smc_lgr_cleanup(struct smc_link_group *lgr)
883891
if (!rsn)
884892
rsn = SMC_LLC_DEL_PROG_INIT_TERM;
885893
smc_llc_send_link_delete_all(lgr, false, rsn);
886-
for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) {
887-
struct smc_link *lnk = &lgr->lnk[i];
888-
889-
if (smc_link_usable(lnk))
890-
lnk->state = SMC_LNK_INACTIVE;
891-
}
892-
wake_up_interruptible_all(&lgr->llc_waiter);
894+
smcr_lgr_link_deactivate_all(lgr);
893895
}
894896
}
895897

@@ -905,8 +907,8 @@ static void __smc_lgr_terminate(struct smc_link_group *lgr, bool soft)
905907

906908
if (lgr->terminating)
907909
return; /* lgr already terminating */
908-
if (!soft)
909-
cancel_delayed_work_sync(&lgr->free_work);
910+
/* cancel free_work sync, will terminate when lgr->freeing is set */
911+
cancel_delayed_work_sync(&lgr->free_work);
910912
lgr->terminating = 1;
911913

912914
/* kill remaining link group connections */
@@ -926,10 +928,7 @@ static void __smc_lgr_terminate(struct smc_link_group *lgr, bool soft)
926928
}
927929
read_unlock_bh(&lgr->conns_lock);
928930
smc_lgr_cleanup(lgr);
929-
if (soft)
930-
smc_lgr_schedule_free_work_fast(lgr);
931-
else
932-
smc_lgr_free(lgr);
931+
smc_lgr_free(lgr);
933932
}
934933

935934
/* unlink link group and schedule termination */
@@ -944,6 +943,7 @@ void smc_lgr_terminate_sched(struct smc_link_group *lgr)
944943
return; /* lgr already terminating */
945944
}
946945
list_del_init(&lgr->list);
946+
lgr->freeing = 1;
947947
spin_unlock_bh(lgr_lock);
948948
schedule_work(&lgr->terminate_work);
949949
}
@@ -962,6 +962,7 @@ void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, unsigned short vlan)
962962
if (peer_gid) /* peer triggered termination */
963963
lgr->peer_shutdown = 1;
964964
list_move(&lgr->list, &lgr_free_list);
965+
lgr->freeing = 1;
965966
}
966967
}
967968
spin_unlock_bh(&dev->lgr_lock);

0 commit comments

Comments
 (0)