]> git.dujemihanovic.xyz Git - linux.git/commitdiff
net: rds: add service level support in rds-info
authorZhu Yanjun <yanjun.zhu@oracle.com>
Sat, 24 Aug 2019 01:04:16 +0000 (21:04 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sat, 24 Aug 2019 23:55:25 +0000 (16:55 -0700)
>From IB specific 7.6.5 SERVICE LEVEL, Service Level (SL)
is used to identify different flows within an IBA subnet.
It is carried in the local route header of the packet.

Before this commit, run "rds-info -I". The outputs are as
below:
"
RDS IB Connections:
 LocalAddr  RemoteAddr Tos SL  LocalDev               RemoteDev
192.2.95.3  192.2.95.1  2   0  fe80::21:28:1a:39  fe80::21:28:10:b9
192.2.95.3  192.2.95.1  1   0  fe80::21:28:1a:39  fe80::21:28:10:b9
192.2.95.3  192.2.95.1  0   0  fe80::21:28:1a:39  fe80::21:28:10:b9
"
After this commit, the output is as below:
"
RDS IB Connections:
 LocalAddr  RemoteAddr Tos SL  LocalDev               RemoteDev
192.2.95.3  192.2.95.1  2   2  fe80::21:28:1a:39  fe80::21:28:10:b9
192.2.95.3  192.2.95.1  1   1  fe80::21:28:1a:39  fe80::21:28:10:b9
192.2.95.3  192.2.95.1  0   0  fe80::21:28:1a:39  fe80::21:28:10:b9
"

The commit fe3475af3bdf ("net: rds: add per rds connection cache
statistics") adds cache_allocs in struct rds_info_rdma_connection
as below:
struct rds_info_rdma_connection {
...
        __u32           rdma_mr_max;
        __u32           rdma_mr_size;
        __u8            tos;
        __u32           cache_allocs;
 };
The peer struct in rds-tools of struct rds_info_rdma_connection is as
below:
struct rds_info_rdma_connection {
...
        uint32_t        rdma_mr_max;
        uint32_t        rdma_mr_size;
        uint8_t         tos;
        uint8_t         sl;
        uint32_t        cache_allocs;
};
The difference between userspace and kernel is the member variable sl.
In the kernel struct, the member variable sl is missing. This will
introduce risks. So it is necessary to use this commit to avoid this risk.

Fixes: fe3475af3bdf ("net: rds: add per rds connection cache statistics")
CC: Joe Jin <joe.jin@oracle.com>
CC: JUNXIAO_BI <junxiao.bi@oracle.com>
Suggested-by: Gerd Rausch <gerd.rausch@oracle.com>
Signed-off-by: Zhu Yanjun <yanjun.zhu@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/rds.h
net/rds/ib.c
net/rds/ib.h
net/rds/ib_cm.c
net/rds/rdma_transport.c

index fd6b5f66e2c55432b05ad939477393a29659a5ac..cba368e558634ff7e7ea125487b95ac3afda2d28 100644 (file)
@@ -250,6 +250,7 @@ struct rds_info_rdma_connection {
        __u32           rdma_mr_max;
        __u32           rdma_mr_size;
        __u8            tos;
+       __u8            sl;
        __u32           cache_allocs;
 };
 
@@ -265,6 +266,7 @@ struct rds6_info_rdma_connection {
        __u32           rdma_mr_max;
        __u32           rdma_mr_size;
        __u8            tos;
+       __u8            sl;
        __u32           cache_allocs;
 };
 
index ec05d91aa9a2b39b0b904a275b0731ba540ebb3c..45acab2de0cf3e09b295d2faf7db3b3c78528fc5 100644 (file)
@@ -291,7 +291,7 @@ static int rds_ib_conn_info_visitor(struct rds_connection *conn,
                                    void *buffer)
 {
        struct rds_info_rdma_connection *iinfo = buffer;
-       struct rds_ib_connection *ic;
+       struct rds_ib_connection *ic = conn->c_transport_data;
 
        /* We will only ever look at IB transports */
        if (conn->c_trans != &rds_ib_transport)
@@ -301,15 +301,16 @@ static int rds_ib_conn_info_visitor(struct rds_connection *conn,
 
        iinfo->src_addr = conn->c_laddr.s6_addr32[3];
        iinfo->dst_addr = conn->c_faddr.s6_addr32[3];
-       iinfo->tos = conn->c_tos;
+       if (ic) {
+               iinfo->tos = conn->c_tos;
+               iinfo->sl = ic->i_sl;
+       }
 
        memset(&iinfo->src_gid, 0, sizeof(iinfo->src_gid));
        memset(&iinfo->dst_gid, 0, sizeof(iinfo->dst_gid));
        if (rds_conn_state(conn) == RDS_CONN_UP) {
                struct rds_ib_device *rds_ibdev;
 
-               ic = conn->c_transport_data;
-
                rdma_read_gids(ic->i_cm_id, (union ib_gid *)&iinfo->src_gid,
                               (union ib_gid *)&iinfo->dst_gid);
 
@@ -329,7 +330,7 @@ static int rds6_ib_conn_info_visitor(struct rds_connection *conn,
                                     void *buffer)
 {
        struct rds6_info_rdma_connection *iinfo6 = buffer;
-       struct rds_ib_connection *ic;
+       struct rds_ib_connection *ic = conn->c_transport_data;
 
        /* We will only ever look at IB transports */
        if (conn->c_trans != &rds_ib_transport)
@@ -337,6 +338,10 @@ static int rds6_ib_conn_info_visitor(struct rds_connection *conn,
 
        iinfo6->src_addr = conn->c_laddr;
        iinfo6->dst_addr = conn->c_faddr;
+       if (ic) {
+               iinfo6->tos = conn->c_tos;
+               iinfo6->sl = ic->i_sl;
+       }
 
        memset(&iinfo6->src_gid, 0, sizeof(iinfo6->src_gid));
        memset(&iinfo6->dst_gid, 0, sizeof(iinfo6->dst_gid));
@@ -344,7 +349,6 @@ static int rds6_ib_conn_info_visitor(struct rds_connection *conn,
        if (rds_conn_state(conn) == RDS_CONN_UP) {
                struct rds_ib_device *rds_ibdev;
 
-               ic = conn->c_transport_data;
                rdma_read_gids(ic->i_cm_id, (union ib_gid *)&iinfo6->src_gid,
                               (union ib_gid *)&iinfo6->dst_gid);
                rds_ibdev = ic->rds_ibdev;
index 303c6ee8bdb7b0835448068e64dc992fda0380a1..f2b558e8b5eaf738cd6b1a46dc98c20205d5ab7b 100644 (file)
@@ -220,6 +220,7 @@ struct rds_ib_connection {
        /* Send/Recv vectors */
        int                     i_scq_vector;
        int                     i_rcq_vector;
+       u8                      i_sl;
 };
 
 /* This assumes that atomic_t is at least 32 bits */
index fddaa09f7b0dbd68d1d19cef054dccaa6369e45c..233f1368162b4f1be8596ba2d4803fdced10b41a 100644 (file)
@@ -152,6 +152,9 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
                  RDS_PROTOCOL_MINOR(conn->c_version),
                  ic->i_flowctl ? ", flow control" : "");
 
+       /* receive sl from the peer */
+       ic->i_sl = ic->i_cm_id->route.path_rec->sl;
+
        atomic_set(&ic->i_cq_quiesce, 0);
 
        /* Init rings and fill recv. this needs to wait until protocol
index 9986d6065c4d1f357f021700351866d0ebe4f8a2..5f741e51b4baa46f825b7a676969cde3159b2c21 100644 (file)
@@ -43,6 +43,9 @@ static struct rdma_cm_id *rds_rdma_listen_id;
 static struct rdma_cm_id *rds6_rdma_listen_id;
 #endif
 
+/* Per IB specification 7.7.3, service level is a 4-bit field. */
+#define TOS_TO_SL(tos)         ((tos) & 0xF)
+
 static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
                                         struct rdma_cm_event *event,
                                         bool isv6)
@@ -97,10 +100,13 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
                        struct rds_ib_connection *ibic;
 
                        ibic = conn->c_transport_data;
-                       if (ibic && ibic->i_cm_id == cm_id)
+                       if (ibic && ibic->i_cm_id == cm_id) {
+                               cm_id->route.path_rec[0].sl =
+                                       TOS_TO_SL(conn->c_tos);
                                ret = trans->cm_initiate_connect(cm_id, isv6);
-                       else
+                       } else {
                                rds_conn_drop(conn);
+                       }
                }
                break;