aboutsummaryrefslogtreecommitdiffstats
path: root/net/smc
diff options
context:
space:
mode:
authorKarsten Graul <kgraul@linux.ibm.com>2018-07-25 10:35:32 -0400
committerDavid S. Miller <davem@davemloft.net>2018-07-26 01:25:53 -0400
commit603cc1498455cf57f5ca4483b600efb37ea2c56c (patch)
treeba933ac7ee9002bc65e53e6bfc868c363c63676a /net/smc
parent7005ada68d1774d7c1109deaba0c2cd8e46f5091 (diff)
net/smc: provide fallback reason code
Remember the fallback reason code and the peer diagnosis code for smc sockets, and provide them in smc_diag.c to the netlink interface. And add more detailed reason codes. 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>
Diffstat (limited to 'net/smc')
-rw-r--r--net/smc/af_smc.c52
-rw-r--r--net/smc/smc.h2
-rw-r--r--net/smc/smc_clc.c6
-rw-r--r--net/smc/smc_clc.h18
-rw-r--r--net/smc/smc_diag.c6
5 files changed, 55 insertions, 29 deletions
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index b81797103260..fce7e4751151 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -344,17 +344,17 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc)
344 344
345 rc = smc_ib_modify_qp_rts(link); 345 rc = smc_ib_modify_qp_rts(link);
346 if (rc) 346 if (rc)
347 return SMC_CLC_DECL_INTERR; 347 return SMC_CLC_DECL_ERR_RDYLNK;
348 348
349 smc_wr_remember_qp_attr(link); 349 smc_wr_remember_qp_attr(link);
350 350
351 if (smc_reg_rmb(link, smc->conn.rmb_desc, false)) 351 if (smc_reg_rmb(link, smc->conn.rmb_desc, false))
352 return SMC_CLC_DECL_INTERR; 352 return SMC_CLC_DECL_ERR_REGRMB;
353 353
354 /* send CONFIRM LINK response over RoCE fabric */ 354 /* send CONFIRM LINK response over RoCE fabric */
355 rc = smc_llc_send_confirm_link(link, SMC_LLC_RESP); 355 rc = smc_llc_send_confirm_link(link, SMC_LLC_RESP);
356 if (rc < 0) 356 if (rc < 0)
357 return SMC_CLC_DECL_TCL; 357 return SMC_CLC_DECL_TIMEOUT_CL;
358 358
359 /* receive ADD LINK request from server over RoCE fabric */ 359 /* receive ADD LINK request from server over RoCE fabric */
360 rest = wait_for_completion_interruptible_timeout(&link->llc_add, 360 rest = wait_for_completion_interruptible_timeout(&link->llc_add,
@@ -372,7 +372,7 @@ static int smc_clnt_conf_first_link(struct smc_sock *smc)
372 link->smcibdev->mac[link->ibport - 1], 372 link->smcibdev->mac[link->ibport - 1],
373 link->gid, SMC_LLC_RESP); 373 link->gid, SMC_LLC_RESP);
374 if (rc < 0) 374 if (rc < 0)
375 return SMC_CLC_DECL_TCL; 375 return SMC_CLC_DECL_TIMEOUT_AL;
376 376
377 smc_llc_link_active(link, net->ipv4.sysctl_tcp_keepalive_time); 377 smc_llc_link_active(link, net->ipv4.sysctl_tcp_keepalive_time);
378 378
@@ -424,9 +424,10 @@ static void smc_link_save_peer_info(struct smc_link *link,
424} 424}
425 425
426/* fall back during connect */ 426/* fall back during connect */
427static int smc_connect_fallback(struct smc_sock *smc) 427static int smc_connect_fallback(struct smc_sock *smc, int reason_code)
428{ 428{
429 smc->use_fallback = true; 429 smc->use_fallback = true;
430 smc->fallback_rsn = reason_code;
430 smc_copy_sock_settings_to_clc(smc); 431 smc_copy_sock_settings_to_clc(smc);
431 if (smc->sk.sk_state == SMC_INIT) 432 if (smc->sk.sk_state == SMC_INIT)
432 smc->sk.sk_state = SMC_ACTIVE; 433 smc->sk.sk_state = SMC_ACTIVE;
@@ -443,7 +444,7 @@ static int smc_connect_decline_fallback(struct smc_sock *smc, int reason_code)
443 sock_put(&smc->sk); /* passive closing */ 444 sock_put(&smc->sk); /* passive closing */
444 return reason_code; 445 return reason_code;
445 } 446 }
446 if (reason_code != SMC_CLC_DECL_REPLY) { 447 if (reason_code != SMC_CLC_DECL_PEERDECL) {
447 rc = smc_clc_send_decline(smc, reason_code); 448 rc = smc_clc_send_decline(smc, reason_code);
448 if (rc < 0) { 449 if (rc < 0) {
449 if (smc->sk.sk_state == SMC_INIT) 450 if (smc->sk.sk_state == SMC_INIT)
@@ -451,7 +452,7 @@ static int smc_connect_decline_fallback(struct smc_sock *smc, int reason_code)
451 return rc; 452 return rc;
452 } 453 }
453 } 454 }
454 return smc_connect_fallback(smc); 455 return smc_connect_fallback(smc, reason_code);
455} 456}
456 457
457/* abort connecting */ 458/* abort connecting */
@@ -568,7 +569,7 @@ static int smc_connect_rdma(struct smc_sock *smc,
568 smc_link_save_peer_info(link, aclc); 569 smc_link_save_peer_info(link, aclc);
569 570
570 if (smc_rmb_rtoken_handling(&smc->conn, aclc)) 571 if (smc_rmb_rtoken_handling(&smc->conn, aclc))
571 return smc_connect_abort(smc, SMC_CLC_DECL_INTERR, 572 return smc_connect_abort(smc, SMC_CLC_DECL_ERR_RTOK,
572 local_contact); 573 local_contact);
573 574
574 smc_close_init(smc); 575 smc_close_init(smc);
@@ -576,12 +577,12 @@ static int smc_connect_rdma(struct smc_sock *smc,
576 577
577 if (local_contact == SMC_FIRST_CONTACT) { 578 if (local_contact == SMC_FIRST_CONTACT) {
578 if (smc_ib_ready_link(link)) 579 if (smc_ib_ready_link(link))
579 return smc_connect_abort(smc, SMC_CLC_DECL_INTERR, 580 return smc_connect_abort(smc, SMC_CLC_DECL_ERR_RDYLNK,
580 local_contact); 581 local_contact);
581 } else { 582 } else {
582 if (!smc->conn.rmb_desc->reused && 583 if (!smc->conn.rmb_desc->reused &&
583 smc_reg_rmb(link, smc->conn.rmb_desc, true)) 584 smc_reg_rmb(link, smc->conn.rmb_desc, true))
584 return smc_connect_abort(smc, SMC_CLC_DECL_INTERR, 585 return smc_connect_abort(smc, SMC_CLC_DECL_ERR_REGRMB,
585 local_contact); 586 local_contact);
586 } 587 }
587 smc_rmb_sync_sg_for_device(&smc->conn); 588 smc_rmb_sync_sg_for_device(&smc->conn);
@@ -659,11 +660,11 @@ static int __smc_connect(struct smc_sock *smc)
659 sock_hold(&smc->sk); /* sock put in passive closing */ 660 sock_hold(&smc->sk); /* sock put in passive closing */
660 661
661 if (smc->use_fallback) 662 if (smc->use_fallback)
662 return smc_connect_fallback(smc); 663 return smc_connect_fallback(smc, smc->fallback_rsn);
663 664
664 /* if peer has not signalled SMC-capability, fall back */ 665 /* if peer has not signalled SMC-capability, fall back */
665 if (!tcp_sk(smc->clcsock->sk)->syn_smc) 666 if (!tcp_sk(smc->clcsock->sk)->syn_smc)
666 return smc_connect_fallback(smc); 667 return smc_connect_fallback(smc, SMC_CLC_DECL_PEERNOSMC);
667 668
668 /* IPSec connections opt out of SMC-R optimizations */ 669 /* IPSec connections opt out of SMC-R optimizations */
669 if (using_ipsec(smc)) 670 if (using_ipsec(smc))
@@ -693,7 +694,7 @@ static int __smc_connect(struct smc_sock *smc)
693 694
694 /* if neither ISM nor RDMA are supported, fallback */ 695 /* if neither ISM nor RDMA are supported, fallback */
695 if (!rdma_supported && !ism_supported) 696 if (!rdma_supported && !ism_supported)
696 return smc_connect_decline_fallback(smc, SMC_CLC_DECL_CNFERR); 697 return smc_connect_decline_fallback(smc, SMC_CLC_DECL_NOSMCDEV);
697 698
698 /* perform CLC handshake */ 699 /* perform CLC handshake */
699 rc = smc_connect_clc(smc, smc_type, &aclc, ibdev, ibport, gid, ismdev); 700 rc = smc_connect_clc(smc, smc_type, &aclc, ibdev, ibport, gid, ismdev);
@@ -708,7 +709,7 @@ static int __smc_connect(struct smc_sock *smc)
708 else if (ism_supported && aclc.hdr.path == SMC_TYPE_D) 709 else if (ism_supported && aclc.hdr.path == SMC_TYPE_D)
709 rc = smc_connect_ism(smc, &aclc, ismdev); 710 rc = smc_connect_ism(smc, &aclc, ismdev);
710 else 711 else
711 rc = SMC_CLC_DECL_CNFERR; 712 rc = SMC_CLC_DECL_MODEUNSUPP;
712 if (rc) { 713 if (rc) {
713 smc_connect_ism_vlan_cleanup(smc, ism_supported, ismdev, vlan); 714 smc_connect_ism_vlan_cleanup(smc, ism_supported, ismdev, vlan);
714 return smc_connect_decline_fallback(smc, rc); 715 return smc_connect_decline_fallback(smc, rc);
@@ -946,12 +947,12 @@ static int smc_serv_conf_first_link(struct smc_sock *smc)
946 link = &lgr->lnk[SMC_SINGLE_LINK]; 947 link = &lgr->lnk[SMC_SINGLE_LINK];
947 948
948 if (smc_reg_rmb(link, smc->conn.rmb_desc, false)) 949 if (smc_reg_rmb(link, smc->conn.rmb_desc, false))
949 return SMC_CLC_DECL_INTERR; 950 return SMC_CLC_DECL_ERR_REGRMB;
950 951
951 /* send CONFIRM LINK request to client over the RoCE fabric */ 952 /* send CONFIRM LINK request to client over the RoCE fabric */
952 rc = smc_llc_send_confirm_link(link, SMC_LLC_REQ); 953 rc = smc_llc_send_confirm_link(link, SMC_LLC_REQ);
953 if (rc < 0) 954 if (rc < 0)
954 return SMC_CLC_DECL_TCL; 955 return SMC_CLC_DECL_TIMEOUT_CL;
955 956
956 /* receive CONFIRM LINK response from client over the RoCE fabric */ 957 /* receive CONFIRM LINK response from client over the RoCE fabric */
957 rest = wait_for_completion_interruptible_timeout( 958 rest = wait_for_completion_interruptible_timeout(
@@ -973,7 +974,7 @@ static int smc_serv_conf_first_link(struct smc_sock *smc)
973 link->smcibdev->mac[link->ibport - 1], 974 link->smcibdev->mac[link->ibport - 1],
974 link->gid, SMC_LLC_REQ); 975 link->gid, SMC_LLC_REQ);
975 if (rc < 0) 976 if (rc < 0)
976 return SMC_CLC_DECL_TCL; 977 return SMC_CLC_DECL_TIMEOUT_AL;
977 978
978 /* receive ADD LINK response from client over the RoCE fabric */ 979 /* receive ADD LINK response from client over the RoCE fabric */
979 rest = wait_for_completion_interruptible_timeout(&link->llc_add_resp, 980 rest = wait_for_completion_interruptible_timeout(&link->llc_add_resp,
@@ -1048,7 +1049,8 @@ static void smc_listen_decline(struct smc_sock *new_smc, int reason_code,
1048 } 1049 }
1049 smc_conn_free(&new_smc->conn); 1050 smc_conn_free(&new_smc->conn);
1050 new_smc->use_fallback = true; 1051 new_smc->use_fallback = true;
1051 if (reason_code && reason_code != SMC_CLC_DECL_REPLY) { 1052 new_smc->fallback_rsn = reason_code;
1053 if (reason_code && reason_code != SMC_CLC_DECL_PEERDECL) {
1052 if (smc_clc_send_decline(new_smc, reason_code) < 0) { 1054 if (smc_clc_send_decline(new_smc, reason_code) < 0) {
1053 smc_listen_out_err(new_smc); 1055 smc_listen_out_err(new_smc);
1054 return; 1056 return;
@@ -1139,7 +1141,7 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, int local_contact)
1139 if (local_contact != SMC_FIRST_CONTACT) { 1141 if (local_contact != SMC_FIRST_CONTACT) {
1140 if (!new_smc->conn.rmb_desc->reused) { 1142 if (!new_smc->conn.rmb_desc->reused) {
1141 if (smc_reg_rmb(link, new_smc->conn.rmb_desc, true)) 1143 if (smc_reg_rmb(link, new_smc->conn.rmb_desc, true))
1142 return SMC_CLC_DECL_INTERR; 1144 return SMC_CLC_DECL_ERR_REGRMB;
1143 } 1145 }
1144 } 1146 }
1145 smc_rmb_sync_sg_for_device(&new_smc->conn); 1147 smc_rmb_sync_sg_for_device(&new_smc->conn);
@@ -1159,13 +1161,13 @@ static void smc_listen_rdma_finish(struct smc_sock *new_smc,
1159 smc_link_save_peer_info(link, cclc); 1161 smc_link_save_peer_info(link, cclc);
1160 1162
1161 if (smc_rmb_rtoken_handling(&new_smc->conn, cclc)) { 1163 if (smc_rmb_rtoken_handling(&new_smc->conn, cclc)) {
1162 reason_code = SMC_CLC_DECL_INTERR; 1164 reason_code = SMC_CLC_DECL_ERR_RTOK;
1163 goto decline; 1165 goto decline;
1164 } 1166 }
1165 1167
1166 if (local_contact == SMC_FIRST_CONTACT) { 1168 if (local_contact == SMC_FIRST_CONTACT) {
1167 if (smc_ib_ready_link(link)) { 1169 if (smc_ib_ready_link(link)) {
1168 reason_code = SMC_CLC_DECL_INTERR; 1170 reason_code = SMC_CLC_DECL_ERR_RDYLNK;
1169 goto decline; 1171 goto decline;
1170 } 1172 }
1171 /* QP confirmation over RoCE fabric */ 1173 /* QP confirmation over RoCE fabric */
@@ -1206,6 +1208,7 @@ static void smc_listen_work(struct work_struct *work)
1206 /* check if peer is smc capable */ 1208 /* check if peer is smc capable */
1207 if (!tcp_sk(newclcsock->sk)->syn_smc) { 1209 if (!tcp_sk(newclcsock->sk)->syn_smc) {
1208 new_smc->use_fallback = true; 1210 new_smc->use_fallback = true;
1211 new_smc->fallback_rsn = SMC_CLC_DECL_PEERNOSMC;
1209 smc_listen_out_connected(new_smc); 1212 smc_listen_out_connected(new_smc);
1210 return; 1213 return;
1211 } 1214 }
@@ -1250,7 +1253,8 @@ static void smc_listen_work(struct work_struct *work)
1250 smc_listen_rdma_reg(new_smc, local_contact))) { 1253 smc_listen_rdma_reg(new_smc, local_contact))) {
1251 /* SMC not supported, decline */ 1254 /* SMC not supported, decline */
1252 mutex_unlock(&smc_create_lgr_pending); 1255 mutex_unlock(&smc_create_lgr_pending);
1253 smc_listen_decline(new_smc, SMC_CLC_DECL_CNFERR, local_contact); 1256 smc_listen_decline(new_smc, SMC_CLC_DECL_MODEUNSUPP,
1257 local_contact);
1254 return; 1258 return;
1255 } 1259 }
1256 1260
@@ -1297,6 +1301,7 @@ static void smc_tcp_listen_work(struct work_struct *work)
1297 1301
1298 new_smc->listen_smc = lsmc; 1302 new_smc->listen_smc = lsmc;
1299 new_smc->use_fallback = lsmc->use_fallback; 1303 new_smc->use_fallback = lsmc->use_fallback;
1304 new_smc->fallback_rsn = lsmc->fallback_rsn;
1300 sock_hold(lsk); /* sock_put in smc_listen_work */ 1305 sock_hold(lsk); /* sock_put in smc_listen_work */
1301 INIT_WORK(&new_smc->smc_listen_work, smc_listen_work); 1306 INIT_WORK(&new_smc->smc_listen_work, smc_listen_work);
1302 smc_copy_sock_settings_to_smc(new_smc); 1307 smc_copy_sock_settings_to_smc(new_smc);
@@ -1451,6 +1456,7 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
1451 if (msg->msg_flags & MSG_FASTOPEN) { 1456 if (msg->msg_flags & MSG_FASTOPEN) {
1452 if (sk->sk_state == SMC_INIT) { 1457 if (sk->sk_state == SMC_INIT) {
1453 smc->use_fallback = true; 1458 smc->use_fallback = true;
1459 smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP;
1454 } else { 1460 } else {
1455 rc = -EINVAL; 1461 rc = -EINVAL;
1456 goto out; 1462 goto out;
@@ -1648,6 +1654,7 @@ static int smc_setsockopt(struct socket *sock, int level, int optname,
1648 /* option not supported by SMC */ 1654 /* option not supported by SMC */
1649 if (sk->sk_state == SMC_INIT) { 1655 if (sk->sk_state == SMC_INIT) {
1650 smc->use_fallback = true; 1656 smc->use_fallback = true;
1657 smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP;
1651 } else { 1658 } else {
1652 if (!smc->use_fallback) 1659 if (!smc->use_fallback)
1653 rc = -EINVAL; 1660 rc = -EINVAL;
@@ -1885,6 +1892,7 @@ static int smc_create(struct net *net, struct socket *sock, int protocol,
1885 /* create internal TCP socket for CLC handshake and fallback */ 1892 /* create internal TCP socket for CLC handshake and fallback */
1886 smc = smc_sk(sk); 1893 smc = smc_sk(sk);
1887 smc->use_fallback = false; /* assume rdma capability first */ 1894 smc->use_fallback = false; /* assume rdma capability first */
1895 smc->fallback_rsn = 0;
1888 rc = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP, 1896 rc = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP,
1889 &smc->clcsock); 1897 &smc->clcsock);
1890 if (rc) { 1898 if (rc) {
diff --git a/net/smc/smc.h b/net/smc/smc.h
index be20acd7b5ab..08786ace6010 100644
--- a/net/smc/smc.h
+++ b/net/smc/smc.h
@@ -208,6 +208,8 @@ struct smc_sock { /* smc sock container */
208 struct list_head accept_q; /* sockets to be accepted */ 208 struct list_head accept_q; /* sockets to be accepted */
209 spinlock_t accept_q_lock; /* protects accept_q */ 209 spinlock_t accept_q_lock; /* protects accept_q */
210 bool use_fallback; /* fallback to tcp */ 210 bool use_fallback; /* fallback to tcp */
211 int fallback_rsn; /* reason for fallback */
212 u32 peer_diagnosis; /* decline reason from peer */
211 int sockopt_defer_accept; 213 int sockopt_defer_accept;
212 /* sockopt TCP_DEFER_ACCEPT 214 /* sockopt TCP_DEFER_ACCEPT
213 * value 215 * value
diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
index 78d74938a9d9..83aba9ade060 100644
--- a/net/smc/smc_clc.c
+++ b/net/smc/smc_clc.c
@@ -334,7 +334,11 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
334 goto out; 334 goto out;
335 } 335 }
336 if (clcm->type == SMC_CLC_DECLINE) { 336 if (clcm->type == SMC_CLC_DECLINE) {
337 reason_code = SMC_CLC_DECL_REPLY; 337 struct smc_clc_msg_decline *dclc;
338
339 dclc = (struct smc_clc_msg_decline *)clcm;
340 reason_code = SMC_CLC_DECL_PEERDECL;
341 smc->peer_diagnosis = ntohl(dclc->peer_diagnosis);
338 if (((struct smc_clc_msg_decline *)buf)->hdr.flag) { 342 if (((struct smc_clc_msg_decline *)buf)->hdr.flag) {
339 smc->conn.lgr->sync_err = 1; 343 smc->conn.lgr->sync_err = 1;
340 smc_lgr_terminate(smc->conn.lgr); 344 smc_lgr_terminate(smc->conn.lgr);
diff --git a/net/smc/smc_clc.h b/net/smc/smc_clc.h
index 6bdc63352d6a..18da89b681c2 100644
--- a/net/smc/smc_clc.h
+++ b/net/smc/smc_clc.h
@@ -28,15 +28,21 @@
28#define SMC_TYPE_B 3 /* SMC-R and SMC-D */ 28#define SMC_TYPE_B 3 /* SMC-R and SMC-D */
29#define CLC_WAIT_TIME (6 * HZ) /* max. wait time on clcsock */ 29#define CLC_WAIT_TIME (6 * HZ) /* max. wait time on clcsock */
30#define SMC_CLC_DECL_MEM 0x01010000 /* insufficient memory resources */ 30#define SMC_CLC_DECL_MEM 0x01010000 /* insufficient memory resources */
31#define SMC_CLC_DECL_TIMEOUT 0x02000000 /* timeout */ 31#define SMC_CLC_DECL_TIMEOUT_CL 0x02010000 /* timeout w4 QP confirm link */
32#define SMC_CLC_DECL_TIMEOUT_AL 0x02020000 /* timeout w4 QP add link */
32#define SMC_CLC_DECL_CNFERR 0x03000000 /* configuration error */ 33#define SMC_CLC_DECL_CNFERR 0x03000000 /* configuration error */
33#define SMC_CLC_DECL_IPSEC 0x03030000 /* IPsec usage */ 34#define SMC_CLC_DECL_PEERNOSMC 0x03010000 /* peer did not indicate SMC */
35#define SMC_CLC_DECL_IPSEC 0x03020000 /* IPsec usage */
36#define SMC_CLC_DECL_NOSMCDEV 0x03030000 /* no SMC device found */
37#define SMC_CLC_DECL_MODEUNSUPP 0x03040000 /* smc modes do not match (R or D)*/
38#define SMC_CLC_DECL_RMBE_EC 0x03050000 /* peer has eyecatcher in RMBE */
39#define SMC_CLC_DECL_OPTUNSUPP 0x03060000 /* fastopen sockopt not supported */
34#define SMC_CLC_DECL_SYNCERR 0x04000000 /* synchronization error */ 40#define SMC_CLC_DECL_SYNCERR 0x04000000 /* synchronization error */
35#define SMC_CLC_DECL_REPLY 0x06000000 /* reply to a received decline */ 41#define SMC_CLC_DECL_PEERDECL 0x05000000 /* peer declined during handshake */
36#define SMC_CLC_DECL_INTERR 0x99990000 /* internal error */ 42#define SMC_CLC_DECL_INTERR 0x99990000 /* internal error */
37#define SMC_CLC_DECL_TCL 0x02040000 /* timeout w4 QP confirm */ 43#define SMC_CLC_DECL_ERR_RTOK 0x99990001 /* rtoken handling failed */
38#define SMC_CLC_DECL_SEND 0x07000000 /* sending problem */ 44#define SMC_CLC_DECL_ERR_RDYLNK 0x99990002 /* ib ready link failed */
39#define SMC_CLC_DECL_RMBE_EC 0x08000000 /* peer has eyecatcher in RMBE */ 45#define SMC_CLC_DECL_ERR_REGRMB 0x99990003 /* reg rmb failed */
40 46
41struct smc_clc_msg_hdr { /* header1 of clc messages */ 47struct smc_clc_msg_hdr { /* header1 of clc messages */
42 u8 eyecatcher[4]; /* eye catcher */ 48 u8 eyecatcher[4]; /* eye catcher */
diff --git a/net/smc/smc_diag.c b/net/smc/smc_diag.c
index a3cf7313a2d3..dbf64a93d68a 100644
--- a/net/smc/smc_diag.c
+++ b/net/smc/smc_diag.c
@@ -79,6 +79,7 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb,
79 struct nlattr *bc) 79 struct nlattr *bc)
80{ 80{
81 struct smc_sock *smc = smc_sk(sk); 81 struct smc_sock *smc = smc_sk(sk);
82 struct smc_diag_fallback fallback;
82 struct user_namespace *user_ns; 83 struct user_namespace *user_ns;
83 struct smc_diag_msg *r; 84 struct smc_diag_msg *r;
84 struct nlmsghdr *nlh; 85 struct nlmsghdr *nlh;
@@ -101,6 +102,11 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb,
101 if (smc_diag_msg_attrs_fill(sk, skb, r, user_ns)) 102 if (smc_diag_msg_attrs_fill(sk, skb, r, user_ns))
102 goto errout; 103 goto errout;
103 104
105 fallback.reason = smc->fallback_rsn;
106 fallback.peer_diagnosis = smc->peer_diagnosis;
107 if (nla_put(skb, SMC_DIAG_FALLBACK, sizeof(fallback), &fallback) < 0)
108 goto errout;
109
104 if ((req->diag_ext & (1 << (SMC_DIAG_CONNINFO - 1))) && 110 if ((req->diag_ext & (1 << (SMC_DIAG_CONNINFO - 1))) &&
105 smc->conn.alert_token_local) { 111 smc->conn.alert_token_local) {
106 struct smc_connection *conn = &smc->conn; 112 struct smc_connection *conn = &smc->conn;