Skip to content

Commit 36595d8

Browse files
Wen Gudavem330
authored andcommitted
net/smc: Reset conn->lgr when link group registration fails
SMC connections might fail to be registered in a link group due to unable to find a usable link during its creation. As a result, smc_conn_create() will return a failure and most resources related to the connection won't be applied or initialized, such as conn->abort_work or conn->lnk. If smc_conn_free() is invoked later, it will try to access the uninitialized resources related to the connection, thus causing a warning or crash. This patch tries to fix this by resetting conn->lgr to NULL if an abnormal exit occurs in smc_lgr_register_conn(), thus avoiding the access to uninitialized resources in smc_conn_free(). Meanwhile, the new created link group should be terminated if smc connections can't be registered in it. So smc_lgr_cleanup_early() is modified to take care of link group only and invoked to terminate unusable link group by smc_conn_create(). The call to smc_conn_free() is moved out from smc_lgr_cleanup_early() to smc_conn_abort(). Fixes: 56bc3b2 ("net/smc: assign link to a new connection") Suggested-by: Karsten Graul <[email protected]> Signed-off-by: Wen Gu <[email protected]> Acked-by: Karsten Graul <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d5a73ec commit 36595d8

File tree

3 files changed

+13
-9
lines changed

3 files changed

+13
-9
lines changed

net/smc/af_smc.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -632,10 +632,12 @@ static int smc_connect_decline_fallback(struct smc_sock *smc, int reason_code,
632632

633633
static void smc_conn_abort(struct smc_sock *smc, int local_first)
634634
{
635+
struct smc_connection *conn = &smc->conn;
636+
struct smc_link_group *lgr = conn->lgr;
637+
638+
smc_conn_free(conn);
635639
if (local_first)
636-
smc_lgr_cleanup_early(&smc->conn);
637-
else
638-
smc_conn_free(&smc->conn);
640+
smc_lgr_cleanup_early(lgr);
639641
}
640642

641643
/* check if there is a rdma device available for this connection. */

net/smc/smc_core.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,10 @@ static int smc_lgr_register_conn(struct smc_connection *conn, bool first)
171171

172172
if (!conn->lgr->is_smcd) {
173173
rc = smcr_lgr_conn_assign_link(conn, first);
174-
if (rc)
174+
if (rc) {
175+
conn->lgr = NULL;
175176
return rc;
177+
}
176178
}
177179
/* find a new alert_token_local value not yet used by some connection
178180
* in this link group
@@ -622,15 +624,13 @@ int smcd_nl_get_lgr(struct sk_buff *skb, struct netlink_callback *cb)
622624
return skb->len;
623625
}
624626

625-
void smc_lgr_cleanup_early(struct smc_connection *conn)
627+
void smc_lgr_cleanup_early(struct smc_link_group *lgr)
626628
{
627-
struct smc_link_group *lgr = conn->lgr;
628629
spinlock_t *lgr_lock;
629630

630631
if (!lgr)
631632
return;
632633

633-
smc_conn_free(conn);
634634
smc_lgr_list_head(lgr, &lgr_lock);
635635
spin_lock_bh(lgr_lock);
636636
/* do not use this link group for new connections */
@@ -1832,8 +1832,10 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
18321832
write_lock_bh(&lgr->conns_lock);
18331833
rc = smc_lgr_register_conn(conn, true);
18341834
write_unlock_bh(&lgr->conns_lock);
1835-
if (rc)
1835+
if (rc) {
1836+
smc_lgr_cleanup_early(lgr);
18361837
goto out;
1838+
}
18371839
}
18381840
conn->local_tx_ctrl.common.type = SMC_CDC_MSG_TYPE;
18391841
conn->local_tx_ctrl.len = SMC_WR_TX_SIZE;

net/smc/smc_core.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ static inline void smc_set_pci_values(struct pci_dev *pci_dev,
468468
struct smc_sock;
469469
struct smc_clc_msg_accept_confirm;
470470

471-
void smc_lgr_cleanup_early(struct smc_connection *conn);
471+
void smc_lgr_cleanup_early(struct smc_link_group *lgr);
472472
void smc_lgr_terminate_sched(struct smc_link_group *lgr);
473473
void smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport);
474474
void smcr_port_err(struct smc_ib_device *smcibdev, u8 ibport);

0 commit comments

Comments
 (0)