Skip to content

Commit f16a7dd

Browse files
Ursula Braundavem330
Ursula Braun
authored andcommitted
smc: netlink interface for SMC sockets
Support for SMC socket monitoring via netlink sockets of protocol NETLINK_SOCK_DIAG. Signed-off-by: Ursula Braun <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b38d732 commit f16a7dd

File tree

10 files changed

+379
-1
lines changed

10 files changed

+379
-1
lines changed

include/net/smc.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Shared Memory Communications over RDMA (SMC-R) and RoCE
3+
*
4+
* Definitions for the SMC module (socket related)
5+
*
6+
* Copyright IBM Corp. 2016
7+
*
8+
* Author(s): Ursula Braun <[email protected]>
9+
*/
10+
#ifndef _SMC_H
11+
#define _SMC_H
12+
13+
struct smc_hashinfo {
14+
rwlock_t lock;
15+
struct hlist_head ht;
16+
};
17+
18+
int smc_hash_sk(struct sock *sk);
19+
void smc_unhash_sk(struct sock *sk);
20+
#endif /* _SMC_H */

include/net/sock.h

+3
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#include <net/checksum.h>
7171
#include <net/tcp_states.h>
7272
#include <linux/net_tstamp.h>
73+
#include <net/smc.h>
7374

7475
/*
7576
* This structure really needs to be cleaned up.
@@ -986,6 +987,7 @@ struct request_sock_ops;
986987
struct timewait_sock_ops;
987988
struct inet_hashinfo;
988989
struct raw_hashinfo;
990+
struct smc_hashinfo;
989991
struct module;
990992

991993
/*
@@ -1094,6 +1096,7 @@ struct proto {
10941096
struct inet_hashinfo *hashinfo;
10951097
struct udp_table *udp_table;
10961098
struct raw_hashinfo *raw_hash;
1099+
struct smc_hashinfo *smc_hash;
10971100
} h;
10981101

10991102
struct module *owner;

include/uapi/linux/netlink.h

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#define NETLINK_ECRYPTFS 19
2828
#define NETLINK_RDMA 20
2929
#define NETLINK_CRYPTO 21 /* Crypto layer */
30+
#define NETLINK_SMC 22 /* SMC monitoring */
3031

3132
#define NETLINK_INET_DIAG NETLINK_SOCK_DIAG
3233

include/uapi/linux/smc_diag.h

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#ifndef _UAPI_SMC_DIAG_H_
2+
#define _UAPI_SMC_DIAG_H_
3+
4+
#include <linux/types.h>
5+
#include <linux/inet_diag.h>
6+
#include <rdma/ib_verbs.h>
7+
8+
/* Request structure */
9+
struct smc_diag_req {
10+
__u8 diag_family;
11+
__u8 pad[2];
12+
__u8 diag_ext; /* Query extended information */
13+
struct inet_diag_sockid id;
14+
};
15+
16+
/* Base info structure. It contains socket identity (addrs/ports/cookie) based
17+
* on the internal clcsock, and more SMC-related socket data
18+
*/
19+
struct smc_diag_msg {
20+
__u8 diag_family;
21+
__u8 diag_state;
22+
__u8 diag_fallback;
23+
__u8 diag_shutdown;
24+
struct inet_diag_sockid id;
25+
26+
__u32 diag_uid;
27+
__u64 diag_inode;
28+
};
29+
30+
/* Extensions */
31+
32+
enum {
33+
SMC_DIAG_NONE,
34+
SMC_DIAG_CONNINFO,
35+
SMC_DIAG_LGRINFO,
36+
SMC_DIAG_SHUTDOWN,
37+
__SMC_DIAG_MAX,
38+
};
39+
40+
#define SMC_DIAG_MAX (__SMC_DIAG_MAX - 1)
41+
42+
/* SMC_DIAG_CONNINFO */
43+
44+
struct smc_diag_cursor {
45+
__u16 reserved;
46+
__u16 wrap;
47+
__u32 count;
48+
};
49+
50+
struct smc_diag_conninfo {
51+
__u32 token; /* unique connection id */
52+
__u32 sndbuf_size; /* size of send buffer */
53+
__u32 rmbe_size; /* size of RMB element */
54+
__u32 peer_rmbe_size; /* size of peer RMB element */
55+
/* local RMB element cursors */
56+
struct smc_diag_cursor rx_prod; /* received producer cursor */
57+
struct smc_diag_cursor rx_cons; /* received consumer cursor */
58+
/* peer RMB element cursors */
59+
struct smc_diag_cursor tx_prod; /* sent producer cursor */
60+
struct smc_diag_cursor tx_cons; /* sent consumer cursor */
61+
__u8 rx_prod_flags; /* received producer flags */
62+
__u8 rx_conn_state_flags; /* recvd connection flags*/
63+
__u8 tx_prod_flags; /* sent producer flags */
64+
__u8 tx_conn_state_flags; /* sent connection flags*/
65+
/* send buffer cursors */
66+
struct smc_diag_cursor tx_prep; /* prepared to be sent cursor */
67+
struct smc_diag_cursor tx_sent; /* sent cursor */
68+
struct smc_diag_cursor tx_fin; /* confirmed sent cursor */
69+
};
70+
71+
/* SMC_DIAG_LINKINFO */
72+
73+
struct smc_diag_linkinfo {
74+
__u8 link_id; /* link identifier */
75+
__u8 ibname[IB_DEVICE_NAME_MAX]; /* name of the RDMA device */
76+
__u8 ibport; /* RDMA device port number */
77+
__u8 gid[40]; /* local GID */
78+
__u8 peer_gid[40]; /* peer GID */
79+
};
80+
81+
struct smc_diag_lgrinfo {
82+
struct smc_diag_linkinfo lnk[1];
83+
__u8 role;
84+
};
85+
#endif /* _UAPI_SMC_DIAG_H_ */

