Skip to content

Commit 6bb14e4

Browse files
Ursula Braundavem330
authored andcommitted
net/smc: dynamic allocation of CLC proposal buffer
Reduce stack size for smc_listen_work() and smc_clc_send_proposal() by dynamic allocation of the CLC buffer to be received or sent. Signed-off-by: Ursula Braun <ubraun@linux.ibm.com> Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 5ac54d8 commit 6bb14e4

File tree

3 files changed

+67
-49
lines changed

3 files changed

+67
-49
lines changed

net/smc/af_smc.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,10 +1276,10 @@ static void smc_listen_work(struct work_struct *work)
12761276
smc_listen_work);
12771277
struct socket *newclcsock = new_smc->clcsock;
12781278
struct smc_clc_msg_accept_confirm cclc;
1279+
struct smc_clc_msg_proposal_area *buf;
12791280
struct smc_clc_msg_proposal *pclc;
12801281
struct smc_init_info ini = {0};
12811282
bool ism_supported = false;
1282-
u8 buf[SMC_CLC_MAX_LEN];
12831283
int rc = 0;
12841284

12851285
if (new_smc->listen_smc->sk.sk_state != SMC_LISTEN)
@@ -1301,8 +1301,13 @@ static void smc_listen_work(struct work_struct *work)
13011301
/* do inband token exchange -
13021302
* wait for and receive SMC Proposal CLC message
13031303
*/
1304-
pclc = (struct smc_clc_msg_proposal *)&buf;
1305-
rc = smc_clc_wait_msg(new_smc, pclc, SMC_CLC_MAX_LEN,
1304+
buf = kzalloc(sizeof(*buf), GFP_KERNEL);
1305+
if (!buf) {
1306+
rc = SMC_CLC_DECL_MEM;
1307+
goto out_decl;
1308+
}
1309+
pclc = (struct smc_clc_msg_proposal *)buf;
1310+
rc = smc_clc_wait_msg(new_smc, pclc, sizeof(*buf),
13061311
SMC_CLC_PROPOSAL, CLC_WAIT_TIME);
13071312
if (rc)
13081313
goto out_decl;
@@ -1382,6 +1387,7 @@ static void smc_listen_work(struct work_struct *work)
13821387
}
13831388

13841389
/* finish worker */
1390+
kfree(buf);
13851391
if (!ism_supported) {
13861392
rc = smc_listen_rdma_finish(new_smc, &cclc,
13871393
ini.first_contact_local);
@@ -1397,6 +1403,7 @@ static void smc_listen_work(struct work_struct *work)
13971403
mutex_unlock(&smc_server_lgr_pending);
13981404
out_decl:
13991405
smc_listen_decline(new_smc, rc, ini.first_contact_local);
1406+
kfree(buf);
14001407
}
14011408

14021409
static void smc_tcp_listen_work(struct work_struct *work)

