
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC914B CVE: NA -------------------------------- This reverts commit e024ae9843e624298e9cd7a03cbc8f7837944358. Replace it with mainline patch 61f434b0280e ("net/smc: Resolve the race between link group access and termination") later. Fixes: e024ae9843e6 ("anolis: net/smc: Resolve the race between link group access and termination") Conflicts: net/smc/smc_core.c [conflicts due to merged mainline ddc992866f13 ("net/smc: Add link counters for IB device ports")] Signed-off-by: Wang Liang <wangliang74@huawei.com> --- net/smc/smc.h | 1 - net/smc/smc_core.c | 42 ++++-------------------------------------- net/smc/smc_core.h | 3 --- 3 files changed, 4 insertions(+), 42 deletions(-) diff --git a/net/smc/smc.h b/net/smc/smc.h index 7c50514aaa7e..3eafd44e363f 100644 --- a/net/smc/smc.h +++ b/net/smc/smc.h @@ -219,7 +219,6 @@ struct smc_connection { */ u64 peer_token; /* SMC-D token of peer */ u8 killed : 1; /* abnormal termination */ - u8 freed : 1; /* normal termiation */ u8 out_of_sync : 1; /* out of sync with peer */ }; diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index f94d1f452482..710adfedafc3 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -184,7 +184,6 @@ static int smc_lgr_register_conn(struct smc_connection *conn, bool first) conn->alert_token_local = 0; } smc_lgr_add_alert_token(conn); - smc_lgr_hold(conn->lgr); /* lgr_put in smc_conn_free() */ conn->lgr->conns_num++; return 0; } @@ -217,6 +216,7 @@ static void smc_lgr_unregister_conn(struct smc_connection *conn) __smc_lgr_unregister_conn(conn); } write_unlock_bh(&lgr->conns_lock); + conn->lgr = NULL; } int smc_nl_get_sys_info(struct sk_buff *skb, struct netlink_callback *cb) @@ -698,7 +698,6 @@ int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk, atomic_inc(&ini->ib_dev->lnk_cnt); lnk->link_id = smcr_next_link_id(lgr); lnk->lgr = lgr; - smc_lgr_hold(lgr); /* lgr_put in smcr_link_clear() */ lnk->link_idx = link_idx; lnk->wr_rx_id_compl = 0; lnk->smcibdev = ini->ib_dev; @@ -792,7 +791,6 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) lgr->terminating = 0; lgr->freeing = 0; lgr->vlan_id = ini->vlan_id; - refcount_set(&lgr->refcnt, 1); /* set lgr refcnt to 1 */ init_rwsem(&lgr->sndbufs_lock); init_rwsem(&lgr->rmbs_lock); rwlock_init(&lgr->conns_lock); @@ -1070,20 +1068,8 @@ void smc_conn_free(struct smc_connection *conn) { struct smc_link_group *lgr = conn->lgr; - if (!lgr || conn->freed) - /* smc connection wasn't registered to a link group - * or has already been freed before. - * - * Judge these to ensure that lgr refcnt will be put - * only once if connection has been registered to a - * link group successfully. - */ + if (!lgr) return; - - conn->freed = 1; - if (conn->killed) - goto lgr_put; - if (lgr->is_smcd) { if (!list_empty(&lgr->list)) smc_ism_unset_conn(conn); @@ -1100,8 +1086,6 @@ void smc_conn_free(struct smc_connection *conn) if (!lgr->conns_num) smc_lgr_schedule_free_work(lgr); -lgr_put: - smc_lgr_put(lgr); /* lgr_hold in smc_lgr_register_conn() */ } /* unregister a link from a buf_desc */ @@ -1175,7 +1159,6 @@ void smcr_link_clear(struct smc_link *lnk, bool log) smc_ib_dealloc_protection_domain(lnk); smc_wr_free_link_mem(lnk); smc_ibdev_cnt_dec(lnk); - smc_lgr_put(lnk->lgr); /* lgr_hold in smcr_link_init() */ put_device(&lnk->smcibdev->ibdev->dev); smcibdev = lnk->smcibdev; memset(lnk, 0, sizeof(struct smc_link)); @@ -1248,13 +1231,6 @@ static void smc_lgr_free_bufs(struct smc_link_group *lgr) __smc_lgr_free_bufs(lgr, true); } -/* won't be freed until no one accesses to lgr anymore */ -static void __smc_lgr_free(struct smc_link_group *lgr) -{ - smc_lgr_free_bufs(lgr); - kfree(lgr); -} - /* remove a link group */ static void smc_lgr_free(struct smc_link_group *lgr) { @@ -1270,6 +1246,7 @@ static void smc_lgr_free(struct smc_link_group *lgr) smc_llc_lgr_clear(lgr); } + smc_lgr_free_bufs(lgr); destroy_workqueue(lgr->tx_wq); if (lgr->is_smcd) { smc_ism_put_vlan(lgr->smcd, lgr->vlan_id); @@ -1280,18 +1257,7 @@ static void smc_lgr_free(struct smc_link_group *lgr) if (!atomic_dec_return(&lgr_cnt)) wake_up(&lgrs_deleted); } - smc_lgr_put(lgr); /* theoretically last lgr_put */ -} - -void smc_lgr_hold(struct smc_link_group *lgr) -{ - refcount_inc(&lgr->refcnt); -} - -void smc_lgr_put(struct smc_link_group *lgr) -{ - if (refcount_dec_and_test(&lgr->refcnt)) - __smc_lgr_free(lgr); + kfree(lgr); } static void smcd_unregister_all_dmbs(struct smc_link_group *lgr) diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h index 4ce4636f8c05..45a6b89e6d42 100644 --- a/net/smc/smc_core.h +++ b/net/smc/smc_core.h @@ -252,7 +252,6 @@ struct smc_link_group { u8 terminating : 1;/* lgr is terminating */ u8 freeing : 1; /* lgr is being freed */ - refcount_t refcnt; /* lgr reference count */ bool is_smcd; /* SMC-R or SMC-D */ u8 smc_version; u8 negotiated_eid[SMC_MAX_EID_LEN]; @@ -437,8 +436,6 @@ struct smc_clc_msg_local; void smc_lgr_cleanup_early(struct smc_connection *conn); void smc_lgr_terminate_sched(struct smc_link_group *lgr); -void smc_lgr_hold(struct smc_link_group *lgr); -void smc_lgr_put(struct smc_link_group *lgr); void smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport); void smcr_port_err(struct smc_ib_device *smcibdev, u8 ibport); void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, -- 2.34.1