Skip to content

Commit b37289f

Browse files
author
CKI KWF Bot
committed
Merge: Upgrade SMC driver
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1739 JIRA: https://issues.redhat.com/browse/RHEL-99998 Commit ids: ``` cd959bf 0541db8 2c7f14e 27ef6a9 2b33eb8 679e9dd a29e220 7863c9f 9ab332d c5b8ee5 10bc976 a4b6539 bfc6c67 752e221 199561a c3ee72d 091d019 ae2402b 4814f91 60ada4f d9cef55 ba1e942 ``` Signed-off-by: Mete Durlu <mdurlu@redhat.com> Approved-by: Steve Best <sbest@redhat.com> Approved-by: David Arcari <darcari@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents 77e658f + 1a04643 commit b37289f

File tree

14 files changed

+184
-90
lines changed

14 files changed

+184
-90
lines changed

drivers/s390/net/ism_drv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
614614
ism->dev.parent = &pdev->dev;
615615
ism->dev.release = ism_dev_release;
616616
device_initialize(&ism->dev);
617-
dev_set_name(&ism->dev, dev_name(&pdev->dev));
617+
dev_set_name(&ism->dev, "%s", dev_name(&pdev->dev));
618618
ret = device_add(&ism->dev);
619619
if (ret)
620620
goto err_dev;

net/smc/af_smc.c

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include <linux/splice.h>
3131

3232
#include <net/sock.h>
33+
#include <net/inet_common.h>
34+
#if IS_ENABLED(CONFIG_IPV6)
35+
#include <net/ipv6.h>
36+
#endif
3337
#include <net/tcp.h>
3438
#include <net/smc.h>
3539
#include <asm/ioctls.h>
@@ -360,8 +364,21 @@ static void smc_destruct(struct sock *sk)
360364
return;
361365
if (!sock_flag(sk, SOCK_DEAD))
362366
return;
367+
switch (sk->sk_family) {
368+
case AF_INET:
369+
inet_sock_destruct(sk);
370+
break;
371+
#if IS_ENABLED(CONFIG_IPV6)
372+
case AF_INET6:
373+
inet6_sock_destruct(sk);
374+
break;
375+
#endif
376+
}
363377
}
364378

379+
static struct lock_class_key smc_key;
380+
static struct lock_class_key smc_slock_key;
381+
365382
void smc_sk_init(struct net *net, struct sock *sk, int protocol)
366383
{
367384
struct smc_sock *smc = smc_sk(sk);
@@ -375,6 +392,8 @@ void smc_sk_init(struct net *net, struct sock *sk, int protocol)
375392
INIT_WORK(&smc->connect_work, smc_connect_work);
376393
INIT_DELAYED_WORK(&smc->conn.tx_work, smc_tx_work);
377394
INIT_LIST_HEAD(&smc->accept_q);
395+
sock_lock_init_class_and_name(sk, "slock-AF_SMC", &smc_slock_key,
396+
"sk_lock-AF_SMC", &smc_key);
378397
spin_lock_init(&smc->accept_q_lock);
379398
spin_lock_init(&smc->conn.send_lock);
380399
sk->sk_prot->hash(sk);
@@ -383,6 +402,7 @@ void smc_sk_init(struct net *net, struct sock *sk, int protocol)
383402
smc->limit_smc_hs = net->smc.limit_smc_hs;
384403
smc->use_fallback = false; /* assume rdma capability first */
385404
smc->fallback_rsn = 0;
405+
smc_close_init(smc);
386406
}
387407

388408
static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
@@ -1302,7 +1322,6 @@ static int smc_connect_rdma(struct smc_sock *smc,
13021322
goto connect_abort;
13031323
}
13041324

1305-
smc_close_init(smc);
13061325
smc_rx_init(smc);
13071326

13081327
if (ini->first_contact_local) {
@@ -1438,7 +1457,6 @@ static int smc_connect_ism(struct smc_sock *smc,
14381457
goto connect_abort;
14391458
}
14401459
}
1441-
smc_close_init(smc);
14421460
smc_rx_init(smc);
14431461
smc_tx_init(smc);
14441462

@@ -1904,6 +1922,7 @@ static void smc_listen_out(struct smc_sock *new_smc)
19041922
if (tcp_sk(new_smc->clcsock->sk)->syn_smc)
19051923
atomic_dec(&lsmc->queued_smc_hs);
19061924