net/smc/Kconfig

+9
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,12 @@ config SMC
99
a separate socket family SMC.
1010

1111
Select this option if you want to run SMC socket applications
12+
13+
config SMC_DIAG
14+
tristate "SMC: socket monitoring interface"
15+
depends on SMC
16+
---help---
17+
Support for SMC socket monitoring interface used by tools such as
18+
smcss.
19+
20+
if unsure, say Y.

net/smc/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
obj-$(CONFIG_SMC) += smc.o
2+
obj-$(CONFIG_SMC_DIAG) += smc_diag.o
23
smc-y := af_smc.o smc_pnet.o smc_ib.o smc_clc.o smc_core.o smc_wr.o smc_llc.o
34
smc-y += smc_cdc.o smc_tx.o smc_rx.o smc_close.o

net/smc/af_smc.c

+42-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <linux/in.h>
3030
#include <net/sock.h>
3131
#include <net/tcp.h>
32+
#include <net/smc.h>
3233

3334
#include "smc.h"
3435
#include "smc_clc.h"
@@ -59,13 +60,48 @@ static void smc_set_keepalive(struct sock *sk, int val)
5960
smc->clcsock->sk->sk_prot->keepalive(smc->clcsock->sk, val);
6061
}
6162

62-
static struct proto smc_proto = {
63+
static struct smc_hashinfo smc_v4_hashinfo = {
64+
.lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
65+
};
66+
67+
int smc_hash_sk(struct sock *sk)
68+
{
69+
struct smc_hashinfo *h = sk->sk_prot->h.smc_hash;
70+
struct hlist_head *head;
71+
72+
head = &h->ht;
73+
74+
write_lock_bh(&h->lock);
75+
sk_add_node(sk, head);
76+
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
77+
write_unlock_bh(&h->lock);
78+
79+
return 0;
80+
}
81+
EXPORT_SYMBOL_GPL(smc_hash_sk);
82+
83+
void smc_unhash_sk(struct sock *sk)
84+
{
85+
struct smc_hashinfo *h = sk->sk_prot->h.smc_hash;
86+
87+
write_lock_bh(&h->lock);
88+
if (sk_del_node_init(sk))
89+
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
90+
write_unlock_bh(&h->lock);
91+
}
92+
EXPORT_SYMBOL_GPL(smc_unhash_sk);
93+
94+
struct proto smc_proto = {
6395
.name = "SMC",
6496
.owner = THIS_MODULE,
6597
.keepalive = smc_set_keepalive,
98+
.hash = smc_hash_sk,
99+
.unhash = smc_unhash_sk,
66100
.obj_size = sizeof(struct smc_sock),
101+
.h.smc_hash = &smc_v4_hashinfo,
67102
.slab_flags = SLAB_DESTROY_BY_RCU,
68103
};
104+
EXPORT_SYMBOL_GPL(smc_proto);
69105

70106
static int smc_release(struct socket *sock)
71107
{
@@ -109,6 +145,7 @@ static int smc_release(struct socket *sock)
109145
schedule_delayed_work(&smc->sock_put_work,
110146
SMC_CLOSE_SOCK_PUT_DELAY);
111147
}
148+
sk->sk_prot->unhash(sk);
112149
release_sock(sk);
113150

114151
sock_put(sk);
@@ -144,6 +181,7 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock)
144181
INIT_LIST_HEAD(&smc->accept_q);
145182
spin_lock_init(&smc->accept_q_lock);
146183
INIT_DELAYED_WORK(&smc->sock_put_work, smc_close_sock_put_work);
184+
sk->sk_prot->hash(sk);
147185
sk_refcnt_debug_inc(sk);
148186

149187
return sk;
@@ -536,6 +574,7 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
536574
lsmc->sk.sk_err = -rc;
537575
new_sk->sk_state = SMC_CLOSED;
538576
sock_set_flag(new_sk, SOCK_DEAD);
577+
sk->sk_prot->unhash(new_sk);
539578
sock_put(new_sk);
540579
*new_smc = NULL;
541580
goto out;
@@ -545,6 +584,7 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
545584
sock_release(new_clcsock);
546585
new_sk->sk_state = SMC_CLOSED;
547586
sock_set_flag(new_sk, SOCK_DEAD);
587+
sk->sk_prot->unhash(new_sk);
548588
sock_put(new_sk);
549589
*new_smc = NULL;
550590
goto out;
@@ -1320,6 +1360,7 @@ static int __init smc_init(void)
13201360
pr_err("%s: sock_register fails with %d\n", __func__, rc);
13211361
goto out_proto;
13221362
}
1363+
INIT_HLIST_HEAD(&smc_v4_hashinfo.ht);
13231364

13241365
rc = smc_ib_register_client();
13251366
if (rc) {

net/smc/smc.h

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
#define SMC_MAX_PORTS 2 /* Max # of ports */
2323

24+
extern struct proto smc_proto;
25+
2426
#ifdef ATOMIC64_INIT
2527
#define KERNEL_HAS_ATOMIC64
2628
#endif

net/smc/smc_close.c

+1
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ void smc_close_sock_put_work(struct work_struct *work)
384384
struct smc_sock,
385385
sock_put_work);
386386

387+
smc->sk.sk_prot->unhash(&smc->sk);
387388
sock_put(&smc->sk);
388389
}
389390

0 commit comments

Comments
 (0)