From: Hans Wippel Date: Wed, 23 May 2018 14:38:10 +0000 (+0200) Subject: net/smc: lock smc_lgr_list in port_terminate() X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=b9f227c37071d1115cec791b328b684e2c4ba414;p=openwrt%2Fstaging%2Fblogic.git net/smc: lock smc_lgr_list in port_terminate() Currently, smc_port_terminate() is not holding the lock of the lgr list while it is traversing the list. This patch adds locking to this function and changes smc_lgr_terminate() accordingly. Signed-off-by: Hans Wippel Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 1e5c0e90a706..21c244f53b0a 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -346,7 +346,7 @@ void smc_lgr_forget(struct smc_link_group *lgr) } /* terminate linkgroup abnormally */ -void smc_lgr_terminate(struct smc_link_group *lgr) +static void __smc_lgr_terminate(struct smc_link_group *lgr) { struct smc_connection *conn; struct smc_sock *smc; @@ -355,7 +355,8 @@ void smc_lgr_terminate(struct smc_link_group *lgr) if (lgr->terminating) return; /* lgr already terminating */ lgr->terminating = 1; - smc_lgr_forget(lgr); + if (!list_empty(&lgr->list)) /* forget lgr */ + list_del_init(&lgr->list); smc_llc_link_inactive(&lgr->lnk[SMC_SINGLE_LINK]); write_lock_bh(&lgr->conns_lock); @@ -377,16 +378,25 @@ void smc_lgr_terminate(struct smc_link_group *lgr) smc_lgr_schedule_free_work(lgr); } +void smc_lgr_terminate(struct smc_link_group *lgr) +{ + spin_lock_bh(&smc_lgr_list.lock); + __smc_lgr_terminate(lgr); + spin_unlock_bh(&smc_lgr_list.lock); +} + /* Called when IB port is terminated */ void smc_port_terminate(struct smc_ib_device *smcibdev, u8 ibport) { struct smc_link_group *lgr, *l; + spin_lock_bh(&smc_lgr_list.lock); list_for_each_entry_safe(lgr, l, &smc_lgr_list.list, list) { if (lgr->lnk[SMC_SINGLE_LINK].smcibdev == smcibdev && lgr->lnk[SMC_SINGLE_LINK].ibport == ibport) - smc_lgr_terminate(lgr); + __smc_lgr_terminate(lgr); } + spin_unlock_bh(&smc_lgr_list.lock); } /* Determine vlan of internal TCP socket.