1925+
release_sock(newsmcsk); /* lock in smc_listen_work() */
19071926
if (lsmc->sk.sk_state == SMC_LISTEN) {
19081927
lock_sock_nested(&lsmc->sk, SINGLE_DEPTH_NESTING);
19091928
smc_accept_enqueue(&lsmc->sk, newsmcsk);
@@ -2035,6 +2054,8 @@ static int smc_listen_prfx_check(struct smc_sock *new_smc,
20352054
if (pclc->hdr.typev1 == SMC_TYPE_N)
20362055
return 0;
20372056
pclc_prfx = smc_clc_proposal_get_prefix(pclc);
2057+
if (!pclc_prfx)
2058+
return -EPROTO;
20382059
if (smc_clc_prfx_match(newclcsock, pclc_prfx))
20392060
return SMC_CLC_DECL_DIFFPREFIX;
20402061

@@ -2148,6 +2169,8 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
21482169
pclc_smcd = smc_get_clc_msg_smcd(pclc);
21492170
smc_v2_ext = smc_get_clc_v2_ext(pclc);
21502171
smcd_v2_ext = smc_get_clc_smcd_v2_ext(smc_v2_ext);
2172+
if (!pclc_smcd || !smc_v2_ext || !smcd_v2_ext)
2173+
goto not_found;
21512174

21522175
mutex_lock(&smcd_dev_list.mutex);
21532176
if (pclc_smcd->ism.chid) {
@@ -2224,7 +2247,9 @@ static void smc_find_ism_v1_device_serv(struct smc_sock *new_smc,
22242247
int rc = 0;
22252248

22262249
/* check if ISM V1 is available */
2227-
if (!(ini->smcd_version & SMC_V1) || !smcd_indicated(ini->smc_type_v1))
2250+
if (!(ini->smcd_version & SMC_V1) ||
2251+
!smcd_indicated(ini->smc_type_v1) ||
2252+
!pclc_smcd)
22282253
goto not_found;
22292254
ini->is_smcd = true; /* prepare ISM check */
22302255
ini->ism_peer_gid[0].gid = ntohll(pclc_smcd->ism.gid);
@@ -2275,7 +2300,8 @@ static void smc_find_rdma_v2_device_serv(struct smc_sock *new_smc,
22752300
goto not_found;
22762301

22772302
smc_v2_ext = smc_get_clc_v2_ext(pclc);
2278-
if (!smc_clc_match_eid(ini->negotiated_eid, smc_v2_ext, NULL, NULL))
2303+
if (!smc_v2_ext ||
2304+
!smc_clc_match_eid(ini->negotiated_eid, smc_v2_ext, NULL, NULL))
22792305
goto not_found;
22802306

22812307
/* prepare RDMA check */
@@ -2425,6 +2451,7 @@ static void smc_listen_work(struct work_struct *work)
24252451
u8 accept_version;
24262452
int rc = 0;
24272453

2454+
lock_sock(&new_smc->sk); /* release in smc_listen_out() */
24282455
if (new_smc->listen_smc->sk.sk_state != SMC_LISTEN)
24292456
return smc_listen_out_err(new_smc);
24302457

@@ -2482,7 +2509,6 @@ static void smc_listen_work(struct work_struct *work)
24822509
goto out_decl;
24832510

24842511
mutex_lock(&smc_server_lgr_pending);
2485-
smc_close_init(new_smc);
24862512
smc_rx_init(new_smc);
24872513
smc_tx_init(new_smc);
24882514

@@ -2542,8 +2568,9 @@ static void smc_listen_work(struct work_struct *work)
25422568
goto out_decl;
25432569
}
25442570

2545-
smc_listen_out_connected(new_smc);
25462571
SMC_STAT_SERV_SUCC_INC(sock_net(newclcsock->sk), ini);
2572+
/* smc_listen_out() will release smcsk */
2573+
smc_listen_out_connected(new_smc);
25472574
goto out_free;
25482575

25492576
out_unlock:
@@ -2723,8 +2750,7 @@ int smc_accept(struct socket *sock, struct socket *new_sock,
27232750

27242751
if (lsmc->sockopt_defer_accept && !(arg->flags & O_NONBLOCK)) {
27252752
/* wait till data arrives on the socket */
2726-
timeo = msecs_to_jiffies(lsmc->sockopt_defer_accept *
2727-
MSEC_PER_SEC);
2753+
timeo = secs_to_jiffies(lsmc->sockopt_defer_accept);
27282754
if (smc_sk(nsk)->use_fallback) {
27292755
struct sock *clcsk = smc_sk(nsk)->clcsock->sk;
27302756

@@ -2734,7 +2760,7 @@ int smc_accept(struct socket *sock, struct socket *new_sock,
27342760
release_sock(clcsk);
27352761
} else if (!atomic_read(&smc_sk(nsk)->conn.bytes_to_rcv)) {
27362762
lock_sock(nsk);
2737-
smc_rx_wait(smc_sk(nsk), &timeo, smc_rx_data_available);
2763+
smc_rx_wait(smc_sk(nsk), &timeo, 0, smc_rx_data_available);
27382764
release_sock(nsk);
27392765
}
27402766
}
@@ -2884,6 +2910,13 @@ __poll_t smc_poll(struct file *file, struct socket *sock,
28842910
} else {
28852911
sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
28862912
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
2913+
2914+
if (sk->sk_state != SMC_INIT) {
2915+
/* Race breaker the same way as tcp_poll(). */
2916+
smp_mb__after_atomic();
2917+
if (atomic_read(&smc->conn.sndbuf_space))
2918+
mask |= EPOLLOUT | EPOLLWRNORM;
2919+
}
28872920
}
28882921
if (atomic_read(&smc->conn.bytes_to_rcv))
28892922
mask |= EPOLLIN | EPOLLRDNORM;

net/smc/smc.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -278,15 +278,15 @@ struct smc_connection {
278278
*/
279279
u64 peer_token; /* SMC-D token of peer */
280280
u8 killed : 1; /* abnormal termination */
281-
u8 freed : 1; /* normal termiation */
281+
u8 freed : 1; /* normal termination */
282282
u8 out_of_sync : 1; /* out of sync with peer */
283283
};
284284

285285
struct smc_sock { /* smc sock container */
286-
struct sock sk;
287-
#if IS_ENABLED(CONFIG_IPV6)
288-
struct ipv6_pinfo *pinet6;
289-
#endif
286+
union {
287+
struct sock sk;
288+
struct inet_sock icsk_inet;
289+
};
290290
struct socket *clcsock; /* internal tcp socket */
291291
void (*clcsk_state_change)(struct sock *sk);
292292
/* original stat_change fct. */

net/smc/smc_clc.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,11 @@ static bool smc_clc_msg_prop_valid(struct smc_clc_msg_proposal *pclc)
352352
struct smc_clc_msg_hdr *hdr = &pclc->hdr;
353353
struct smc_clc_v2_extension *v2_ext;
354354

355-
v2_ext = smc_get_clc_v2_ext(pclc);
356355
pclc_prfx = smc_clc_proposal_get_prefix(pclc);
356+
if (!pclc_prfx ||
357+
pclc_prfx->ipv6_prefixes_cnt > SMC_CLC_MAX_V6_PREFIX)
358+
return false;
359+
357360
if (hdr->version == SMC_V1) {
358361
if (hdr->typev1 == SMC_TYPE_N)
359362
return false;
@@ -365,6 +368,13 @@ static bool smc_clc_msg_prop_valid(struct smc_clc_msg_proposal *pclc)
365368
sizeof(struct smc_clc_msg_trail))
366369
return false;
367370
} else {
371+
v2_ext = smc_get_clc_v2_ext(pclc);
372+
if ((hdr->typev2 != SMC_TYPE_N &&
373+
(!v2_ext || v2_ext->hdr.eid_cnt > SMC_CLC_MAX_UEID)) ||
374+
(smcd_indicated(hdr->typev2) &&
375+
v2_ext->hdr.ism_gid_cnt > SMCD_CLC_MAX_V2_GID_ENTRIES))
376+
return false;
377+
368378
if (ntohs(hdr->length) !=
369379
sizeof(*pclc) +
370380
sizeof(struct smc_clc_msg_smcd) +
@@ -762,6 +772,11 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
762772
SMC_CLC_RECV_BUF_LEN : datlen;
763773
iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen);
764774
len = sock_recvmsg(smc->clcsock, &msg, krflags);
775+
if (len < recvlen) {
776+
smc->sk.sk_err = EPROTO;
777+
reason_code = -EPROTO;
778+
goto out;
779+
}
765780
datlen -= len;
766781
}
767782
if (clcm->type == SMC_CLC_DECLINE) {

net/smc/smc_clc.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ struct smc_clc_msg_proposal_prefix { /* prefix part of clc proposal message*/
156156
} __aligned(4);
157157

158158
struct smc_clc_msg_smcd { /* SMC-D GID information */
159-
struct smc_clc_smcd_gid_chid ism; /* ISM native GID+CHID of requestor */
159+
struct smc_clc_smcd_gid_chid ism; /* ISM native GID+CHID of requester */
160160
__be16 v2_ext_offset; /* SMC Version 2 Extension Offset */
161161
u8 vendor_oui[3]; /* vendor organizationally unique identifier */
162162
u8 vendor_exp_options[5];
@@ -336,8 +336,12 @@ struct smc_clc_msg_decline_v2 { /* clc decline message */
336336
static inline struct smc_clc_msg_proposal_prefix *
337337
smc_clc_proposal_get_prefix(struct smc_clc_msg_proposal *pclc)
338338
{
339+
u16 offset = ntohs(pclc->iparea_offset);
340+
341+
if (offset > sizeof(struct smc_clc_msg_smcd))
342+
return NULL;
339343
return (struct smc_clc_msg_proposal_prefix *)
340-
((u8 *)pclc + sizeof(*pclc) + ntohs(pclc->iparea_offset));
344+
((u8 *)pclc + sizeof(*pclc) + offset);
341345
}
342346

343347
static inline bool smcr_indicated(int smc_type)
@@ -376,8 +380,14 @@ static inline struct smc_clc_v2_extension *
376380
smc_get_clc_v2_ext(struct smc_clc_msg_proposal *prop)
377381
{
378382
struct smc_clc_msg_smcd *prop_smcd = smc_get_clc_msg_smcd(prop);
383+
u16 max_offset;
379384

380-
if (!prop_smcd || !ntohs(prop_smcd->v2_ext_offset))
385+
max_offset = offsetof(struct smc_clc_msg_proposal_area, pclc_v2_ext) -
386+
offsetof(struct smc_clc_msg_proposal_area, pclc_smcd) -
387+
offsetofend(struct smc_clc_msg_smcd, v2_ext_offset);
388+
389+
if (!prop_smcd || !ntohs(prop_smcd->v2_ext_offset) ||
390+
ntohs(prop_smcd->v2_ext_offset) > max_offset)
381391
return NULL;
382392

383393
return (struct smc_clc_v2_extension *)
@@ -390,9 +400,15 @@ smc_get_clc_v2_ext(struct smc_clc_msg_proposal *prop)
390400
static inline struct smc_clc_smcd_v2_extension *
391401
smc_get_clc_smcd_v2_ext(struct smc_clc_v2_extension *prop_v2ext)
392402
{
403+
u16 max_offset = offsetof(struct smc_clc_msg_proposal_area, pclc_smcd_v2_ext) -
404+
offsetof(struct smc_clc_msg_proposal_area, pclc_v2_ext) -
405+
offsetof(struct smc_clc_v2_extension, hdr) -
406+
offsetofend(struct smc_clnt_opts_area_hdr, smcd_v2_ext_offset);
407+
393408
if (!prop_v2ext)
394409
return NULL;
395-
if (!ntohs(prop_v2ext->hdr.smcd_v2_ext_offset))
410+
if (!ntohs(prop_v2ext->hdr.smcd_v2_ext_offset) ||
411+
ntohs(prop_v2ext->hdr.smcd_v2_ext_offset) > max_offset)
396412
return NULL;
397413

398414
return (struct smc_clc_smcd_v2_extension *)

net/smc/smc_core.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -795,9 +795,14 @@ int smcr_link_init(struct smc_link_group *lgr, struct smc_link *lnk,
795795
if (lgr->smc_version == SMC_V2) {
796796
lnk->smcibdev = ini->smcrv2.ib_dev_v2;
797797
lnk->ibport = ini->smcrv2.ib_port_v2;
798+
lnk->wr_rx_sge_cnt = lnk->smcibdev->ibdev->attrs.max_recv_sge < 2 ? 1 : 2;
799+
lnk->wr_rx_buflen = smc_link_shared_v2_rxbuf(lnk) ?
800+
SMC_WR_BUF_SIZE : SMC_WR_BUF_V2_SIZE;
798801
} else {
799802
lnk->smcibdev = ini->ib_dev;
800803
lnk->ibport = ini->ib_port;
804+
lnk->wr_rx_sge_cnt = 1;
805+
lnk->wr_rx_buflen = SMC_WR_BUF_SIZE;
801806
}
802807
get_device(&lnk->smcibdev->ibdev->dev);
803808
atomic_inc(&lnk->smcibdev->lnk_cnt);
@@ -1818,7 +1823,9 @@ void smcr_link_down_cond_sched(struct smc_link *lnk)
18181823
{
18191824
if (smc_link_downing(&lnk->state)) {
18201825
trace_smcr_link_down(lnk, __builtin_return_address(0));
1821-
schedule_work(&lnk->link_down_wrk);
1826+
smcr_link_hold(lnk); /* smcr_link_put in link_down_wrk */
1827+
if (!schedule_work(&lnk->link_down_wrk))
1828+
smcr_link_put(lnk);
18221829
}
18231830
}
18241831

@@ -1850,11 +1857,14 @@ static void smc_link_down_work(struct work_struct *work)
18501857
struct smc_link_group *lgr = link->lgr;
18511858

18521859
if (list_empty(&lgr->list))
1853-
return;
1860+
goto out;
18541861
wake_up_all(&lgr->llc_msg_waiter);
18551862
down_write(&lgr->llc_conf_mutex);
18561863
smcr_link_down(link);
18571864
up_write(&lgr->llc_conf_mutex);
1865+
1866+
out:
1867+
smcr_link_put(link); /* smcr_link_hold by schedulers of link_down_work */
18581868
}
18591869

18601870
static int smc_vlan_by_tcpsk_walk(struct net_device *lower_dev,
@@ -2090,8 +2100,7 @@ int smc_uncompress_bufsize(u8 compressed)
20902100
/* try to reuse a sndbuf or rmb description slot for a certain
20912101
* buffer size; if not available, return NULL
20922102
*/
2093-
static struct smc_buf_desc *smc_buf_get_slot(int compressed_bufsize,
2094-
struct rw_semaphore *lock,
2103+
static struct smc_buf_desc *smc_buf_get_slot(struct rw_semaphore *lock,
20952104
struct list_head *buf_list)
20962105
{
20972106
struct smc_buf_desc *buf_slot;
@@ -2145,7 +2154,7 @@ static int smcr_buf_map_link(struct smc_buf_desc *buf_desc, bool is_rmb,
21452154
for_each_sg(buf_desc->sgt[lnk->link_idx].sgl, sg, nents, i) {
21462155
size = min_t(int, PAGE_SIZE - offset, buf_size);
21472156
sg_set_page(sg, vmalloc_to_page(buf), size, offset);
2148-
buf += size / sizeof(*buf);
2157+
buf += size;
21492158
buf_size -= size;
21502159
offset = 0;
21512160
}
@@ -2321,7 +2330,7 @@ static struct smc_buf_desc *smcr_new_buf_create(struct smc_link_group *lgr,
23212330
}
23222331
if (lgr->buf_type == SMCR_PHYS_CONT_BUFS)
23232332
goto out;
2324-
fallthrough; // try virtually continguous buf
2333+
fallthrough; // try virtually contiguous buf
23252334
case SMCR_VIRT_CONT_BUFS:
23262335
buf_desc->order = get_order(bufsize);
23272336
buf_desc->cpu_addr = vzalloc(PAGE_SIZE << buf_desc->order);
@@ -2432,7 +2441,7 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)
24322441
bufsize = smc_uncompress_bufsize(bufsize_comp);
24332442

24342443
/* check for reusable slot in the link group */
2435-
buf_desc = smc_buf_get_slot(bufsize_comp, lock, buf_list);
2444+
buf_desc = smc_buf_get_slot(lock, buf_list);
24362445
if (buf_desc) {
24372446
buf_desc->is_dma_need_sync = 0;
24382447
SMC_STAT_RMB_SIZE(smc, is_smcd, is_rmb, true, bufsize);

0 commit comments

Comments
 (0)