net/smc/smc_clc.c

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ static int smc_clc_prfx_set(struct socket *clcsock,
153153
struct sockaddr_in *addr;
154154
int rc = -ENOENT;
155155

156-
memset(prop, 0, sizeof(*prop));
157156
if (!dst) {
158157
rc = -ENOTCONN;
159158
goto out;
@@ -412,76 +411,89 @@ int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info)
412411
int smc_clc_send_proposal(struct smc_sock *smc, int smc_type,
413412
struct smc_init_info *ini)
414413
{
415-
struct smc_clc_ipv6_prefix ipv6_prfx[SMC_CLC_MAX_V6_PREFIX];
416-
struct smc_clc_msg_proposal_prefix pclc_prfx;
417-
struct smc_clc_msg_smcd pclc_smcd;
418-
struct smc_clc_msg_proposal pclc;
419-
struct smc_clc_msg_trail trl;
414+
struct smc_clc_msg_proposal_prefix *pclc_prfx;
415+
struct smc_clc_msg_proposal *pclc_base;
416+
struct smc_clc_msg_proposal_area *pclc;
417+
struct smc_clc_ipv6_prefix *ipv6_prfx;
418+
struct smc_clc_msg_smcd *pclc_smcd;
419+
struct smc_clc_msg_trail *trl;
420420
int len, i, plen, rc;
421421
int reason_code = 0;
422422
struct kvec vec[5];
423423
struct msghdr msg;
424424

425+
pclc = kzalloc(sizeof(*pclc), GFP_KERNEL);
426+
if (!pclc)
427+
return -ENOMEM;
428+
429+
pclc_base = &pclc->pclc_base;
430+
pclc_smcd = &pclc->pclc_smcd;
431+
pclc_prfx = &pclc->pclc_prfx;
432+
ipv6_prfx = pclc->pclc_prfx_ipv6;
433+
trl = &pclc->pclc_trl;
434+
425435
/* retrieve ip prefixes for CLC proposal msg */
426-
rc = smc_clc_prfx_set(smc->clcsock, &pclc_prfx, ipv6_prfx);
427-
if (rc)
436+
rc = smc_clc_prfx_set(smc->clcsock, pclc_prfx, ipv6_prfx);
437+
if (rc) {
438+
kfree(pclc);
428439
return SMC_CLC_DECL_CNFERR; /* configuration error */
440+
}
429441

430442
/* send SMC Proposal CLC message */
431-
plen = sizeof(pclc) + sizeof(pclc_prfx) +
432-
(pclc_prfx.ipv6_prefixes_cnt * sizeof(ipv6_prfx[0])) +
433-
sizeof(trl);
434-
memset(&pclc, 0, sizeof(pclc));
435-
memcpy(pclc.hdr.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
436-
pclc.hdr.type = SMC_CLC_PROPOSAL;
437-
pclc.hdr.version = SMC_V1; /* SMC version */
438-
pclc.hdr.path = smc_type;
443+
plen = sizeof(*pclc_base) + sizeof(*pclc_prfx) +
444+
(pclc_prfx->ipv6_prefixes_cnt * sizeof(ipv6_prfx[0])) +
445+
sizeof(*trl);
446+
memcpy(pclc_base->hdr.eyecatcher, SMC_EYECATCHER,
447+
sizeof(SMC_EYECATCHER));
448+
pclc_base->hdr.type = SMC_CLC_PROPOSAL;
449+
pclc_base->hdr.version = SMC_V1; /* SMC version */
450+
pclc_base->hdr.path = smc_type;
439451
if (smc_type == SMC_TYPE_R || smc_type == SMC_TYPE_B) {
440452
/* add SMC-R specifics */
441-
memcpy(pclc.lcl.id_for_peer, local_systemid,
453+
memcpy(pclc_base->lcl.id_for_peer, local_systemid,
442454
sizeof(local_systemid));
443-
memcpy(&pclc.lcl.gid, ini->ib_gid, SMC_GID_SIZE);
444-
memcpy(&pclc.lcl.mac, &ini->ib_dev->mac[ini->ib_port - 1],
455+
memcpy(pclc_base->lcl.gid, ini->ib_gid, SMC_GID_SIZE);
456+
memcpy(pclc_base->lcl.mac, &ini->ib_dev->mac[ini->ib_port - 1],
445457
ETH_ALEN);
446-
pclc.iparea_offset = htons(0);
458+
pclc_base->iparea_offset = htons(0);
447459
}
448460
if (smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B) {
449461
/* add SMC-D specifics */
450-
memset(&pclc_smcd, 0, sizeof(pclc_smcd));
451-
plen += sizeof(pclc_smcd);
452-
pclc.iparea_offset = htons(SMC_CLC_PROPOSAL_MAX_OFFSET);
453-
pclc_smcd.gid = ini->ism_dev->local_gid;
462+
plen += sizeof(*pclc_smcd);
463+
pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
464+
pclc_smcd->gid = ini->ism_dev->local_gid;
454465
}
455-
pclc.hdr.length = htons(plen);
466+
pclc_base->hdr.length = htons(plen);
456467

457-
memcpy(trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
468+
memcpy(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
458469
memset(&msg, 0, sizeof(msg));
459470
i = 0;
460-
vec[i].iov_base = &pclc;
461-
vec[i++].iov_len = sizeof(pclc);
471+
vec[i].iov_base = pclc_base;
472+
vec[i++].iov_len = sizeof(*pclc_base);
462473
if (smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B) {
463-
vec[i].iov_base = &pclc_smcd;
464-
vec[i++].iov_len = sizeof(pclc_smcd);
474+
vec[i].iov_base = pclc_smcd;
475+
vec[i++].iov_len = sizeof(*pclc_smcd);
465476
}
466-
vec[i].iov_base = &pclc_prfx;
467-
vec[i++].iov_len = sizeof(pclc_prfx);
468-
if (pclc_prfx.ipv6_prefixes_cnt > 0) {
469-
vec[i].iov_base = &ipv6_prfx[0];
470-
vec[i++].iov_len = pclc_prfx.ipv6_prefixes_cnt *
477+
vec[i].iov_base = pclc_prfx;
478+
vec[i++].iov_len = sizeof(*pclc_prfx);
479+
if (pclc_prfx->ipv6_prefixes_cnt > 0) {
480+
vec[i].iov_base = ipv6_prfx;
481+
vec[i++].iov_len = pclc_prfx->ipv6_prefixes_cnt *
471482
sizeof(ipv6_prfx[0]);
472483
}
473-
vec[i].iov_base = &trl;
474-
vec[i++].iov_len = sizeof(trl);
484+
vec[i].iov_base = trl;
485+
vec[i++].iov_len = sizeof(*trl);
475486
/* due to the few bytes needed for clc-handshake this cannot block */
476487
len = kernel_sendmsg(smc->clcsock, &msg, vec, i, plen);
477488
if (len < 0) {
478489
smc->sk.sk_err = smc->clcsock->sk->sk_err;
479490
reason_code = -smc->sk.sk_err;
480-
} else if (len < (int)sizeof(pclc)) {
491+
} else if (len < ntohs(pclc_base->hdr.length)) {
481492
reason_code = -ENETUNREACH;
482493
smc->sk.sk_err = -reason_code;
483494
}
484495

496+
kfree(pclc);
485497
return reason_code;
486498
}
487499

net/smc/smc_clc.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,13 @@ struct smc_clc_msg_proposal { /* clc proposal message sent by Linux */
110110
__be16 iparea_offset; /* offset to IP address information area */
111111
} __aligned(4);
112112

113-
#define SMC_CLC_PROPOSAL_MAX_OFFSET 0x28
114-
#define SMC_CLC_PROPOSAL_MAX_PREFIX (SMC_CLC_MAX_V6_PREFIX * \
115-
sizeof(struct smc_clc_ipv6_prefix))
116-
#define SMC_CLC_MAX_LEN (sizeof(struct smc_clc_msg_proposal) + \
117-
SMC_CLC_PROPOSAL_MAX_OFFSET + \
118-
sizeof(struct smc_clc_msg_proposal_prefix) + \
119-
SMC_CLC_PROPOSAL_MAX_PREFIX + \
120-
sizeof(struct smc_clc_msg_trail))
113+
struct smc_clc_msg_proposal_area {
114+
struct smc_clc_msg_proposal pclc_base;
115+
struct smc_clc_msg_smcd pclc_smcd;
116+
struct smc_clc_msg_proposal_prefix pclc_prfx;
117+
struct smc_clc_ipv6_prefix pclc_prfx_ipv6[SMC_CLC_MAX_V6_PREFIX];
118+
struct smc_clc_msg_trail pclc_trl;
119+
};
121120

122121
struct smc_clc_msg_accept_confirm { /* clc accept / confirm message */
123122
struct smc_clc_msg_hdr hdr;

0 commit comments

Comments
 (0)