Home Home > GIT Browse > SLE12-SP4
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Tesarik <ptesarik@suse.cz>2019-05-23 21:35:31 +0200
committerPetr Tesarik <ptesarik@suse.cz>2019-05-23 21:35:42 +0200
commitab601a52786481156bcca12e18cd0a899bf99e02 (patch)
tree5850bf9ccf4460436caaee4b30b86e0096f3c840
parent6f0904a1769b4cb0b9d014896c7476a34485a570 (diff)
net/smc: improve smc_conn_create reason codes (bsc#1134607SLE12-SP4
LTC#177518).
-rw-r--r--patches.fixes/net-smc-improve-smc_conn_create-reason-codes375
-rw-r--r--series.conf1
2 files changed, 376 insertions, 0 deletions
diff --git a/patches.fixes/net-smc-improve-smc_conn_create-reason-codes b/patches.fixes/net-smc-improve-smc_conn_create-reason-codes
new file mode 100644
index 0000000000..28bf8e49f6
--- /dev/null
+++ b/patches.fixes/net-smc-improve-smc_conn_create-reason-codes
@@ -0,0 +1,375 @@
+From: Karsten Graul <kgraul@linux.ibm.com>
+Date: Fri, 12 Apr 2019 12:57:30 +0200
+Subject: net/smc: improve smc_conn_create reason codes
+Git-commit: 7a62725a50e0282ed90185074c769ce2ecb16e59
+Patch-mainline: v5.2-rc1
+References: bsc#1134607 LTC#177518
+
+Rework smc_conn_create() to always return a valid DECLINE reason code.
+This removes the need to translate the return codes on 4 different
+places and allows to easily add more detailed return codes by changing
+smc_conn_create() only.
+
+Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
+Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Petr Tesarik <ptesarik@suse.com>
+---
+ net/smc/af_smc.c | 90 +++++++++++++++++++++++------------------------------
+ net/smc/smc_clc.h | 1
+ net/smc/smc_core.c | 25 +++++++++-----
+ net/smc/smc_core.h | 1
+ 4 files changed, 58 insertions(+), 59 deletions(-)
+
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -532,7 +532,7 @@ static int smc_connect_ism_vlan_setup(st
+ struct smc_init_info *ini)
+ {
+ if (ini->vlan_id && smc_ism_get_vlan(ini->ism_dev, ini->vlan_id))
+- return SMC_CLC_DECL_CNFERR;
++ return SMC_CLC_DECL_ISMVLANERR;
+ return 0;
+ }
+
+@@ -570,7 +570,6 @@ static int smc_connect_rdma(struct smc_s
+ struct smc_clc_msg_accept_confirm *aclc,
+ struct smc_init_info *ini)
+ {
+- int local_contact = SMC_FIRST_CONTACT;
+ struct smc_link *link;
+ int reason_code = 0;
+
+@@ -580,14 +579,8 @@ static int smc_connect_rdma(struct smc_s
+ ini->srv_first_contact = aclc->hdr.flag;
+
+ mutex_lock(&smc_client_lgr_pending);
+- local_contact = smc_conn_create(smc, ini);
+- if (local_contact < 0) {
+- if (local_contact == -ENOMEM)
+- reason_code = SMC_CLC_DECL_MEM;/* insufficient memory*/
+- else if (local_contact == -ENOLINK)
+- reason_code = SMC_CLC_DECL_SYNCERR; /* synchr. error */
+- else
+- reason_code = SMC_CLC_DECL_INTERR; /* other error */
++ reason_code = smc_conn_create(smc, ini);
++ if (reason_code) {
+ mutex_unlock(&smc_client_lgr_pending);
+ return reason_code;
+ }
+@@ -597,41 +590,43 @@ static int smc_connect_rdma(struct smc_s
+
+ /* create send buffer and rmb */
+ if (smc_buf_create(smc, false))
+- return smc_connect_abort(smc, SMC_CLC_DECL_MEM, local_contact);
++ return smc_connect_abort(smc, SMC_CLC_DECL_MEM,
++ ini->cln_first_contact);
+
+- if (local_contact == SMC_FIRST_CONTACT)
++ if (ini->cln_first_contact == SMC_FIRST_CONTACT)
+ smc_link_save_peer_info(link, aclc);
+
+ if (smc_rmb_rtoken_handling(&smc->conn, aclc))
+ return smc_connect_abort(smc, SMC_CLC_DECL_ERR_RTOK,
+- local_contact);
++ ini->cln_first_contact);
+
+ smc_close_init(smc);
+ smc_rx_init(smc);
+
+- if (local_contact == SMC_FIRST_CONTACT) {
++ if (ini->cln_first_contact == SMC_FIRST_CONTACT) {
+ if (smc_ib_ready_link(link))
+ return smc_connect_abort(smc, SMC_CLC_DECL_ERR_RDYLNK,
+- local_contact);
++ ini->cln_first_contact);
+ } else {
+ if (smc_reg_rmb(link, smc->conn.rmb_desc, true))
+ return smc_connect_abort(smc, SMC_CLC_DECL_ERR_REGRMB,
+- local_contact);
++ ini->cln_first_contact);
+ }
+ smc_rmb_sync_sg_for_device(&smc->conn);
+
+ reason_code = smc_clc_send_confirm(smc);
+ if (reason_code)
+- return smc_connect_abort(smc, reason_code, local_contact);
++ return smc_connect_abort(smc, reason_code,
++ ini->cln_first_contact);
+
+ smc_tx_init(smc);
+
+- if (local_contact == SMC_FIRST_CONTACT) {
++ if (ini->cln_first_contact == SMC_FIRST_CONTACT) {
+ /* QP confirmation over RoCE fabric */
+ reason_code = smc_clnt_conf_first_link(smc);
+ if (reason_code)
+ return smc_connect_abort(smc, reason_code,
+- local_contact);
++ ini->cln_first_contact);
+ }
+ mutex_unlock(&smc_client_lgr_pending);
+
+@@ -648,7 +643,6 @@ static int smc_connect_ism(struct smc_so
+ struct smc_clc_msg_accept_confirm *aclc,
+ struct smc_init_info *ini)
+ {
+- int local_contact = SMC_FIRST_CONTACT;
+ int rc = 0;
+
+ ini->is_smcd = true;
+@@ -657,15 +651,16 @@ static int smc_connect_ism(struct smc_so
+
+ /* there is only one lgr role for SMC-D; use server lock */
+ mutex_lock(&smc_server_lgr_pending);
+- local_contact = smc_conn_create(smc, ini);
+- if (local_contact < 0) {
++ rc = smc_conn_create(smc, ini);
++ if (rc) {
+ mutex_unlock(&smc_server_lgr_pending);
+- return SMC_CLC_DECL_MEM;
++ return rc;
+ }
+
+ /* Create send and receive buffers */
+ if (smc_buf_create(smc, true))
+- return smc_connect_abort(smc, SMC_CLC_DECL_MEM, local_contact);
++ return smc_connect_abort(smc, SMC_CLC_DECL_MEM,
++ ini->cln_first_contact);
+
+ smc_conn_save_peer_info(smc, aclc);
+ smc_close_init(smc);
+@@ -674,7 +669,7 @@ static int smc_connect_ism(struct smc_so
+
+ rc = smc_clc_send_confirm(smc);
+ if (rc)
+- return smc_connect_abort(smc, rc, local_contact);
++ return smc_connect_abort(smc, rc, ini->cln_first_contact);
+ mutex_unlock(&smc_server_lgr_pending);
+
+ smc_copy_sock_settings_to_clc(smc);
+@@ -1131,15 +1126,14 @@ static int smc_listen_prfx_check(struct
+
+ /* listen worker: initialize connection and buffers */
+ static int smc_listen_rdma_init(struct smc_sock *new_smc,
+- struct smc_init_info *ini, int *local_contact)
++ struct smc_init_info *ini)
+ {
++ int rc;
++
+ /* allocate connection / link group */
+- *local_contact = smc_conn_create(new_smc, ini);
+- if (*local_contact < 0) {
+- if (*local_contact == -ENOMEM)
+- return SMC_CLC_DECL_MEM;/* insufficient memory*/
+- return SMC_CLC_DECL_INTERR; /* other error */
+- }
++ rc = smc_conn_create(new_smc, ini);
++ if (rc)
++ return rc;
+
+ /* create send buffer and rmb */
+ if (smc_buf_create(new_smc, false))
+@@ -1151,25 +1145,22 @@ static int smc_listen_rdma_init(struct s
+ /* listen worker: initialize connection and buffers for SMC-D */
+ static int smc_listen_ism_init(struct smc_sock *new_smc,
+ struct smc_clc_msg_proposal *pclc,
+- struct smc_init_info *ini,
+- int *local_contact)
++ struct smc_init_info *ini)
+ {
+ struct smc_clc_msg_smcd *pclc_smcd;
++ int rc;
+
+ pclc_smcd = smc_get_clc_msg_smcd(pclc);
+ ini->ism_gid = pclc_smcd->gid;
+- *local_contact = smc_conn_create(new_smc, ini);
+- if (*local_contact < 0) {
+- if (*local_contact == -ENOMEM)
+- return SMC_CLC_DECL_MEM;/* insufficient memory*/
+- return SMC_CLC_DECL_INTERR; /* other error */
+- }
++ rc = smc_conn_create(new_smc, ini);
++ if (rc)
++ return rc;
+
+ /* Check if peer can be reached via ISM device */
+ if (smc_ism_cantalk(new_smc->conn.lgr->peer_gid,
+ new_smc->conn.lgr->vlan_id,
+ new_smc->conn.lgr->smcd)) {
+- if (*local_contact == SMC_FIRST_CONTACT)
++ if (ini->cln_first_contact == SMC_FIRST_CONTACT)
+ smc_lgr_forget(new_smc->conn.lgr);
+ smc_conn_free(&new_smc->conn);
+ return SMC_CLC_DECL_SMCDNOTALK;
+@@ -1177,7 +1168,7 @@ static int smc_listen_ism_init(struct sm
+
+ /* Create send and receive buffers */
+ if (smc_buf_create(new_smc, true)) {
+- if (*local_contact == SMC_FIRST_CONTACT)
++ if (ini->cln_first_contact == SMC_FIRST_CONTACT)
+ smc_lgr_forget(new_smc->conn.lgr);
+ smc_conn_free(&new_smc->conn);
+ return SMC_CLC_DECL_MEM;
+@@ -1244,7 +1235,6 @@ static void smc_listen_work(struct work_
+ struct smc_init_info ini = {0};
+ bool ism_supported = false;
+ u8 buf[SMC_CLC_MAX_LEN];
+- int local_contact = 0;
+ int rc = 0;
+
+ if (new_smc->listen_smc->sk.sk_state != SMC_LISTEN)
+@@ -1299,8 +1289,7 @@ static void smc_listen_work(struct work_
+ ini.is_smcd = true; /* prepare ISM check */
+ rc = smc_find_ism_device(new_smc, &ini);
+ if (!rc)
+- rc = smc_listen_ism_init(new_smc, pclc, &ini,
+- &local_contact);
++ rc = smc_listen_ism_init(new_smc, pclc, &ini);
+ if (!rc)
+ ism_supported = true;
+ else if (pclc->hdr.path == SMC_TYPE_D)
+@@ -1321,16 +1310,16 @@ static void smc_listen_work(struct work_
+ rc = SMC_CLC_DECL_NOSMCDEV;
+ goto out_unlock;
+ }
+- rc = smc_listen_rdma_init(new_smc, &ini, &local_contact);
++ rc = smc_listen_rdma_init(new_smc, &ini);
+ if (rc)
+ goto out_unlock;
+- rc = smc_listen_rdma_reg(new_smc, local_contact);
++ rc = smc_listen_rdma_reg(new_smc, ini.cln_first_contact);
+ if (rc)
+ goto out_unlock;
+ }
+
+ /* send SMC Accept CLC message */
+- rc = smc_clc_send_accept(new_smc, local_contact);
++ rc = smc_clc_send_accept(new_smc, ini.cln_first_contact);
+ if (rc)
+ goto out_unlock;
+
+@@ -1349,7 +1338,8 @@ static void smc_listen_work(struct work_
+
+ /* finish worker */
+ if (!ism_supported) {
+- rc = smc_listen_rdma_finish(new_smc, &cclc, local_contact);
++ rc = smc_listen_rdma_finish(new_smc, &cclc,
++ ini.cln_first_contact);
+ mutex_unlock(&smc_server_lgr_pending);
+ if (rc)
+ return;
+@@ -1361,7 +1351,7 @@ static void smc_listen_work(struct work_
+ out_unlock:
+ mutex_unlock(&smc_server_lgr_pending);
+ out_decl:
+- smc_listen_decline(new_smc, rc, local_contact);
++ smc_listen_decline(new_smc, rc, ini.cln_first_contact);
+ }
+
+ static void smc_tcp_listen_work(struct work_struct *work)
+--- a/net/smc/smc_clc.h
++++ b/net/smc/smc_clc.h
+@@ -42,6 +42,7 @@
+ #define SMC_CLC_DECL_OPTUNSUPP 0x03060000 /* fastopen sockopt not supported */
+ #define SMC_CLC_DECL_DIFFPREFIX 0x03070000 /* IP prefix / subnet mismatch */
+ #define SMC_CLC_DECL_GETVLANERR 0x03080000 /* err to get vlan id of ip device*/
++#define SMC_CLC_DECL_ISMVLANERR 0x03090000 /* err to reg vlan id on ism dev */
+ #define SMC_CLC_DECL_SYNCERR 0x04000000 /* synchronization error */
+ #define SMC_CLC_DECL_PEERDECL 0x05000000 /* peer declined during handshake */
+ #define SMC_CLC_DECL_INTERR 0x09990000 /* internal error */
+--- a/net/smc/smc_core.c
++++ b/net/smc/smc_core.c
+@@ -203,14 +203,15 @@ static int smc_lgr_create(struct smc_soc
+ int i;
+
+ if (ini->is_smcd && ini->vlan_id) {
+- rc = smc_ism_get_vlan(ini->ism_dev, ini->vlan_id);
+- if (rc)
++ if (smc_ism_get_vlan(ini->ism_dev, ini->vlan_id)) {
++ rc = SMC_CLC_DECL_ISMVLANERR;
+ goto out;
++ }
+ }
+
+ lgr = kzalloc(sizeof(*lgr), GFP_KERNEL);
+ if (!lgr) {
+- rc = -ENOMEM;
++ rc = SMC_CLC_DECL_MEM;
+ goto out;
+ }
+ lgr->is_smcd = ini->is_smcd;
+@@ -290,6 +291,12 @@ clear_llc_lnk:
+ free_lgr:
+ kfree(lgr);
+ out:
++ if (rc < 0) {
++ if (rc == -ENOMEM)
++ rc = SMC_CLC_DECL_MEM;
++ else
++ rc = SMC_CLC_DECL_INTERR;
++ }
+ return rc;
+ }
+
+@@ -598,11 +605,11 @@ static bool smcd_lgr_match(struct smc_li
+ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)
+ {
+ struct smc_connection *conn = &smc->conn;
+- int local_contact = SMC_FIRST_CONTACT;
+ struct smc_link_group *lgr;
+ enum smc_lgr_role role;
+ int rc = 0;
+
++ ini->cln_first_contact = SMC_FIRST_CONTACT;
+ role = smc->listen_smc ? SMC_SERV : SMC_CLNT;
+ if (role == SMC_CLNT && ini->srv_first_contact)
+ /* create new link group as well */
+@@ -620,7 +627,7 @@ int smc_conn_create(struct smc_sock *smc
+ (role == SMC_CLNT ||
+ lgr->conns_num < SMC_RMBS_PER_LGR_MAX)) {
+ /* link group found */
+- local_contact = SMC_REUSE_CONTACT;
++ ini->cln_first_contact = SMC_REUSE_CONTACT;
+ conn->lgr = lgr;
+ smc_lgr_register_conn(conn); /* add smc conn to lgr */
+ if (delayed_work_pending(&lgr->free_work))
+@@ -633,16 +640,16 @@ int smc_conn_create(struct smc_sock *smc
+ spin_unlock_bh(&smc_lgr_list.lock);
+
+ if (role == SMC_CLNT && !ini->srv_first_contact &&
+- local_contact == SMC_FIRST_CONTACT) {
++ ini->cln_first_contact == SMC_FIRST_CONTACT) {
+ /* Server reuses a link group, but Client wants to start
+ * a new one
+ * send out_of_sync decline, reason synchr. error
+ */
+- return -ENOLINK;
++ return SMC_CLC_DECL_SYNCERR;
+ }
+
+ create:
+- if (local_contact == SMC_FIRST_CONTACT) {
++ if (ini->cln_first_contact == SMC_FIRST_CONTACT) {
+ rc = smc_lgr_create(smc, ini);
+ if (rc)
+ goto out;
+@@ -660,7 +667,7 @@ create:
+ #endif
+
+ out:
+- return rc ? rc : local_contact;
++ return rc;
+ }
+
+ /* convert the RMB size into the compressed notation - minimum 16K.
+--- a/net/smc/smc_core.h
++++ b/net/smc/smc_core.h
+@@ -234,6 +234,7 @@ struct smc_init_info {
+ u8 is_smcd;
+ unsigned short vlan_id;
+ int srv_first_contact;
++ int cln_first_contact;
+ /* SMC-R */
+ struct smc_clc_msg_local *ib_lcl;
+ struct smc_ib_device *ib_dev;
diff --git a/series.conf b/series.conf
index 214a0f3ae2..bfab8cd5db 100644
--- a/series.conf
+++ b/series.conf
@@ -22253,6 +22253,7 @@
patches.fixes/net-smc-cleanup-of-get-vlan-id
patches.fixes/net-smc-code-cleanup-smc_listen_work
patches.fixes/net-smc-improve-smc_listen_work-reason-codes
+ patches.fixes/net-smc-improve-smc_conn_create-reason-codes
patches.drivers/b43-shut-up-clang-Wuninitialized-variable-warning.patch
patches.drivers/mwifiex-Fix-mem-leak-in-mwifiex_tm_cmd.patch
patches.drivers/Bluetooth-hidp-fix-buffer-overflow.patch